📄 modules.c
字号:
}; module_list_t *p_list, *p_first, *p_tmp; vlc_list_t *p_all; int i_which_module, i_index = 0; vlc_bool_t b_intf = VLC_FALSE; module_t *p_module; int i_shortcuts = 0; char *psz_shortcuts = NULL, *psz_var = NULL; vlc_bool_t b_force_backup = p_this->b_force; /* Deal with variables */ if( psz_name && psz_name[0] == '$' ) { vlc_value_t val; var_Create( p_this, psz_name + 1, VLC_VAR_MODULE | VLC_VAR_DOINHERIT ); var_Get( p_this, psz_name + 1, &val ); psz_var = val.psz_string; psz_name = psz_var; } /* 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" ) ) { if( psz_var ) free( psz_var ); 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 = VLC_TRUE; i_shortcuts--; } else if( !strcmp(psz_last_shortcut, "any") ) { b_strict = VLC_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; /* 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( strcmp( p_module->psz_capability, 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 & p_this->p_libvlc->i_cpu) != p_module->i_cpu ) { continue; } /* If we required a shortcut, check this plugin provides it. */ if( i_shortcuts > 0 ) { vlc_bool_t b_trash; int i_dummy, i_short = i_shortcuts; 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; while( i_short > 0 ) { for( i_dummy = 0; p_module->pp_shortcuts[i_dummy]; i_dummy++ ) { if( !strcasecmp( psz_name, p_module->pp_shortcuts[i_dummy] ) ) { /* Found it */ b_trash = VLC_FALSE; i_shortcut_bonus = i_short * 10000; break; } } if( i_shortcut_bonus ) { /* We found it... remember ? */ break; } /* Go to the next shortcut... This is so lame! */ while( *psz_name ) { psz_name++; } psz_name++; i_short--; } /* 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( i_short == 0 && b_strict ) { b_trash = VLC_TRUE; } if( b_trash ) { continue; } } /* If we didn't require a shortcut, trash <= 0 scored plugins */ else if( p_module->i_score <= 0 ) { continue; } /* Special case: test if we requested a particular intf plugin */ if( !i_shortcuts && p_module->psz_program && !strcmp( psz_capability, "interface" ) && !strcmp( p_module->psz_program, p_this->p_vlc->psz_object_name ) ) { if( !b_intf ) { /* Remove previous non-matching plugins */ i_index = 0; b_intf = VLC_TRUE; } } else if( b_intf ) { /* This one doesn't match */ continue; } /* 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; /* 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->b_submodule ? (module_t *)p_tmp->p_module->p_parent : p_tmp->p_module; 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 ); } }#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_module, "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" ); } } 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" ); } if( psz_shortcuts ) { free( psz_shortcuts ); } if( psz_var ) { free( psz_var ); } /* Don't forget that the module is still locked */ return p_module;}/***************************************************************************** * module_Unneed: decrease the usage count of a module. ***************************************************************************** * This function must be called by the thread that called module_Need, to * decrease the reference count and allow for hiding of modules. *****************************************************************************/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_module, "unlocking module \"%s\"", p_module->psz_object_name ); vlc_object_release( p_module ); return;}/***************************************************************************** * Following functions are local. *****************************************************************************//***************************************************************************** * AllocateAllPlugins: load all plugin modules we can find. *****************************************************************************/#ifdef HAVE_DYNAMIC_PLUGINSstatic void AllocateAllPlugins( vlc_object_t *p_this ){ /* Yes, there are two NULLs because we replace one with "plugin-path". */#if defined( WIN32 ) || defined( UNDER_CE ) char *path[] = { "modules", "", "plugins", 0, 0 };#else char *path[] = { "modules", PLUGIN_PATH, "plugins", 0, 0 };#endif char **ppsz_path = path; char *psz_fullpath; /* If the user provided a plugin path, we add it to the list */ path[ sizeof(path)/sizeof(char*) - 2 ] = config_GetPsz( p_this, "plugin-path" ); for( ; *ppsz_path != NULL ; ppsz_path++ ) { if( !(*ppsz_path)[0] ) continue;#if defined( SYS_BEOS ) || defined( SYS_DARWIN ) || defined( WIN32 ) /* Handle relative as well as absolute paths */#ifdef WIN32 if( (*ppsz_path)[0] != '\\' && (*ppsz_path)[0] != '/' && (*ppsz_path)[1] != ':' )#else if( (*ppsz_path)[0] != '/' )#endif { int i_dirlen = strlen( *ppsz_path ); i_dirlen += strlen( p_this->p_libvlc->psz_vlcpath ) + 2; psz_fullpath = malloc( i_dirlen ); if( psz_fullpath == NULL ) { continue; }#ifdef WIN32 sprintf( psz_fullpath, "%s\\%s", p_this->p_libvlc->psz_vlcpath, *ppsz_path );#else sprintf( psz_fullpath, "%s/%s", p_this->p_libvlc->psz_vlcpath, *ppsz_path );#endif } else#endif { psz_fullpath = strdup( *ppsz_path ); } msg_Dbg( p_this, "recursively browsing `%s'", psz_fullpath ); /* Don't go deeper than 5 subdirectories */ AllocatePluginDir( p_this, psz_fullpath, 5 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -