LCOV - code coverage report
Current view: top level - utils - module.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 183 260 70.4 %
Date: 2021-04-29 23:48:07 Functions: 15 16 93.8 %

          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             : }

Generated by: LCOV version 1.13