⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modules.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************** * modules.c : Builtin and plugin modules management functions ***************************************************************************** * Copyright (C) 2001-2007 the VideoLAN team * $Id: 9ff601b3a6aa5916a564b14758292fdc99d412df $ * * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_plugin.h>#include "libvlc.h"/* 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 <assert.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 "config/configuration.h"#include "vlc_charset.h"#include "vlc_arrays.h"#include "modules/modules.h"#include "modules/builtin.h"/***************************************************************************** * 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 void DeleteModule ( module_t *, bool );#ifdef HAVE_DYNAMIC_PLUGINSstatic void   DupModule        ( module_t * );static void   UndupModule      ( module_t * );#endif/** * Init bank * * Creates a module bank structure which will be filled later * on with all the modules found. * \param p_this vlc object structure * \return nothing */void __module_InitBank( vlc_object_t *p_this ){    module_bank_t *p_bank = NULL;    libvlc_global_data_t *p_libvlc_global = vlc_global();    vlc_mutex_t *lock = var_AcquireMutex( "libvlc" );    if( p_libvlc_global->p_module_bank == NULL )    {        p_bank = vlc_custom_create( p_this, sizeof(module_bank_t),                                    VLC_OBJECT_GENERIC, "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 = NULL;        p_bank->b_cache = p_bank->b_cache_dirty =        p_bank->b_cache_delete = false;        /* Everything worked, attach the object */        p_libvlc_global->p_module_bank = p_bank;        vlc_object_attach( p_bank, p_libvlc_global );        /* Fills the module bank structure with the main module infos.         * This is very useful as it will allow us to consider the main         * library 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. */        AllocateBuiltinModule( p_this, vlc_entry__main );    }    else        p_libvlc_global->p_module_bank->i_usage++;    vlc_mutex_unlock( lock );}/** * End bank * * Unloads all unused plugin modules and empties the module * bank in case of success. * \param p_this vlc object structure * \return nothing */void __module_EndBank( vlc_object_t *p_this ){    module_t * p_next = NULL;    libvlc_global_data_t *p_libvlc_global = vlc_global();    vlc_mutex_t *lock = var_AcquireMutex( "libvlc" );    if( !p_libvlc_global->p_module_bank )    {        vlc_mutex_unlock( lock );        return;    }    if( --p_libvlc_global->p_module_bank->i_usage )    {        vlc_mutex_unlock( lock );        return;    }    vlc_mutex_unlock( lock );    /* Save the configuration */    config_AutoSaveConfigFile( p_this );#ifdef HAVE_DYNAMIC_PLUGINS# define p_bank p_libvlc_global->p_module_bank    if( p_bank->b_cache ) CacheSave( p_this );    while( p_bank->i_loaded_cache-- )    {        if( p_bank->pp_loaded_cache[p_bank->i_loaded_cache] )        {            DeleteModule(                    p_bank->pp_loaded_cache[p_bank->i_loaded_cache]->p_module,                    p_bank->pp_loaded_cache[p_bank->i_loaded_cache]->b_used );            free( p_bank->pp_loaded_cache[p_bank->i_loaded_cache]->psz_file );            free( p_bank->pp_loaded_cache[p_bank->i_loaded_cache] );            p_bank->pp_loaded_cache[p_bank->i_loaded_cache] = NULL;        }    }    if( p_bank->pp_loaded_cache )    {        free( p_bank->pp_loaded_cache );        p_bank->pp_loaded_cache = NULL;    }    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] );        p_bank->pp_cache[p_bank->i_cache] = NULL;    }    if( p_bank->pp_cache )    {        free( p_bank->pp_cache );        p_bank->pp_cache = NULL;    }# undef p_bank#endif    vlc_object_detach( p_libvlc_global->p_module_bank );    while( vlc_internals( p_libvlc_global->p_module_bank )->i_children )    {        p_next = (module_t *)vlc_internals( p_libvlc_global->p_module_bank )->pp_children[0];        DeleteModule( p_next, true );    }    vlc_object_release( p_libvlc_global->p_module_bank );    p_libvlc_global->p_module_bank = NULL;}/** * Load all modules which we built with. * * Fills the module bank structure with the builtin modules. * \param p_this vlc object structure * \return nothing */void __module_LoadBuiltins( vlc_object_t * p_this ){    libvlc_global_data_t *p_libvlc_global = vlc_global();    vlc_mutex_t *lock = var_AcquireMutex( "libvlc" );    if( p_libvlc_global->p_module_bank->b_builtins )    {        vlc_mutex_unlock( lock );        return;    }    p_libvlc_global->p_module_bank->b_builtins = true;    vlc_mutex_unlock( lock );    msg_Dbg( p_this, "checking builtin modules" );    ALLOCATE_ALL_BUILTINS();}/** * Load all plugins * * Load all plugin modules we can find. * Fills the module bank structure with the plugin modules. * \param p_this vlc object structure * \return nothing */void __module_LoadPlugins( vlc_object_t * p_this ){#ifdef HAVE_DYNAMIC_PLUGINS    libvlc_global_data_t *p_libvlc_global = vlc_global();    vlc_mutex_t *lock = var_AcquireMutex( "libvlc" );    if( p_libvlc_global->p_module_bank->b_plugins )    {        vlc_mutex_unlock( lock );        return;    }    p_libvlc_global->p_module_bank->b_plugins = true;    vlc_mutex_unlock( lock );    msg_Dbg( p_this, "checking plugin modules" );    if( config_GetInt( p_this, "plugins-cache" ) )        p_libvlc_global->p_module_bank->b_cache = true;    if( p_libvlc_global->p_module_bank->b_cache ||        p_libvlc_global->p_module_bank->b_cache_delete ) CacheLoad( p_this );    AllocateAllPlugins( p_this );#endif}/** * Checks whether a module implements a capability. * * \param m the module * \param cap the capability to check * \return TRUE if the module have the capability */bool module_IsCapable( const module_t *m, const char *cap ){    return !strcmp( m->psz_capability, cap );}/** * Get the internal name of a module * * \param m the module * \return the module name */const char *module_GetObjName( const module_t *m ){    return m->psz_object_name;}/** * Get the human-friendly name of a module. * * \param m the module * \param long_name TRUE to have the long name of the module * \return the short or long name of the module */const char *module_GetName( const module_t *m, bool long_name ){    if( long_name && ( m->psz_longname != NULL) )        return m->psz_longname;    return m->psz_shortname ?: m->psz_object_name;}/** * Get the help for a module * * \param m the module * \return the help */const char *module_GetHelp( const module_t *m ){    return m->psz_help;}/** * module Need * * Return the best module function, given a capability list. * \param p_this the vlc object * \param psz_capability list of capabilities needed * \param psz_name name of the module asked * \param b_strict TRUE yto use the strict mode * \return the module or NULL in case of a failure */module_t * __module_Need( vlc_object_t *p_this, const char *psz_capability,                          const char *psz_name, bool b_strict ){    typedef struct module_list_t module_list_t;    stats_TimerStart( p_this, "module_Need()", STATS_TIMER_MODULE_NEED );    struct module_list_t    {        module_t *p_module;        int i_score;        bool b_force;        module_list_t *p_next;    };    module_list_t *p_list, *p_first, *p_tmp;    vlc_list_t *p_all;    int i_which_module, i_index = 0;    module_t *p_module;    int   i_shortcuts = 0;    char *psz_shortcuts = NULL, *psz_var = NULL, *psz_alias = NULL;    bool b_force_backup = p_this->b_force;    /* Deal with variables */    if( psz_name && psz_name[0] == '$' )    {        psz_name = psz_var = var_CreateGetString( p_this, psz_name + 1 );    }    /* Count how many different shortcuts were asked for */    if( psz_name && *psz_name )    {        char *psz_parser, *psz_last_shortcut;        /* If the user wants none, give him none. */        if( !strcmp( psz_name, "none" ) )        {            free( psz_var );            stats_TimerStop( p_this, STATS_TIMER_MODULE_NEED );            stats_TimerDump( p_this, STATS_TIMER_MODULE_NEED );            stats_TimerClean( p_this, STATS_TIMER_MODULE_NEED );            return NULL;        }        i_shortcuts++;        psz_shortcuts = psz_last_shortcut = strdup( psz_name );        for( psz_parser = psz_shortcuts; *psz_parser; psz_parser++ )        {            if( *psz_parser == ',' )            {                 *psz_parser = '\0';                 i_shortcuts++;                 psz_last_shortcut = psz_parser + 1;            }        }        /* Check if the user wants to override the "strict" mode */        if( psz_last_shortcut )        {            if( !strcmp(psz_last_shortcut, "none") )            {                b_strict = true;                i_shortcuts--;            }            else if( !strcmp(psz_last_shortcut, "any") )            {                b_strict = false;                i_shortcuts--;            }        }    }    /* Sort the modules and test them */    p_all = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );    p_list = malloc( p_all->i_count * sizeof( module_list_t ) );    p_first = NULL;    unsigned i_cpu = vlc_CPU();    /* Parse the module list for capabilities and probe each of them */    for( i_which_module = 0; i_which_module < p_all->i_count; i_which_module++ )    {        int i_shortcut_bonus = 0;        p_module = (module_t *)p_all->p_values[i_which_module].p_object;        /* Test that this module can do what we need */        if( !module_IsCapable( p_module, psz_capability ) )        {            /* Don't recurse through the sub-modules because vlc_list_find()             * will list them anyway. */            continue;        }        /* Test if we have the required CPU */        if( (p_module->i_cpu & i_cpu) != p_module->i_cpu )        {            continue;        }        /* If we required a shortcut, check this plugin provides it. */        if( i_shortcuts > 0 )        {            bool b_trash;            const char *psz_name = psz_shortcuts;            /* Let's drop modules with a <= 0 score (unless they are             * explicitly requested) */            b_trash = p_module->i_score <= 0;            for( unsigned i_short = i_shortcuts; i_short > 0; i_short-- )            {                for( unsigned i = 0; p_module->pp_shortcuts[i]; i++ )                {                    char *c;                    if( ( c = strchr( psz_name, '@' ) )                        ? !strncasecmp( psz_name, p_module->pp_shortcuts[i],                                        c-psz_name )                        : !strcasecmp( psz_name, p_module->pp_shortcuts[i] ) )                    {                        /* Found it */                        if( c && c[1] )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -