📄 modules.c
字号:
/***************************************************************************** * modules.c : Builtin and plugin modules management functions ***************************************************************************** * Copyright (C) 2001-2004 VideoLAN * $Id: modules.c 11126 2005-05-23 09:08:04Z xtophe $ * * Authors: Sam Hocevar <sam@zoy.org> * Ethan C. Baldridge <BaldridgeE@cadmus.com> * Hans-Peter Jansen <hpj@urpla.net> * Gildas Bazin <gbazin@videolan.org> * * 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. *****************************************************************************//* Some faulty libcs have a broken struct dirent when _FILE_OFFSET_BITS * is set to 64. Don't try to be cleverer. */#ifdef _FILE_OFFSET_BITS#undef _FILE_OFFSET_BITS#endif#include <stdlib.h> /* free(), strtol() */#include <stdio.h> /* sprintf() */#include <string.h> /* strdup() */#include <vlc/vlc.h>#include <vlc/input.h>#ifdef HAVE_DIRENT_H# include <dirent.h>#endif#ifdef HAVE_SYS_TYPES_H# include <sys/types.h>#endif#ifdef HAVE_SYS_STAT_H# include <sys/stat.h>#endif#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#if !defined(HAVE_DYNAMIC_PLUGINS) /* no support for plugins */#elif defined(HAVE_DL_DYLD)# if defined(HAVE_MACH_O_DYLD_H)# include <mach-o/dyld.h># endif#elif defined(HAVE_DL_BEOS)# if defined(HAVE_IMAGE_H)# include <image.h># endif#elif defined(HAVE_DL_WINDOWS)# include <windows.h>#elif defined(HAVE_DL_DLOPEN)# if defined(HAVE_DLFCN_H) /* Linux, BSD, Hurd */# include <dlfcn.h># endif# if defined(HAVE_SYS_DL_H)# include <sys/dl.h># endif#elif defined(HAVE_DL_SHL_LOAD)# if defined(HAVE_DL_H)# include <dl.h># endif#endif#include "vlc_error.h"#include "vlc_interface.h"#include "intf_eject.h"#include "vlc_playlist.h"#include "vlc_video.h"#include "video_output.h"#include "vout_synchro.h"#include "vlc_spu.h"#include "audio_output.h"#include "aout_internal.h"#include "stream_output.h"#include "osd.h"#include "vlc_httpd.h"#include "vlc_tls.h"#include "vlc_xml.h"#include "iso_lang.h"#include "charset.h"#include "vlc_block.h"#include "vlc_vlm.h"#include "vlc_image.h"#ifdef HAVE_DYNAMIC_PLUGINS# include "modules_plugin.h"#endif#if defined( _MSC_VER ) && defined( UNDER_CE )# include "modules_builtin_evc.h"#elif defined( _MSC_VER )# include "modules_builtin_msvc.h"#else# include "modules_builtin.h"#endif#include "network.h"#if defined( WIN32 ) || defined( UNDER_CE ) /* Avoid name collisions */# define LoadModule(a,b,c) _LoadModule(a,b,c)#endif/***************************************************************************** * Local prototypes *****************************************************************************/#ifdef HAVE_DYNAMIC_PLUGINSstatic void AllocateAllPlugins ( vlc_object_t * );static void AllocatePluginDir ( vlc_object_t *, const char *, int );static int AllocatePluginFile ( vlc_object_t *, char *, int64_t, int64_t );static module_t * AllocatePlugin( vlc_object_t *, char * );#endifstatic int AllocateBuiltinModule( vlc_object_t *, int ( * ) ( module_t * ) );static int DeleteModule ( module_t * );#ifdef HAVE_DYNAMIC_PLUGINSstatic void DupModule ( module_t * );static void UndupModule ( module_t * );static int CallEntry ( module_t * );static int LoadModule ( vlc_object_t *, char *, module_handle_t * );static void CloseModule ( module_handle_t );static void * GetSymbol ( module_handle_t, const char * );static void CacheLoad ( vlc_object_t * );static int CacheLoadConfig ( module_t *, FILE * );static void CacheSave ( vlc_object_t * );static void CacheSaveConfig ( module_t *, FILE * );static char * CacheName ( void );static void CacheMerge ( vlc_object_t *, module_t *, module_t * );static module_cache_t * CacheFind( vlc_object_t *, char *, int64_t, int64_t );#if defined(HAVE_DL_WINDOWS)static char * GetWindowsError ( void );#endif#endif/* Sub-version number * (only used to avoid breakage in dev version when cache structure changes) */#define CACHE_SUBVERSION_NUM 1/***************************************************************************** * module_InitBank: create the module bank. ***************************************************************************** * This function creates a module bank structure which will be filled later * on with all the modules found. *****************************************************************************/void __module_InitBank( vlc_object_t *p_this ){ module_bank_t *p_bank; vlc_value_t lockval; var_Create( p_this->p_libvlc, "libvlc", VLC_VAR_MUTEX ); var_Get( p_this->p_libvlc, "libvlc", &lockval ); vlc_mutex_lock( lockval.p_address ); if( p_this->p_libvlc->p_module_bank ) { p_this->p_libvlc->p_module_bank->i_usage++; vlc_mutex_unlock( lockval.p_address ); var_Destroy( p_this->p_libvlc, "libvlc" ); return; } vlc_mutex_unlock( lockval.p_address ); var_Destroy( p_this->p_libvlc, "libvlc" ); p_bank = vlc_object_create( p_this, sizeof(module_bank_t) ); p_bank->psz_object_name = "module bank"; p_bank->i_usage = 1; p_bank->i_cache = p_bank->i_loaded_cache = 0; p_bank->pp_cache = p_bank->pp_loaded_cache = 0; p_bank->b_cache = p_bank->b_cache_dirty = p_bank->b_cache_delete = VLC_FALSE; /* * Store the symbols to be exported */#ifdef HAVE_DYNAMIC_PLUGINS STORE_SYMBOLS( &p_bank->symbols );#endif /* Everything worked, attach the object */ p_this->p_libvlc->p_module_bank = p_bank; vlc_object_attach( p_bank, p_this->p_libvlc ); module_LoadMain( p_this ); return;}/***************************************************************************** * module_ResetBank: reset the module bank. ***************************************************************************** * This function resets the module bank by unloading all unused plugin * modules. *****************************************************************************/void __module_ResetBank( vlc_object_t *p_this ){ msg_Err( p_this, "FIXME: module_ResetBank unimplemented" ); return;}/***************************************************************************** * module_EndBank: empty the module bank. ***************************************************************************** * This function unloads all unused plugin modules and empties the module * bank in case of success. *****************************************************************************/void __module_EndBank( vlc_object_t *p_this ){ module_t * p_next; vlc_value_t lockval; var_Create( p_this->p_libvlc, "libvlc", VLC_VAR_MUTEX ); var_Get( p_this->p_libvlc, "libvlc", &lockval ); vlc_mutex_lock( lockval.p_address ); if( !p_this->p_libvlc->p_module_bank ) { vlc_mutex_unlock( lockval.p_address ); var_Destroy( p_this->p_libvlc, "libvlc" ); return; } if( --p_this->p_libvlc->p_module_bank->i_usage ) { vlc_mutex_unlock( lockval.p_address ); var_Destroy( p_this->p_libvlc, "libvlc" ); return; } vlc_mutex_unlock( lockval.p_address ); var_Destroy( p_this->p_libvlc, "libvlc" ); config_AutoSaveConfigFile( p_this );#ifdef HAVE_DYNAMIC_PLUGINS#define p_bank p_this->p_libvlc->p_module_bank if( p_bank->b_cache ) CacheSave( p_this ); while( p_bank->i_loaded_cache-- ) { free( p_bank->pp_loaded_cache[p_bank->i_loaded_cache]->psz_file ); free( p_bank->pp_loaded_cache[p_bank->i_loaded_cache] ); if( !p_bank->i_loaded_cache ) free( p_bank->pp_loaded_cache ); } while( p_bank->i_cache-- ) { free( p_bank->pp_cache[p_bank->i_cache]->psz_file ); free( p_bank->pp_cache[p_bank->i_cache] ); if( !p_bank->i_cache ) free( p_bank->pp_cache ); }#undef p_bank#endif vlc_object_detach( p_this->p_libvlc->p_module_bank ); while( p_this->p_libvlc->p_module_bank->i_children ) { p_next = (module_t *)p_this->p_libvlc->p_module_bank->pp_children[0]; if( DeleteModule( p_next ) ) { /* Module deletion failed */ msg_Err( p_this, "module \"%s\" can't be removed, trying harder", p_next->psz_object_name ); /* We just free the module by hand. Niahahahahaha. */ vlc_object_detach( p_next ); vlc_object_destroy( p_next ); } } vlc_object_destroy( p_this->p_libvlc->p_module_bank ); p_this->p_libvlc->p_module_bank = NULL; return;}/***************************************************************************** * module_LoadMain: load the main program info into the module bank. ***************************************************************************** * This function fills the module bank structure with the main module infos. * This is very useful as it will allow us to consider the main program just * as another module, and for instance the configuration options of main will * be available in the module bank structure just as for every other module. *****************************************************************************/void __module_LoadMain( vlc_object_t *p_this ){ vlc_value_t lockval; var_Create( p_this->p_libvlc, "libvlc", VLC_VAR_MUTEX ); var_Get( p_this->p_libvlc, "libvlc", &lockval ); vlc_mutex_lock( lockval.p_address ); if( p_this->p_libvlc->p_module_bank->b_main ) { vlc_mutex_unlock( lockval.p_address ); var_Destroy( p_this->p_libvlc, "libvlc" ); return; } p_this->p_libvlc->p_module_bank->b_main = VLC_TRUE; vlc_mutex_unlock( lockval.p_address ); var_Destroy( p_this->p_libvlc, "libvlc" ); AllocateBuiltinModule( p_this, vlc_entry__main );}/***************************************************************************** * module_LoadBuiltins: load all modules which we built with. ***************************************************************************** * This function fills the module bank structure with the builtin modules. *****************************************************************************/void __module_LoadBuiltins( vlc_object_t * p_this ){ vlc_value_t lockval; var_Create( p_this->p_libvlc, "libvlc", VLC_VAR_MUTEX ); var_Get( p_this->p_libvlc, "libvlc", &lockval ); vlc_mutex_lock( lockval.p_address ); if( p_this->p_libvlc->p_module_bank->b_builtins ) { vlc_mutex_unlock( lockval.p_address ); var_Destroy( p_this->p_libvlc, "libvlc" ); return; } p_this->p_libvlc->p_module_bank->b_builtins = VLC_TRUE; vlc_mutex_unlock( lockval.p_address ); var_Destroy( p_this->p_libvlc, "libvlc" ); msg_Dbg( p_this, "checking builtin modules" ); ALLOCATE_ALL_BUILTINS();}/***************************************************************************** * module_LoadPlugins: load all plugin modules we can find. ***************************************************************************** * This function fills the module bank structure with the plugin modules. *****************************************************************************/void __module_LoadPlugins( vlc_object_t * p_this ){#ifdef HAVE_DYNAMIC_PLUGINS vlc_value_t lockval; var_Create( p_this->p_libvlc, "libvlc", VLC_VAR_MUTEX ); var_Get( p_this->p_libvlc, "libvlc", &lockval ); vlc_mutex_lock( lockval.p_address ); if( p_this->p_libvlc->p_module_bank->b_plugins ) { vlc_mutex_unlock( lockval.p_address ); var_Destroy( p_this->p_libvlc, "libvlc" ); return; } p_this->p_libvlc->p_module_bank->b_plugins = VLC_TRUE; vlc_mutex_unlock( lockval.p_address ); var_Destroy( p_this->p_libvlc, "libvlc" ); msg_Dbg( p_this, "checking plugin modules" ); if( config_GetInt( p_this, "plugins-cache" ) ) p_this->p_libvlc->p_module_bank->b_cache = VLC_TRUE; if( p_this->p_libvlc->p_module_bank->b_cache || p_this->p_libvlc->p_module_bank->b_cache_delete ) CacheLoad( p_this ); AllocateAllPlugins( p_this );#endif}/***************************************************************************** * module_Need: return the best module function, given a capability list. ***************************************************************************** * This function returns the module that best fits the asked capabilities. *****************************************************************************/module_t * __module_Need( vlc_object_t *p_this, const char *psz_capability, const char *psz_name, vlc_bool_t b_strict ){ typedef struct module_list_t module_list_t; struct module_list_t { module_t *p_module; int i_score; vlc_bool_t b_force; module_list_t *p_next;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -