📄 modules.c
字号:
psz_alias = c+1; i_shortcut_bonus = i_short * 10000; goto found_shortcut; } } /* Go to the next shortcut... This is so lame! */ psz_name += strlen( psz_name ) + 1; } /* If we are in "strict" mode and we couldn't * find the module in the list of provided shortcuts, * then kick the bastard out of here!!! */ if( b_strict ) continue; } /* If we didn't require a shortcut, trash <= 0 scored plugins */ else if( p_module->i_score <= 0 ) { continue; }found_shortcut: /* Store this new module */ p_list[ i_index ].p_module = p_module; p_list[ i_index ].i_score = p_module->i_score + i_shortcut_bonus; p_list[ i_index ].b_force = i_shortcut_bonus && b_strict; /* Add it to the modules-to-probe list */ if( i_index == 0 ) { p_list[ 0 ].p_next = NULL; p_first = p_list; } else { /* Ok, so at school you learned that quicksort is quick, and * bubble sort sucks raw eggs. But that's when dealing with * thousands of items. Here we have barely 50. */ module_list_t *p_newlist = p_first; if( p_first->i_score < p_list[ i_index ].i_score ) { p_list[ i_index ].p_next = p_first; p_first = &p_list[ i_index ]; } else { while( p_newlist->p_next != NULL && p_newlist->p_next->i_score >= p_list[ i_index ].i_score ) { p_newlist = p_newlist->p_next; } p_list[ i_index ].p_next = p_newlist->p_next; p_newlist->p_next = &p_list[ i_index ]; } } i_index++; } msg_Dbg( p_this, "looking for %s module: %i candidate%s", psz_capability, i_index, i_index == 1 ? "" : "s" ); /* Lock all candidate modules */ p_tmp = p_first; while( p_tmp != NULL ) { vlc_object_yield( p_tmp->p_module ); p_tmp = p_tmp->p_next; } /* We can release the list, interesting modules were yielded */ vlc_list_release( p_all ); /* Parse the linked list and use the first successful module */ p_tmp = p_first; while( p_tmp != NULL ) {#ifdef HAVE_DYNAMIC_PLUGINS /* Make sure the module is loaded in mem */ module_t *p_module = p_tmp->p_module; if( p_module->b_submodule ) p_module = (module_t *)p_module->p_parent; if( !p_module->b_builtin && !p_module->b_loaded ) { module_t *p_new_module = AllocatePlugin( p_this, p_module->psz_filename ); if( p_new_module ) { CacheMerge( p_this, p_module, p_new_module ); vlc_object_attach( p_new_module, p_module ); DeleteModule( p_new_module, true ); } }#endif p_this->b_force = p_tmp->b_force; if( p_tmp->p_module->pf_activate && p_tmp->p_module->pf_activate( p_this ) == VLC_SUCCESS ) { break; } vlc_object_release( p_tmp->p_module ); p_tmp = p_tmp->p_next; } /* Store the locked module value */ if( p_tmp != NULL ) { p_module = p_tmp->p_module; p_tmp = p_tmp->p_next; } else { p_module = NULL; } /* Unlock the remaining modules */ while( p_tmp != NULL ) { vlc_object_release( p_tmp->p_module ); p_tmp = p_tmp->p_next; } free( p_list ); p_this->b_force = b_force_backup; if( p_module != NULL ) { msg_Dbg( p_this, "using %s module \"%s\"", psz_capability, p_module->psz_object_name ); } else if( p_first == NULL ) { if( !strcmp( psz_capability, "access_demux" ) ) { msg_Warn( p_this, "no %s module matched \"%s\"", psz_capability, (psz_name && *psz_name) ? psz_name : "any" ); } else { msg_Err( p_this, "no %s module matched \"%s\"", psz_capability, (psz_name && *psz_name) ? psz_name : "any" ); msg_StackSet( VLC_EGENERIC, "no %s module matched \"%s\"", psz_capability, (psz_name && *psz_name) ? psz_name : "any" ); } } else if( psz_name != NULL && *psz_name ) { msg_Warn( p_this, "no %s module matching \"%s\" could be loaded", psz_capability, (psz_name && *psz_name) ? psz_name : "any" ); } else msg_StackSet( VLC_EGENERIC, "no suitable %s module", psz_capability ); if( p_module && !p_this->psz_object_name ) { /* This assumes that p_this is the object which will be using the * module. That's not always the case ... but it is in most cases. */ if( psz_alias ) p_this->psz_object_name = strdup( psz_alias ); else p_this->psz_object_name = strdup( p_module->psz_object_name ); } free( psz_shortcuts ); 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 ); /* Don't forget that the module is still locked */ return p_module;}/** * Module unneed * * This function must be called by the thread that called module_Need, to * decrease the reference count and allow for hiding of modules. * \param p_this vlc object structure * \param p_module the module structure * \return nothing */void __module_Unneed( vlc_object_t * p_this, module_t * p_module ){ /* Use the close method */ if( p_module->pf_deactivate ) { p_module->pf_deactivate( p_this ); } msg_Dbg( p_this, "removing module \"%s\"", p_module->psz_object_name ); vlc_object_release( p_module );}/** * Get a pointer to a module_t given it's name. * * \param p_this vlc object structure * \param psz_name the name of the module * \return a pointer to the module or NULL in case of a failure */module_t *__module_Find( vlc_object_t *p_this, const char * psz_name ){ vlc_list_t *p_list; int i; p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE ); for( i = 0 ; i < p_list->i_count; i++) { module_t *p_module = ((module_t *) p_list->p_values[i].p_object); const char *psz_module_name = p_module->psz_object_name; if( psz_module_name && !strcmp( psz_module_name, psz_name ) ) { /* We can release the list, and return yes */ vlc_object_yield( p_module ); vlc_list_release( p_list ); return p_module; } } vlc_list_release( p_list ); return NULL;}/** * Release a module_t pointer from module_Find(). * * \param module the module to release * \return nothing */void module_Put( module_t *module ){ vlc_object_release( module );}/** * Tell if a module exists and release it in thic case * * \param p_this vlc object structure * \param psz_name th name of the module * \return TRUE if the module exists */bool __module_Exists( vlc_object_t *p_this, const char * psz_name ){ module_t *p_module = __module_Find( p_this, psz_name ); if( p_module ) { module_Put( p_module ); return true; } else { return false; }}/** * GetModuleNamesForCapability * * Return a NULL terminated array with the names of the modules * that have a certain capability. * Free after uses both the string and the table. * \param p_this vlc object structure * \param psz_capability the capability asked * \param pppsz_longname an pointer to an array of string to contain the long names of the modules. If set to NULL the function don't use it. * \return the NULL terminated array */char ** __module_GetModulesNamesForCapability( vlc_object_t *p_this, const char *psz_capability, char ***pppsz_longname ){ vlc_list_t *p_list; int i, j, count = 0; char **psz_ret; /* Do it in two passes : count the number of modules before */ p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE ); for( i = 0 ; i < p_list->i_count; i++) { module_t *p_module = ((module_t *) p_list->p_values[i].p_object); const char *psz_module_capability = p_module->psz_capability; if( psz_module_capability && !strcmp( psz_module_capability, psz_capability ) ) count++; } psz_ret = malloc( sizeof(char*) * (count+1) ); if( pppsz_longname ) *pppsz_longname = malloc( sizeof(char*) * (count+1) ); if( !psz_ret || ( pppsz_longname && *pppsz_longname == NULL ) ) { free( psz_ret ); free( *pppsz_longname ); *pppsz_longname = NULL; vlc_list_release( p_list ); return NULL; } j = 0; for( i = 0 ; i < p_list->i_count; i++) { module_t *p_module = ((module_t *) p_list->p_values[i].p_object); const char *psz_module_capability = p_module->psz_capability; if( psz_module_capability && !strcmp( psz_module_capability, psz_capability ) ) { int k = -1; /* hack to handle submodules properly */ if( p_module->b_submodule ) { while( p_module->pp_shortcuts[++k] != NULL ); k--; } psz_ret[j] = strdup( k>=0?p_module->pp_shortcuts[k] :p_module->psz_object_name ); if( pppsz_longname ) (*pppsz_longname)[j] = strdup( module_GetName( p_module, true ) ); j++; } } psz_ret[count] = NULL; vlc_list_release( p_list ); return psz_ret;}/** * Get the configuration of a module * * \param module the module * \param psize the size of the configuration returned * \return the configuration as an array */module_config_t *module_GetConfig( const module_t *module, unsigned *restrict psize ){ unsigned i,j; unsigned size = module->confsize; module_config_t *config = malloc( size * sizeof( *config ) ); assert( psize != NULL ); *psize = 0; if( !config ) return NULL; for( i = 0, j = 0; i < size; i++ ) { const module_config_t *item = module->p_config + i; if( item->b_internal /* internal option */ || item->b_unsaveable /* non-modifiable option */ || item->b_removed /* removed option */ ) continue; memcpy( config + j, item, sizeof( *config ) ); j++; } *psize = j; return config;}/** * Release the configuration * * \param the configuration * \return nothing */void module_PutConfig( module_config_t *config ){ free( config );}/***************************************************************************** * Following functions are local. *****************************************************************************/ /***************************************************************************** * copy_next_paths_token: from a PATH_SEP_CHAR (a ':' or a ';') separated paths * return first path. *****************************************************************************/static char * copy_next_paths_token( char * paths, char ** remaining_paths ){ char * path; int i, done; bool escaped = false; assert( paths ); /* Alloc a buffer to store the path */ path = malloc( strlen( paths ) + 1 ); if( !path ) return NULL; /* Look for PATH_SEP_CHAR (a ':' or a ';') */ for( i = 0, done = 0 ; paths[i]; i++ ) { /* Take care of \\ and \: or \; escapement */ if( escaped ) { escaped = false; path[done++] = paths[i]; }#ifdef WIN32 else if( paths[i] == '/' ) escaped = true;#else else if( paths[i] == '\\' ) escaped = true;#endif else if( paths[i] == PATH_SEP_CHAR ) break; else path[done++] = paths[i]; } path[done++] = 0; /* Return the remaining paths */ if( remaining_paths ) { *remaining_paths = paths[i] ? &paths[i]+1 : NULL; } return path;}/***************************************************************************** * AllocateAllPlugins: load all plugin modules we can find. *****************************************************************************/#ifdef HAVE_DYNAMIC_PLUGINSstatic void AllocateAllPlugins( vlc_object_t *p_this ){ const char *vlcpath = vlc_global()->psz_vlcpath; int count,i; char * path; vlc_array_t *arraypaths = vlc_array_new(); /* Contruct the special search path for system that have a relocatable * executable. Set it to <vlc path>/modules and <vlc path>/plugins. */ if( vlcpath && asprintf( &path, "%s" DIR_SEP "modules", vlcpath ) != -1 ) vlc_array_append( arraypaths, path ); if( vlcpath && asprintf( &path, "%s" DIR_SEP "plugins", vlcpath ) != -1 ) vlc_array_append( arraypaths, path );#ifndef WIN32 vlc_array_append( arraypaths, strdup( PLUGIN_PATH ) );#endif /* If the user provided a plugin path, we add it to the list */ char *userpaths = config_GetPsz( p_this, "plugin-path" ); char *paths_iter; for( paths_iter = userpaths; paths_iter; ) { path = copy_next_paths_token( paths_iter, &paths_iter ); if( path ) vlc_array_append( arraypaths, path ); } count = vlc_array_count( arraypaths ); for( i = 0 ; i < count ; i++ ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -