/*
* GPAC - Multimedia Framework C SDK
*
* Authors: Jean Le Feuvre
* Copyright (c) Telecom ParisTech 2000-2012
* All rights reserved
*
* This file is part of GPAC / common tools sub-project
*
* GPAC is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* GPAC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef _GF_MODULE_H_
#define _GF_MODULE_H_
#ifdef __cplusplus
extern "C" {
#endif
/*!
* \file <gpac/module.h>
* \brief plugable dynamic module.
*/
/*!
* \ingroup mods_grp
* \brief Plugable Dynamic Modules
*
*This section documents the plugable module functions of the GPAC framework.
*A module is a dynamic/shared library providing one or several interfaces to the GPAC framework.
*A module cannot provide several interfaces of the same type. Each module must export the following functions:
\code
* u32 *QueryInterfaces(u32 interface_type);
\endcode
* This function is used to query supported interfaces. It returns a zero-terminated array of supported interface types.\n
\code
GF_BaseInterface *LoadInterface(u32 interface_type);
\endcode
* This function is used to load an interface. It returns the interface object, NULL if error.\n
\code
void ShutdownInterface(GF_BaseInterface *interface);
\endcode
*This function is used to destroy an interface.\n\n
*Each interface must begin with the interface macro in order to be type-casted to the base interface structure.
\code
struct {
GF_DECL_MODULE_INTERFACE
extensions;
};
\endcode
* @{
*/
#include <gpac/config_file.h>
typedef struct __tag_mod_man GF_ModuleManager;
/*!
*\brief common module interface
*\hideinitializer
*
*This is the module interface declaration macro. It must be placed first in an interface structure declaration.
*/
#define GF_DECL_MODULE_INTERFACE \
u32 InterfaceType; \
const char *module_name; \
const char *author_name; \
void *HPLUG; \
/*!
*\brief Base Interface
*
*This structure represent a base interface, e.g. the minimal interface declaration without functionalities. Each interface is
*type-casted to this structure and shall always be checked against its interface type. API Versioning is taken care of in the
*interface type itsel, changing at each modification of the interface API
*/
typedef struct
{
GF_DECL_MODULE_INTERFACE
} GF_BaseInterface;
/*!
*\brief module interface registration
*\hideinitializer
*
*This is the module interface registration macro. A module must call this macro whenever creating a new interface.
*- \e _ifce: interface being registered
*- \e _ifce_type: the four character code defining the interface type.
*- \e _ifce_name: a printable string giving the interface name (const char *).
*- \e _ifce_author: a printable string giving the author name (const char *).
*\n
*This is a sample GPAC codec interface declaration:
\code
GF_BaseInterface *MyDecoderInterfaceLoad() {
GF_MediaDecoder *ifce;
GF_SAFEALLOC(ifce, GF_MediaDecoder);
GF_REGISTER_MODULE_INTERFACE(ifce, GF_MEDIA_DECODER_INTERFACE, "Sample Decoder", "The Author")
//follows any initialization private to the decoder
return (GF_BaseInterface *)ifce;
}
\endcode
*/
#define GF_REGISTER_MODULE_INTERFACE(_ifce, _ifce_type, _ifce_name, _ifce_author) \
_ifce->InterfaceType = _ifce_type; \
_ifce->module_name = _ifce_name ? _ifce_name : "unknown"; \
_ifce->author_name = _ifce_author ? _ifce_author : "gpac distribution"; \
/*!
*\brief module interface function export. Modules that can be compiled in libgpac rather than in sharde libraries shall use this macro to declare the 3 exported functions
*\hideinitializer
*
*/
#ifdef GPAC_STATIC_MODULES
#define GPAC_MODULE_EXPORT static
#else
#define GPAC_MODULE_EXPORT GF_EXPORT
#endif
/*!
*\brief Interface Registry
*
*This structure represent a base interface loader, when not using dynamic / shared libraries
*/
typedef struct
{
const char *name;
const u32 *(*QueryInterfaces) ();
GF_BaseInterface * (*LoadInterface) (u32 InterfaceType);
void (*ShutdownInterface) (GF_BaseInterface *interface_obj);
} GF_InterfaceRegister;
/*!
*\brief module interface function export. Modules that can be compiled in libgpac rather than in sharde libraries shall use this macro to declare the 3 exported functions
*\hideinitializer
*
*/
#ifdef GPAC_STATIC_MODULES
#define GPAC_MODULE_STATIC_DECLARATION(__name) \
GF_InterfaceRegister *gf_register_module_##__name() { \
GF_InterfaceRegister *reg; \
GF_SAFEALLOC(reg, GF_InterfaceRegister); \
if (!reg) return NULL;\
reg->name = "gsm_" #__name; \
reg->QueryInterfaces = QueryInterfaces; \
reg->LoadInterface = LoadInterface; \
reg->ShutdownInterface = ShutdownInterface; \
return reg;\
} \
#else
#define GPAC_MODULE_STATIC_DECLARATION(__name)
#endif
/*!
*\brief module manager construtcor
*
*Constructs a module manager object.
*\param directory absolute path to the directory where the manager shall look for modules
*\param cfgFile GPAC configuration file handle. If this is NULL, the modules won't be able to share the configuration
*file with the rest of the GPAC framework.
*\return the module manager object
*/
GF_ModuleManager *gf_modules_new(const char *directory, GF_Config *cfgFile);
/*!
*\brief module manager destructor
*
*Destroys the module manager
*\param pm the module manager
*/
void gf_modules_del(GF_ModuleManager *pm);
/*!
*\brief load a static module given its interface function
*
*\param pm the module manager
*\param register_module the register interface function
*/
GF_Err gf_module_load_static(GF_ModuleManager *pm, GF_InterfaceRegister *(*register_module)());
/*!
*\brief declare a module for loading
*
* When using GPAC as a static library, if GPAC_MODULE_CUSTOM_LOAD is
* defined, this macro can be used with GF_MODULE_STATIC_DECLARE() and
* gf_module_refresh() to load individual modules.
*
* It's first needed to call GF_MODULE_STATIC_DECLARE() with the name
* of the module you need to load outside of any function. This macro
* will declare the prototype of the module registration function so
* it should only be used outside functions.
*
* Then in your GPAC initialization code, you need to call
* GF_MODULE_LOAD_STATIC() with your GPAC module manager and the
* module name.
*
* Finally, you'll need to call gf_modules_refresh() with your module
* manager.
*
* \code
* GF_MODULE_STATIC_DECLARE(aac_in);
* GF_MODULE_STATIC_DECLARE(audio_filter);
* GF_MODULE_STATIC_DECLARE(ffmpeg);
* ...
*
* void prepare() {
* GF_User user;
* ...
* user.modules = gf_modules_new("/data/gpac/modules", user.config);
*
* GF_MODULE_LOAD_STATIC(user.modules, aac_in);
* GF_MODULE_LOAD_STATIC(user.modules, audio_filter);
* GF_MODULE_LOAD_STATIC(user.modules, ffmpeg);
* ...
* gf_modules_refresh(user.modules);
* ...
* }
* \endcode
* \see GF_MODULE_LOAD_STATIC() gf_modules_refresh()
*/
#ifdef __cplusplus
#define GF_MODULE_STATIC_DECLARE(_name) \
extern "C" GF_InterfaceRegister *gf_register_module_##_name()
#else
#define GF_MODULE_STATIC_DECLARE(_name) \
GF_InterfaceRegister *gf_register_module_##_name()
#endif
/*!
*\brief load a static module given its name
*
* Use this function to load a statically compiled
* module. GF_MODULE_STATIC_DECLARE() should be called before and
* gf_modules_refresh() after loading all the needed modules.
*
*\param _pm the module manager
*\param _name the module name
*\see GF_MODULE_STATIC_DECLARE() gf_modules_refresh()
*/
#define GF_MODULE_LOAD_STATIC(_pm, _name) \
gf_module_load_static(_pm,gf_register_module_##_name)
/*!
*\brief refreshes modules
*
*Refreshes all modules in the manager directory and load unloaded ones
*\param pm the module manager
*\return the number of loaded modules
*/
u32 gf_modules_refresh(GF_ModuleManager *pm);
/*!
*\brief get module count
*
*Gets the number of modules found in the manager directory
*\param pm the module manager
*\return the number of loaded modules
*/
u32 gf_modules_get_count(GF_ModuleManager *pm);
/*!
*\brief get all modules directories
*
* Update module manager with all modules directories
*\param pm the module manager
*\param num_dirs the number of module directories
*\return The list of modules directories
*/
const char **gf_modules_get_module_directories(GF_ModuleManager *pm, u32* num_dirs);
/*!
*\brief get module file name
*
*Gets a module shared library file name based on its index
*\param pm the module manager
*\param index the 0-based index of the module to query
*\return the name of the shared library module
*/
const char *gf_modules_get_file_name(GF_ModuleManager *pm, u32 index);
/*!
*\brief get module file name
*
*Gets a module shared library file name based on its index
*\param ifce the module instance to query
*\return the name of the shared library module
*/
const char *gf_module_get_file_name(GF_BaseInterface *ifce);
/*!
*\brief loads an interface
*
*Loads an interface in the desired module.
*\param pm the module manager
*\param index the 0-based index of the module to load the interface from
*\param InterfaceFamily type of the interface to load
*\return the interface object if found and loaded, NULL otherwise.
*/
GF_BaseInterface *gf_modules_load_interface(GF_ModuleManager *pm, u32 index, u32 InterfaceFamily);
/*!
*\brief loads an interface by module name
*
*Loads an interface in the desired module
*\param pm the module manager
*\param mod_name the name of the module (shared library file) or of the interface as declared when registered.
*\param InterfaceFamily type of the interface to load
*\return the interface object if found and loaded, NULL otherwise.
*/
GF_BaseInterface *gf_modules_load_interface_by_name(GF_ModuleManager *pm, const char *mod_name, u32 InterfaceFamily);
/*!
*\brief interface shutdown
*
*Closes an interface
*\param interface_obj the interface to close
*/
GF_Err gf_modules_close_interface(GF_BaseInterface *interface_obj);
/*!
*\brief interface option query
*
*Gets an option from the config file associated with the module manager
*\param interface_obj the interface object used
*\param secName the desired key parent section name
*\param keyName the desired key name
*\return the desired key value if found, NULL otherwise.
*/
const char *gf_modules_get_option(GF_BaseInterface *interface_obj, const char *secName, const char *keyName);
/*!
*\brief interface option update
*
*Sets an option in the config file associated with the module manager
*\param interface_obj the interface object used
*\param secName the desired key parent section name
*\param keyName the desired key name
*\param keyValue the desired key value
*\note this will also create both section and key if they are not found in the configuration file
*/
GF_Err gf_modules_set_option(GF_BaseInterface *interface_obj, const char *secName, const char *keyName, const char *keyValue);
/*!
*\brief get config file
*
*Gets the configuration file for the module instance
*\param ifce the interface object used
*\return handle to the config file
*/
GF_Config *gf_modules_get_config(GF_BaseInterface *ifce);
/*! @} */
#ifdef __cplusplus
}
#endif
#endif /*_GF_MODULE_H_*/