Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2000-2012
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / common tools sub-project
9 : *
10 : * GPAC is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU Lesser General Public License as published by
12 : * the Free Software Foundation; either version 2, or (at your option)
13 : * any later version.
14 : *
15 : * GPAC is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU Lesser General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU Lesser General Public
21 : * License along with this library; see the file COPYING. If not, write to
22 : * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 : *
24 : */
25 :
26 : #include "module_wrap.h"
27 : #include <gpac/config_file.h>
28 : #include <gpac/tools.h>
29 : #include <gpac/network.h>
30 :
31 :
32 :
33 : #ifndef GPAC_MODULE_CUSTOM_LOAD
34 : static void load_all_modules(GF_ModuleManager *mgr)
35 : {
36 : #define LOAD_PLUGIN( __name ) { \
37 : GF_InterfaceRegister *gf_register_module_##__name(); \
38 : pr = gf_register_module_##__name();\
39 : if (!pr) {\
40 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("Failed to statically load module ##__name\n"));\
41 : } else {\
42 : gf_list_add(mgr->plugin_registry, pr); \
43 : } \
44 : }
45 :
46 : #ifdef GPAC_STATIC_MODULES
47 : GF_InterfaceRegister *pr;
48 :
49 : #ifdef GPAC_HAS_SDL
50 : LOAD_PLUGIN(sdl_out);
51 : #endif
52 :
53 : #ifdef GPAC_HAS_FREETYPE
54 : LOAD_PLUGIN(ftfont);
55 : #endif
56 : #ifdef GPAC_HAS_ALSA
57 : LOAD_PLUGIN(alsa);
58 : #endif
59 :
60 : #ifdef GPAC_HAS_DIRECTFB
61 : LOAD_PLUGIN(directfb_out);
62 : #endif
63 :
64 : #ifdef GPAC_HAS_DIRECTX
65 : LOAD_PLUGIN(dx_out);
66 : #endif
67 :
68 : #ifdef GPAC_HAS_JACK
69 : LOAD_PLUGIN(jack);
70 : #endif
71 :
72 : #ifdef GPAC_HAS_OSS
73 : LOAD_PLUGIN(oss);
74 : #endif
75 :
76 : #ifdef GPAC_HAS_PULSEAUDIO
77 : LOAD_PLUGIN(pulseaudio);
78 : #endif
79 :
80 : LOAD_PLUGIN(validator);
81 :
82 : #ifdef GPAC_HAS_WAVEOUT
83 : LOAD_PLUGIN(wave_out);
84 : #endif
85 :
86 : #ifdef GPAC_HAS_X11
87 : LOAD_PLUGIN(x11_out);
88 : #endif
89 :
90 : //todo fix project for iOS
91 : #ifdef GPAC_CONFIG_IOS
92 : //these do not compile with xcode 4.2
93 : // LOAD_PLUGIN(ios_cam);
94 : // LOAD_PLUGIN(ios_mpegv);
95 : #endif
96 :
97 : #endif //GPAC_STATIC_MODULES
98 :
99 : #undef LOAD_PLUGIN
100 :
101 : }
102 : #endif //GPAC_MODULE_CUSTOM_LOAD
103 :
104 : GF_ModuleManager *gpac_modules_static = NULL;
105 :
106 : GF_EXPORT
107 1 : GF_Err gf_module_load_static(GF_InterfaceRegister *(*register_module)())
108 : {
109 : GF_InterfaceRegister *pr;
110 : GF_Err rc;
111 1 : if (register_module == NULL)
112 : return GF_OK;
113 :
114 0 : pr = register_module();
115 0 : if (!pr) {
116 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("Failed to statically loaded module\n"));
117 : return GF_NOT_SUPPORTED;
118 : }
119 :
120 0 : rc = gf_list_add(gpac_modules_static->plugin_registry, pr);
121 0 : if (rc != GF_OK) {
122 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("Failed to statically loaded module\n"));
123 : return rc;
124 : }
125 : return GF_OK;
126 : }
127 :
128 : u32 gf_modules_refresh(GF_ModuleManager *pm);
129 :
130 47719 : static void gf_modules_check_load()
131 : {
132 47719 : if (gpac_modules_static->needs_load) {
133 2741 : gpac_modules_static->needs_load = GF_FALSE;
134 : #ifndef GPAC_MODULE_CUSTOM_LOAD
135 : load_all_modules(gpac_modules_static);
136 : #endif
137 2741 : gf_modules_refresh(gpac_modules_static);
138 2741 : GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("Loaded %d modules.\n", gf_modules_count() ));
139 : }
140 47719 : }
141 :
142 :
143 6241 : void gf_modules_refresh_module_directories()
144 : {
145 : char* directories;
146 : char* tmp_dirs;
147 : char * pch;
148 : u32 i;
149 6241 : GF_ModuleManager *pm = gpac_modules_static;
150 6241 : if (!pm) return;
151 :
152 0 : for (i=0; i<pm->num_dirs; i++) {
153 0 : gf_free(pm->dirs[i]);
154 : }
155 6241 : pm->num_dirs = 0;
156 :
157 : //default module directory
158 6241 : directories = (char*)gf_opts_get_key("core", "module-dir");
159 6241 : if (directories) {
160 6241 : pm->dirs[0] = gf_strdup(directories);
161 6241 : pm->num_dirs = 1;
162 : }
163 :
164 : /* User-defined directories*/
165 6241 : directories = (char*)gf_opts_get_key("core", "mod-dirs");
166 6241 : if (! directories) {
167 6241 : if (!pm->num_dirs) {
168 : #ifndef GPAC_CONFIG_IOS
169 0 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Modules directories not found - check the \"module-dir\" key is set in the \"core\" section\n"));
170 : #endif
171 : }
172 : return;
173 : }
174 :
175 : tmp_dirs = directories;
176 0 : pch = strtok (tmp_dirs,";");
177 :
178 0 : while (pch != NULL) {
179 0 : if (pm->num_dirs == MAX_MODULE_DIRS) {
180 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("Reach maximum number of module directories %d.\n", MAX_MODULE_DIRS));
181 : break;
182 : }
183 0 : pm->dirs[pm->num_dirs] = gf_strdup(pch);
184 0 : pm->num_dirs++;
185 0 : pch = strtok (NULL, ";");
186 : }
187 : }
188 :
189 :
190 : /*!
191 : \brief module manager construtcor
192 : *
193 : *Constructs a module manager object.
194 : \param directory absolute path to the directory where the manager shall look for modules
195 : \param cfgFile GPAC configuration file handle. If this is NULL, the modules won't be able to share the configuration
196 : *file with the rest of the GPAC framework.
197 : \return the module manager object
198 : */
199 6241 : void gf_modules_new(GF_Config *config)
200 : {
201 : const char *opt;
202 6241 : if (!config) return;
203 6241 : if (gpac_modules_static) return;
204 :
205 : /* Try to resolve directory from config file */
206 6241 : GF_SAFEALLOC(gpac_modules_static, GF_ModuleManager);
207 6241 : if (!gpac_modules_static) return;
208 6241 : gpac_modules_static->cfg = config;
209 6241 : gpac_modules_static->mutex = gf_mx_new("Module Manager");
210 6241 : gf_modules_refresh_module_directories();
211 :
212 : /* Initialize module list */
213 6241 : gpac_modules_static->plug_list = gf_list_new();
214 6241 : if (!gpac_modules_static->plug_list) {
215 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("OUT OF MEMORY, cannot create list of modules !!!\n"));
216 0 : gf_free(gpac_modules_static);
217 0 : gpac_modules_static = NULL;
218 0 : return;
219 : }
220 6241 : gpac_modules_static->plugin_registry = gf_list_new();
221 6241 : if (!gpac_modules_static->plugin_registry) {
222 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("OUT OF MEMORY, cannot create list of static module registers !!!\n"));
223 0 : gf_list_del(gpac_modules_static->plug_list);
224 0 : gf_free(gpac_modules_static);
225 0 : gpac_modules_static = NULL;
226 0 : return;
227 : }
228 :
229 6241 : gpac_modules_static->no_unload = !gf_opts_get_bool("core", "mod-reload");
230 :
231 6241 : opt = gf_opts_get_key("core", "version");
232 6241 : if (!opt || strcmp(opt, gf_gpac_version())) {
233 6211 : gf_cfg_del_section(config, "PluginsCache");
234 6211 : gf_opts_set_key("core", "version", gf_gpac_version());
235 : }
236 :
237 6241 : gpac_modules_static->needs_load = GF_TRUE;
238 : }
239 :
240 :
241 0 : void gf_module_reload_dirs()
242 : {
243 0 : if (!gpac_modules_static) return;
244 0 : gf_modules_refresh_module_directories();
245 0 : gpac_modules_static->needs_load = GF_TRUE;
246 : }
247 :
248 :
249 : /*!
250 : \brief module manager destructor
251 : *
252 : *Destroys the module manager
253 : \param pm the module manager
254 : */
255 6240 : void gf_modules_del()
256 : {
257 : u32 i;
258 6240 : GF_ModuleManager *pm = gpac_modules_static;
259 6240 : if (!pm) return;
260 :
261 6240 : gpac_modules_static = NULL;
262 :
263 : /*unload all modules*/
264 31660 : while (gf_list_count(pm->plug_list)) {
265 19180 : ModuleInstance *inst = (ModuleInstance *) gf_list_get(pm->plug_list, 0);
266 19180 : gf_modules_free_module(inst);
267 19180 : gf_list_rem(pm->plug_list, 0);
268 : }
269 6240 : gf_list_del(pm->plug_list);
270 :
271 : /* Delete module directories*/
272 12480 : for (i = 0; i < pm->num_dirs; i++) {
273 6240 : gf_free((void*)pm->dirs[i]);
274 : }
275 :
276 : /*remove all static modules registry*/
277 6240 : while (gf_list_count(pm->plugin_registry)) {
278 0 : GF_InterfaceRegister *reg = (GF_InterfaceRegister *) gf_list_get(pm->plugin_registry, 0);
279 0 : gf_free(reg);
280 0 : gf_list_rem(pm->plugin_registry, 0);
281 : }
282 :
283 6240 : if (pm->plugin_registry) gf_list_del(pm->plugin_registry);
284 6240 : gf_mx_del(pm->mutex);
285 6240 : gf_free(pm);
286 : }
287 :
288 19187 : Bool gf_module_is_loaded(GF_ModuleManager *pm, char *filename)
289 : {
290 19187 : u32 i = 0;
291 : ModuleInstance *inst;
292 95935 : while ( (inst = (ModuleInstance *) gf_list_enum(pm->plug_list, &i) ) ) {
293 57561 : if (!strcmp(inst->name, filename)) return GF_TRUE;
294 : }
295 : return GF_FALSE;
296 : }
297 :
298 : GF_EXPORT
299 12582 : u32 gf_modules_count()
300 : {
301 12582 : if (!gpac_modules_static) return 0;
302 12582 : gf_modules_check_load();
303 12582 : return gf_list_count(gpac_modules_static->plug_list);
304 : }
305 :
306 :
307 : GF_EXPORT
308 14154 : GF_BaseInterface *gf_modules_load(u32 whichplug, u32 InterfaceFamily)
309 : {
310 : const char *opt;
311 : char szKey[32];
312 : ModuleInstance *inst;
313 : GF_BaseInterface *ifce;
314 14154 : GF_ModuleManager *pm = gpac_modules_static;
315 :
316 14154 : if (!pm) {
317 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] gf_modules_load() : No Module Manager set\n"));
318 : return NULL;
319 : }
320 :
321 14154 : gf_mx_p(pm->mutex);
322 :
323 14154 : gf_modules_check_load();
324 :
325 14154 : inst = (ModuleInstance *) gf_list_get(pm->plug_list, whichplug);
326 14154 : if (!inst) {
327 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] gf_modules_load() : no module %d exist.\n", whichplug));
328 0 : gf_mx_v(pm->mutex);
329 0 : return NULL;
330 : }
331 14154 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Load interface...%s\n", inst->name));
332 : /*look in cache*/
333 14154 : if (!pm->cfg) {
334 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] No pm->cfg has been set !!!\n"));
335 0 : gf_mx_v(pm->mutex);
336 0 : return NULL;
337 : }
338 14154 : opt = gf_cfg_get_key(pm->cfg, "PluginsCache", inst->name);
339 14154 : if (opt) {
340 9626 : const char * ifce_str = gf_4cc_to_str(InterfaceFamily);
341 9626 : snprintf(szKey, 32, "%s:yes", ifce_str ? ifce_str : "(null)");
342 9626 : if (!strstr(opt, szKey)) {
343 8093 : gf_mx_v(pm->mutex);
344 8093 : return NULL;
345 : }
346 : }
347 6061 : if (!gf_modules_load_library(inst)) {
348 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Cannot load library %s\n", inst->name));
349 0 : gf_cfg_set_key(pm->cfg, "PluginsCache", inst->name, "invalid");
350 0 : gf_mx_v(pm->mutex);
351 0 : return NULL;
352 : }
353 6061 : if (!inst->query_func) {
354 0 : if (!inst->filterreg_func) {
355 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Library %s missing GPAC export symbols\n", inst->name));
356 0 : gf_cfg_set_key(pm->cfg, "PluginsCache", inst->name, "invalid");
357 : }
358 : goto err_exit;
359 : }
360 :
361 : /*build cache*/
362 6061 : if (!opt) {
363 : u32 i;
364 : const int maxKeySize = 32;
365 : Bool found = GF_FALSE;
366 : char *key;
367 4528 : const u32 *si = inst->query_func();
368 4528 : if (!si) {
369 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("[Core] GPAC module %s has no supported interfaces - disabling\n", inst->name));
370 0 : gf_cfg_set_key(pm->cfg, "PluginsCache", inst->name, "invalid");
371 0 : goto err_exit;
372 : }
373 : i=0;
374 5176 : while (si[i]) i++;
375 :
376 4528 : key = (char*)gf_malloc(sizeof(char) * maxKeySize * i);
377 4528 : key[0] = 0;
378 : i=0;
379 14232 : while (si[i]) {
380 5176 : snprintf(szKey, maxKeySize, "%s:yes ", gf_4cc_to_str(si[i]));
381 : strcat(key, szKey);
382 5176 : if (InterfaceFamily==si[i]) found = GF_TRUE;
383 5176 : i++;
384 : }
385 4528 : strcat(key, inst->filterreg_func ? "GFR1:yes" : "GFR1:no");
386 :
387 4528 : gf_cfg_set_key(pm->cfg, "PluginsCache", inst->name, key);
388 4528 : gf_free(key);
389 4528 : if (!found) goto err_exit;
390 : }
391 :
392 3286 : if (!inst->query_func || !inst->query_func(InterfaceFamily) ) goto err_exit;
393 1643 : ifce = (GF_BaseInterface *) inst->load_func(InterfaceFamily);
394 : /*sanity check*/
395 1643 : if (!ifce) goto err_exit;
396 1643 : if (!ifce->module_name || (ifce->InterfaceType != InterfaceFamily)) {
397 0 : inst->destroy_func(ifce);
398 0 : goto err_exit;
399 : }
400 1643 : gf_list_add(inst->interfaces, ifce);
401 : /*keep track of parent*/
402 1643 : ifce->HPLUG = inst;
403 1643 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Load interface %s DONE.\n", inst->name));
404 1643 : gf_mx_v(pm->mutex);
405 1643 : return ifce;
406 :
407 8836 : err_exit:
408 4418 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Load interface %s exit label, freing library...\n", inst->name));
409 4418 : gf_modules_unload_library(inst);
410 4418 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Load interface %s EXIT.\n", inst->name));
411 4418 : gf_mx_v(pm->mutex);
412 4418 : return NULL;
413 : }
414 :
415 20139 : void *gf_modules_load_filter(u32 whichplug, void *fsess)
416 : {
417 : const char *opt;
418 : ModuleInstance *inst;
419 : void *freg = NULL;
420 20139 : GF_ModuleManager *pm = gpac_modules_static;
421 20139 : if (!pm) return NULL;
422 20139 : gf_modules_check_load();
423 :
424 20139 : inst = (ModuleInstance *) gf_list_get(pm->plug_list, whichplug);
425 20139 : if (!inst) {
426 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] gf_modules_load() : no module %d exist.\n", whichplug));
427 : return NULL;
428 : }
429 20139 : if (strncmp(inst->name, "gf_", 3))
430 : return NULL;
431 0 : opt = gf_cfg_get_key(pm->cfg, "PluginsCache", inst->name);
432 0 : if (opt) {
433 0 : if (!strcmp(opt, "invalid")) return NULL;
434 0 : if (!strstr(opt, "GFR1:yes")) return NULL;
435 : }
436 0 : if (!gf_modules_load_library(inst)) {
437 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Cannot load library %s\n", inst->name));
438 0 : gf_cfg_set_key(pm->cfg, "PluginsCache", inst->name, "invalid");
439 0 : return NULL;
440 : }
441 : freg = NULL;
442 0 : if (inst->filterreg_func) {
443 0 : freg = inst->filterreg_func(fsess);
444 : }
445 0 : if (!freg) {
446 0 : gf_modules_unload_library(inst);
447 : }
448 : return freg;
449 : }
450 :
451 : GF_EXPORT
452 844 : GF_BaseInterface *gf_modules_load_by_name(const char *plug_name, u32 InterfaceFamily)
453 : {
454 : const char *file_name;
455 : u32 i, count;
456 : GF_BaseInterface *ifce;
457 844 : GF_ModuleManager *pm = gpac_modules_static;
458 844 : if (!pm || !plug_name || !pm->plug_list || !pm->cfg) {
459 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] gf_modules_load_by_name has bad parameters pm=%p, plug_name=%s.\n", pm, plug_name));
460 : return NULL;
461 : }
462 :
463 844 : gf_modules_check_load();
464 :
465 844 : count = gf_list_count(pm->plug_list);
466 : /*look for cache entry*/
467 844 : file_name = gf_cfg_get_key(pm->cfg, "PluginsCache", plug_name);
468 :
469 844 : if (file_name) {
470 :
471 238 : for (i=0; i<count; i++) {
472 238 : ModuleInstance *inst = (ModuleInstance *) gf_list_get(pm->plug_list, i);
473 238 : if (!strcmp(inst->name, file_name)) {
474 0 : ifce = gf_modules_load(i, InterfaceFamily);
475 0 : if (ifce) return ifce;
476 : }
477 : }
478 : }
479 844 : GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("[Core] Plugin %s of type %d not found in cache, searching for it...\n", plug_name, InterfaceFamily));
480 4867 : for (i=0; i<count; i++) {
481 : const char *mod_filename;
482 5684 : ifce = gf_modules_load(i, InterfaceFamily);
483 5684 : if (!ifce) continue;
484 1038 : if (ifce->module_name && !strnicmp(ifce->module_name, plug_name, MIN(strlen(ifce->module_name), strlen(plug_name)) )) {
485 : /*update cache entry*/
486 805 : gf_cfg_set_key(pm->cfg, "PluginsCache", plug_name, ((ModuleInstance*)ifce->HPLUG)->name);
487 805 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Added plugin cache %s for %s\n", plug_name, ((ModuleInstance*)ifce->HPLUG)->name));
488 : return ifce;
489 : }
490 : /*check direct addressing by dynamic lib name*/
491 233 : mod_filename = gf_module_get_file_name(ifce);
492 233 : if (mod_filename && strstr(mod_filename, plug_name)) {
493 : return ifce;
494 : }
495 221 : gf_modules_close_interface(ifce);
496 : }
497 27 : GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("[Core] Plugin %s not found in %d modules.\n", plug_name, count));
498 : return NULL;
499 : }
500 :
501 : GF_EXPORT
502 2238 : GF_Err gf_modules_close_interface(GF_BaseInterface *ifce)
503 : {
504 : ModuleInstance *par;
505 : s32 i;
506 2238 : if (!ifce) return GF_BAD_PARAM;
507 2238 : par = (ModuleInstance *) ifce->HPLUG;
508 :
509 2238 : if (!par || !ifce->InterfaceType) return GF_BAD_PARAM;
510 :
511 1640 : i = gf_list_find(par->plugman->plug_list, par);
512 1640 : if (i<0) return GF_BAD_PARAM;
513 :
514 1640 : i = gf_list_find(par->interfaces, ifce);
515 1640 : if (i<0) return GF_BAD_PARAM;
516 1640 : gf_list_rem(par->interfaces, (u32) i);
517 1640 : par->destroy_func(ifce);
518 1640 : gf_modules_unload_library(par);
519 : //GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] interface %s unloaded\n", ifce->module_name));
520 1640 : return GF_OK;
521 : }
522 :
523 : GF_EXPORT
524 21 : const char *gf_modules_get_file_name(u32 i)
525 : {
526 21 : ModuleInstance *inst = (ModuleInstance *) gf_list_get(gpac_modules_static->plug_list, i);
527 21 : if (!inst) return NULL;
528 21 : return inst->name;
529 : }
530 :
531 : GF_EXPORT
532 233 : const char *gf_module_get_file_name(GF_BaseInterface *ifce)
533 : {
534 233 : ModuleInstance *inst = (ModuleInstance *) ifce->HPLUG;
535 233 : if (!inst) return NULL;
536 233 : return inst->name;
537 : }
538 :
539 : #include <gpac/modules/video_out.h>
540 : #include <gpac/modules/audio_out.h>
541 : #include <gpac/modules/font.h>
542 809 : static Bool module_check_ifce(GF_BaseInterface *ifce, u32 ifce_type)
543 : {
544 809 : switch (ifce_type) {
545 158 : case GF_VIDEO_OUTPUT_INTERFACE:
546 : {
547 : GF_VideoOutput *vout = (GF_VideoOutput *) ifce;
548 158 : if (!vout || !vout->Flush || !vout->Setup) return GF_FALSE;
549 158 : return GF_TRUE;
550 : }
551 10 : case GF_AUDIO_OUTPUT_INTERFACE:
552 : {
553 : GF_AudioOutput *aout = (GF_AudioOutput *) ifce;
554 10 : if (!aout || !aout->Configure || !aout->Setup) return GF_FALSE;
555 : //no more support for raw out, deprecated
556 10 : if (!stricmp(ifce->module_name, "Raw Audio Output")) return GF_FALSE;
557 : /*check that's a valid audio mode*/
558 10 : if ((aout->SelfThreaded && aout->SetPriority) || aout->WriteAudio)
559 : return GF_TRUE;
560 0 : return GF_FALSE;
561 : }
562 :
563 : default:
564 : return GF_TRUE;
565 : }
566 : }
567 :
568 :
569 809 : GF_BaseInterface *gf_module_load(u32 ifce_type, const char *name)
570 : {
571 : GF_BaseInterface *ifce = NULL;
572 809 : if (name) {
573 135 : ifce = gf_modules_load_by_name(name, ifce_type);
574 135 : if (!module_check_ifce(ifce, ifce_type)) {
575 0 : gf_modules_close_interface(ifce);
576 : ifce = NULL;
577 : }
578 : }
579 : /*get a preferred output*/
580 135 : if (!ifce) {
581 : const char *sOpt;
582 674 : switch (ifce_type) {
583 26 : case GF_VIDEO_OUTPUT_INTERFACE:
584 26 : sOpt = gf_opts_get_key("core", "video-output");
585 26 : break;
586 7 : case GF_AUDIO_OUTPUT_INTERFACE:
587 7 : sOpt = gf_opts_get_key("core", "audio-output");
588 7 : break;
589 641 : case GF_FONT_READER_INTERFACE:
590 641 : sOpt = gf_opts_get_key("core", "font-reader");
591 641 : break;
592 : default:
593 : sOpt = NULL;
594 : }
595 674 : if (sOpt) {
596 674 : ifce = gf_modules_load_by_name(sOpt, ifce_type);
597 674 : if (!module_check_ifce(ifce, ifce_type)) {
598 0 : gf_modules_close_interface(ifce);
599 : ifce = NULL;
600 : }
601 : }
602 : }
603 809 : if (!ifce) {
604 0 : u32 i, count = gf_modules_count();
605 0 : for (i=0; i<count; i++) {
606 0 : ifce = gf_modules_load(i, ifce_type);
607 0 : if (!ifce) continue;
608 :
609 0 : if (!module_check_ifce(ifce, ifce_type)) {
610 0 : gf_modules_close_interface(ifce);
611 : ifce = NULL;
612 0 : continue;
613 : }
614 : return ifce;
615 : }
616 : }
617 : return ifce;
618 : }
|