Fixed a crash caused by yadif deinterlacer on Windows XP
[vlc/solaris.git] / src / modules / modules.c
blobe124ae72b576870da42c626e78f0ee7051d7841b
1 /*****************************************************************************
2 * modules.c : Builtin and plugin modules management functions
3 *****************************************************************************
4 * Copyright (C) 2001-2011 VLC authors and VideoLAN
5 * $Id$
7 * Authors: Sam Hocevar <sam@zoy.org>
8 * Ethan C. Baldridge <BaldridgeE@cadmus.com>
9 * Hans-Peter Jansen <hpj@urpla.net>
10 * Gildas Bazin <gbazin@videolan.org>
11 * RĂ©mi Denis-Courmont
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU Lesser General Public License as published by
15 * the Free Software Foundation; either version 2.1 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License for more details.
23 * You should have received a copy of the GNU Lesser General Public License
24 * along with this program; if not, write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26 *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
32 #include <stdlib.h>
33 #include <string.h>
34 #ifdef ENABLE_NLS
35 # include <libintl.h>
36 #endif
37 #include <assert.h>
39 #include <vlc_common.h>
40 #include <vlc_modules.h>
41 #include "libvlc.h"
42 #include "config/configuration.h"
43 #include "vlc_arrays.h"
44 #include "modules/modules.h"
46 /**
47 * Checks whether a module implements a capability.
49 * \param m the module
50 * \param cap the capability to check
51 * \return TRUE if the module have the capability
53 bool module_provides( const module_t *m, const char *cap )
55 if (unlikely(m->psz_capability == NULL))
56 return false;
57 return !strcmp( m->psz_capability, cap );
60 /**
61 * Get the internal name of a module
63 * \param m the module
64 * \return the module name
66 const char *module_get_object( const module_t *m )
68 if (unlikely(m->i_shortcuts == 0))
69 return "unnamed";
70 return m->pp_shortcuts[0];
73 /**
74 * Get the human-friendly name of a module.
76 * \param m the module
77 * \param long_name TRUE to have the long name of the module
78 * \return the short or long name of the module
80 const char *module_get_name( const module_t *m, bool long_name )
82 if( long_name && ( m->psz_longname != NULL) )
83 return m->psz_longname;
85 if (m->psz_shortname != NULL)
86 return m->psz_shortname;
87 return module_get_object (m);
90 /**
91 * Get the help for a module
93 * \param m the module
94 * \return the help
96 const char *module_get_help( const module_t *m )
98 return m->psz_help;
102 * Get the capability for a module
104 * \param m the module
105 * return the capability
107 const char *module_get_capability( const module_t *m )
109 return m->psz_capability;
113 * Get the score for a module
115 * \param m the module
116 * return the score for the capability
118 int module_get_score( const module_t *m )
120 return m->i_score;
124 * Translate a string using the module's text domain
126 * \param m the module
127 * \param str the American English ASCII string to localize
128 * \return the gettext-translated string
130 const char *module_gettext (const module_t *m, const char *str)
132 if (m->parent != NULL)
133 m = m->parent;
134 if (unlikely(str == NULL || *str == '\0'))
135 return "";
136 #ifdef ENABLE_NLS
137 const char *domain = m->domain;
138 return dgettext ((domain != NULL) ? domain : PACKAGE_NAME, str);
139 #else
140 (void)m;
141 return str;
142 #endif
145 #undef module_start
146 int module_start (vlc_object_t *obj, const module_t *m)
148 int (*activate) (vlc_object_t *) = m->pf_activate;
150 return (activate != NULL) ? activate (obj) : VLC_SUCCESS;
153 #undef module_stop
154 void module_stop (vlc_object_t *obj, const module_t *m)
156 void (*deactivate) (vlc_object_t *) = m->pf_deactivate;
158 if (deactivate != NULL)
159 deactivate (obj);
162 typedef struct module_list_t
164 module_t *p_module;
165 int16_t i_score;
166 bool b_force;
167 } module_list_t;
169 static int modulecmp (const void *a, const void *b)
171 const module_list_t *la = a, *lb = b;
172 /* Note that qsort() uses _ascending_ order,
173 * so the smallest module is the one with the biggest score. */
174 return lb->i_score - la->i_score;
177 #undef vlc_module_load
179 * Finds and instantiates the best module of a certain type.
180 * All candidates modules having the specified capability and name will be
181 * sorted in decreasing order of priority. Then the probe callback will be
182 * invoked for each module, until it succeeds (returns 0), or all candidate
183 * module failed to initialize.
185 * The probe callback first parameter is the address of the module entry point.
186 * Further parameters are passed as an argument list; it corresponds to the
187 * variable arguments passed to this function. This scheme is meant to
188 * support arbitrary prototypes for the module entry point.
190 * \param p_this VLC object
191 * \param psz_capability capability, i.e. class of module
192 * \param psz_name name name of the module asked, if any
193 * \param b_strict if true, do not fallback to plugin with a different name
194 * but the same capability
195 * \param probe module probe callback
196 * \return the module or NULL in case of a failure
198 module_t *vlc_module_load(vlc_object_t *p_this, const char *psz_capability,
199 const char *psz_name, bool b_strict,
200 vlc_activate_t probe, ...)
202 module_list_t *p_list;
203 module_t *p_module;
204 int i_shortcuts = 0;
205 char *psz_shortcuts = NULL, *psz_var = NULL, *psz_alias = NULL;
206 bool b_force_backup = p_this->b_force;
208 /* Deal with variables */
209 if( psz_name && psz_name[0] == '$' )
211 psz_name = psz_var = var_CreateGetString( p_this, psz_name + 1 );
214 /* Count how many different shortcuts were asked for */
215 if( psz_name && *psz_name )
217 char *psz_parser, *psz_last_shortcut;
219 /* If the user wants none, give him none. */
220 if( !strcmp( psz_name, "none" ) )
222 free( psz_var );
223 return NULL;
226 i_shortcuts++;
227 psz_parser = psz_shortcuts = psz_last_shortcut = strdup( psz_name );
229 while( ( psz_parser = strchr( psz_parser, ',' ) ) )
231 *psz_parser = '\0';
232 i_shortcuts++;
233 psz_last_shortcut = ++psz_parser;
236 /* Check if the user wants to override the "strict" mode */
237 if( psz_last_shortcut )
239 if( !strcmp(psz_last_shortcut, "none") )
241 b_strict = true;
242 i_shortcuts--;
244 else if( !strcmp(psz_last_shortcut, "any") )
246 b_strict = false;
247 i_shortcuts--;
252 /* Sort the modules and test them */
253 size_t count;
254 module_t **p_all = module_list_get (&count);
255 p_list = malloc( count * sizeof( module_list_t ) );
257 /* Parse the module list for capabilities and probe each of them */
258 count = 0;
259 for (size_t i = 0; (p_module = p_all[i]) != NULL; i++)
261 int i_shortcut_bonus = 0;
263 /* Test that this module can do what we need */
264 if( !module_provides( p_module, psz_capability ) )
265 continue;
267 /* If we required a shortcut, check this plugin provides it. */
268 if( i_shortcuts > 0 )
270 const char *name = psz_shortcuts;
272 for( unsigned i_short = i_shortcuts; i_short > 0; i_short-- )
274 for( unsigned i = 0; i < p_module->i_shortcuts; i++ )
276 char *c;
277 if( ( c = strchr( name, '@' ) )
278 ? !strncasecmp( name, p_module->pp_shortcuts[i],
279 c-name )
280 : !strcasecmp( name, p_module->pp_shortcuts[i] ) )
282 /* Found it */
283 if( c && c[1] )
284 psz_alias = c+1;
285 i_shortcut_bonus = i_short * 10000;
286 goto found_shortcut;
290 /* Go to the next shortcut... This is so lame! */
291 name += strlen( name ) + 1;
294 /* If we are in "strict" mode and we couldn't
295 * find the module in the list of provided shortcuts,
296 * then kick the bastard out of here!!! */
297 if( b_strict )
298 continue;
301 /* Trash <= 0 scored plugins (they can only be selected by shortcut) */
302 if( p_module->i_score <= 0 )
303 continue;
305 found_shortcut:
306 /* Store this new module */
307 p_list[count].p_module = p_module;
308 p_list[count].i_score = p_module->i_score + i_shortcut_bonus;
309 p_list[count].b_force = i_shortcut_bonus && b_strict;
310 count++;
313 /* We can release the list, interesting modules are held */
314 module_list_free (p_all);
316 /* Sort candidates by descending score */
317 qsort (p_list, count, sizeof (p_list[0]), modulecmp);
318 msg_Dbg( p_this, "looking for %s module: %zu candidate%s", psz_capability,
319 count, count == 1 ? "" : "s" );
321 /* Parse the linked list and use the first successful module */
322 va_list args;
324 va_start(args, probe);
325 p_module = NULL;
327 for (size_t i = 0; (i < count) && (p_module == NULL); i++)
329 module_t *p_cand = p_list[i].p_module;
331 if (module_Map (p_this, p_cand))
332 continue;
333 p_this->b_force = p_list[i].b_force;
335 int ret;
337 if (likely(p_cand->pf_activate != NULL))
339 va_list ap;
341 va_copy(ap, args);
342 ret = probe(p_cand->pf_activate, ap);
343 va_end(ap);
345 else
346 ret = VLC_SUCCESS;
348 switch (ret)
350 case VLC_SUCCESS:
351 /* good module! */
352 p_module = p_cand;
353 break;
355 case VLC_ETIMEOUT:
356 /* good module, but aborted */
357 break;
359 default: /* bad module */
360 continue;
364 va_end (args);
365 free( p_list );
366 p_this->b_force = b_force_backup;
368 if( p_module != NULL )
370 msg_Dbg( p_this, "using %s module \"%s\"",
371 psz_capability, module_get_object(p_module) );
372 vlc_object_set_name( p_this, psz_alias ? psz_alias
373 : module_get_object(p_module) );
375 else if( count == 0 )
376 msg_Dbg( p_this, "no %s module matched \"%s\"",
377 psz_capability, (psz_name && *psz_name) ? psz_name : "any" );
378 else
379 msg_Dbg( p_this, "no %s module matching \"%s\" could be loaded",
380 psz_capability, (psz_name && *psz_name) ? psz_name : "any" );
382 free( psz_shortcuts );
383 free( psz_var );
385 /* Don't forget that the module is still locked */
386 return p_module;
391 * Deinstantiates a module.
392 * \param module the module pointer as returned by vlc_module_load()
393 * \param deinit deactivation callback
395 void vlc_module_unload(module_t *module, vlc_deactivate_t deinit, ...)
397 if (module->pf_deactivate != NULL)
399 va_list ap;
401 va_start(ap, deinit);
402 deinit(module->pf_deactivate, ap);
403 va_end(ap);
408 static int generic_start(void *func, va_list ap)
410 vlc_object_t *obj = va_arg(ap, vlc_object_t *);
411 int (*activate)(vlc_object_t *) = func;
413 return activate(obj);
416 static void generic_stop(void *func, va_list ap)
418 vlc_object_t *obj = va_arg(ap, vlc_object_t *);
419 void (*deactivate)(vlc_object_t *) = func;
421 deactivate(obj);
424 #undef module_need
425 module_t *module_need(vlc_object_t *obj, const char *cap, const char *name,
426 bool strict)
428 return vlc_module_load(obj, cap, name, strict, generic_start, obj);
431 #undef module_unneed
432 void module_unneed(vlc_object_t *obj, module_t *module)
434 msg_Dbg(obj, "removing module \"%s\"", module_get_object(module));
435 vlc_module_unload(module, generic_stop, obj);
439 * Get a pointer to a module_t given it's name.
441 * \param name the name of the module
442 * \return a pointer to the module or NULL in case of a failure
444 module_t *module_find (const char *name)
446 module_t **list, *module;
448 assert (name != NULL);
449 list = module_list_get (NULL);
450 if (!list)
451 return NULL;
453 for (size_t i = 0; (module = list[i]) != NULL; i++)
455 if (unlikely(module->i_shortcuts == 0))
456 continue;
457 if (!strcmp (module->pp_shortcuts[0], name))
458 break;
460 module_list_free (list);
461 return module;
465 * Tell if a module exists and release it in thic case
467 * \param psz_name th name of the module
468 * \return TRUE if the module exists
470 bool module_exists (const char * psz_name)
472 return module_find (psz_name) != NULL;
476 * Get a pointer to a module_t that matches a shortcut.
477 * This is a temporary hack for SD. Do not re-use (generally multiple modules
478 * can have the same shortcut, so this is *broken* - use module_need()!).
480 * \param psz_shortcut shortcut of the module
481 * \param psz_cap capability of the module
482 * \return a pointer to the module or NULL in case of a failure
484 module_t *module_find_by_shortcut (const char *psz_shortcut)
486 module_t **list, *module;
488 list = module_list_get (NULL);
489 if (!list)
490 return NULL;
492 for (size_t i = 0; (module = list[i]) != NULL; i++)
493 for (size_t j = 0; j < module->i_shortcuts; j++)
494 if (!strcmp (module->pp_shortcuts[j], psz_shortcut))
495 goto out;
496 out:
497 module_list_free (list);
498 return module;
502 * Get the configuration of a module
504 * \param module the module
505 * \param psize the size of the configuration returned
506 * \return the configuration as an array
508 module_config_t *module_config_get( const module_t *module, unsigned *restrict psize )
510 unsigned i,j;
511 unsigned size = module->confsize;
512 module_config_t *config = malloc( size * sizeof( *config ) );
514 assert( psize != NULL );
515 *psize = 0;
517 if( !config )
518 return NULL;
520 for( i = 0, j = 0; i < size; i++ )
522 const module_config_t *item = module->p_config + i;
523 if( item->b_internal /* internal option */
524 || item->b_removed /* removed option */ )
525 continue;
527 memcpy( config + j, item, sizeof( *config ) );
528 j++;
530 *psize = j;
532 return config;
536 * Release the configuration
538 * \param the configuration
539 * \return nothing
541 void module_config_free( module_config_t *config )
543 free( config );