You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

443 lines
14 KiB

/*
* tcmodule-core.h -- transcode module system, take two: core components.
* (C) 2005-2010 - Francesco Romani <fromani -at- gmail -dot- com>
*
* This file is part of transcode, a video stream processing tool.
*
* transcode is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* transcode 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* this header file is intended to be included in components
* which want to use the new transcode module system, acting like
* clients respect to a plugin.
*/
#ifndef TCMODULE_CORE_H
#define TCMODULE_CORE_H
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdint.h>
#include "tcmodule-data.h" /* pulls framebuffer.h and transcode.h */
/*
* this structure will hold all data needed to use a module by client code:
* module operations and capabilities (given by module class, so shared
* between all modules) and private data.
*/
typedef struct tcmodule_ *TCModule;
struct tcmodule_ {
const TCModuleClass *klass;
/* pointer to class data shared between all instances */
TCModuleInstance instance;
/* each module has it's private instance data, it's embedded here */
};
/*************************************************************************
* interface helpers, using shortened notation *
*************************************************************************/
#ifdef HAVE_GCC_ATTRIBUTES
__attribute__((unused))
#endif
static int tc_module_configure(TCModule handle,
const char *options, vob_t *vob)
{
return handle->klass->configure(&(handle->instance), options, vob);
}
#ifdef HAVE_GCC_ATTRIBUTES
__attribute__((unused))
#endif
static int tc_module_stop(TCModule handle)
{
return handle->klass->stop(&(handle->instance));
}
#ifdef HAVE_GCC_ATTRIBUTES
__attribute__((unused))
#endif
static int tc_module_inspect(TCModule handle,
const char *param, const char **value)
{
return handle->klass->inspect(&(handle->instance), param, value);
}
#ifdef HAVE_GCC_ATTRIBUTES
__attribute__((unused))
#endif
static int tc_module_encode_video(TCModule handle,
vframe_list_t *inframe,
vframe_list_t *outframe)
{
return handle->klass->encode_video(&(handle->instance),
inframe, outframe);
}
#ifdef HAVE_GCC_ATTRIBUTES
__attribute__((unused))
#endif
static int tc_module_encode_audio(TCModule handle,
aframe_list_t *inframe,
aframe_list_t *outframe)
{
return handle->klass->encode_audio(&(handle->instance),
inframe, outframe);
}
#ifdef HAVE_GCC_ATTRIBUTES
__attribute__((unused))
#endif
static int tc_module_decode_video(TCModule handle,
vframe_list_t *inframe,
vframe_list_t *outframe)
{
return handle->klass->decode_video(&(handle->instance),
inframe, outframe);
}
#ifdef HAVE_GCC_ATTRIBUTES
__attribute__((unused))
#endif
static int tc_module_decode_audio(TCModule handle,
aframe_list_t *inframe,
aframe_list_t *outframe)
{
return handle->klass->decode_audio(&(handle->instance),
inframe, outframe);
}
#ifdef HAVE_GCC_ATTRIBUTES
__attribute__((unused))
#endif
static int tc_module_filter_video(TCModule handle,
vframe_list_t *frame)
{
return handle->klass->filter_video(&(handle->instance), frame);
}
#ifdef HAVE_GCC_ATTRIBUTES
__attribute__((unused))
#endif
static int tc_module_filter_audio(TCModule handle,
aframe_list_t *frame)
{
return handle->klass->filter_audio(&(handle->instance), frame);
}
#ifdef HAVE_GCC_ATTRIBUTES
__attribute__((unused))
#endif
static int tc_module_multiplex(TCModule handle,
vframe_list_t *vframe,
aframe_list_t *aframe)
{
return handle->klass->multiplex(&(handle->instance), vframe, aframe);
}
#ifdef HAVE_GCC_ATTRIBUTES
__attribute__((unused))
#endif
static int tc_module_demultiplex(TCModule handle,
vframe_list_t *vframe,
aframe_list_t *aframe)
{
return handle->klass->demultiplex(&(handle->instance), vframe, aframe);
}
#ifdef HAVE_GCC_ATTRIBUTES
__attribute__((unused))
#endif
static const TCModuleInfo *tc_module_get_info(TCModule handle)
{
return handle->klass->info;
}
#ifdef HAVE_GCC_ATTRIBUTES
__attribute__((unused))
#endif
static int tc_module_match(int codec,
TCModule handle, TCModule other)
{
return tc_module_info_match(codec,
handle->klass->info, other->klass->info);
}
#ifdef HAVE_GCC_ATTRIBUTES
__attribute__((unused))
#endif
static void tc_module_show_info(TCModule handle, int verbose)
{
tc_module_info_log(handle->klass->info, verbose);
}
/* FIXME: that's just ugly. */
#ifdef HAVE_GCC_ATTRIBUTES
__attribute__((unused))
#endif
static void tc_module_pass_extradata(TCModule source, TCModule dest)
{
if (source != NULL && dest != NULL) {
/* soft copy */
dest->instance.extradata = source->instance.extradata;
dest->instance.extradata_size = source->instance.extradata_size;
}
}
/* factory data type. */
typedef struct tcfactory_ *TCFactory;
/*************************************************************************
* factory methods *
*************************************************************************/
/*
* tc_new_module_factory:
* initialize a module factory. This function will acquire all
* needed resources and set all things appropriately to make the
* factory ready for create module instances, loading plugins on
* demand if needed.
*
* Parameters:
* modpath:
* module base directory. The factory will look for
* transcode plugins to load if needed starting from this
* directory.
* Note that this must be a single directory.
* verbose:
* verbosiness level of factory. Control the quantity
* of informative messates to print out.
* Should be one of TC_INFO, TC_DEBUG... value.
*
* Return Value:
* A valid TCFactory if initialization was done
* succesfully, NULL otherwise. In latter case, a informative
* message is sent through tc_log*().
*
* Side effects:
* uses tc_log*() internally.
*
* Preconditions:
* modpath NOT NULL; giving a NULL parameter will cause a
* graceful failure.
*
* Postconditions:
* factory initialized and ready to create TCModules.
*/
TCFactory tc_new_module_factory(const char *modpath, int verbose);
/*
* tc_del_module_factory:
* finalize a module factory. Shutdowns the factory completely,
* cleaning up everything and unloading plugins.
* PLEASE NOTE: this function _CAN_ fail, notably if a plugin
* can't be unloaded cleanly (this usually happens because a plugin
* has still some live instances at finalization time).
* ALWAYS check the return value and take opportune countermeasures.
* At time of writing, a factory can't (and it's unlikely it will
* do) destroy all living instances automatically.
*
* Parameters:
* factory: factory handle to finalize.
*
* Return Value:
* 0 succesfull.
* -1 an error occurred (notified via tc_log*).
*
* Side effects:
* uses tc_log*() internally.
*
* Preconditions:
* given factory was already initialized. Trying to finalize a
* non-initialized factory causes undefined behaviour.
*
* Postconditions:
* all resources acquired by factory are released; no modules are
* loaded or avalaible, nor module instances are still floating around.
*/
int tc_del_module_factory(TCFactory factory);
/*
* tc_new_module:
* using given factory, create a new module instance of the given type,
* belonging to given class, and initialize it with reasonnable
* defaults values.
* This function may load a plugin implicitely to fullfill the request,
* since plugins are loaded on demand of client code.
* The returned instance pointer must be released using
* tc_del_module (see below).
* The returned instance is ready to use with above tc_module_* macros,
* or in any way you like.
*
* PLEASE NOTE: this function automatically invokes module initialization
* method on given module. You should NOT do by yourself.
*
* Parameters:
* factory: use this factory instance to build the new module.
* modclass: class of module requested (filter, encoding,
* demultiplexing...).
* modname: name of module requested.
* media: media type for new module (TC_VIDEO, TC_AUDIO, TC_EXTRA)
*
* Return value:
* NULL: an error occurred, and notified via tc_log_*()
* valid handle to a new module instance otherwise.
*
* Side effects:
* uses tc_log*() internally.
* a plugin can be loaded (except for errors!) implicitely.
*
* Preconditions:
* given factory was already intialized.
*
* Postconditions:
* if succeeded, module ready to use by client code.
*
* Examples:
* if you want to load the "foobar" plugin, belonging to filter class,
* you should use a code like this:
*
* TCModule my_module = tc_new_module("filter", "foobar");
*/
TCModule tc_new_module(TCFactory factory,
const char *modclass, const char *modname, int media);
/*
* tc_del_module:
* destroy a module instance using given factory, unloading corrispondent
* plugin from factory if needed.
* This function release the maximum amount of resources possible
* acquired by a given module; since some resources (originating plugin)
* are shared between all instances, there is possible that some call
* doesn't release all resources. Anyway, si guaranted that all resources
* are released when all instances are destroyed.
*
* PLEASE NOTE: this function automatically invokes module finalization
* method on given module. You should'nt do by yourself.
*
* Parameters:
* factory: a factory handle, the same one used to create the module
* module: module instance to destroy.
*
* Return Value:
* 0 succesfull
* -1 an error occurred (notified via tc_log*).
*
* Side effects:
* uses tc_log*() internally.
* a plugin could be unloaded implicitely.
*
* Preconditions:
* factory already initialized.
* ***GIVEN MODULE WAS CREATED USING GIVEN FACTORY***
* to violate this condition will case an undefined behaviour.
* At time of writing, factory *CANNOT* detect when this condition
* is violated. So be careful.
*
* given module instance was obtained using tc_new_module,
* applying this function to a module instances obtained in a
* different way causes undefined behaviour, most likely a memory
* corruption.
*
* Postconditions:
* resources belonging to instance are released (see above).
*/
int tc_del_module(TCFactory factory, TCModule module);
/*
* tc_plugin_count:
* get the number of loaded plugins in a given factory.
* Used mainly for debug purposes.
*
* Parameters:
* factory: handle to factory to analyze.
*
* Return Value:
* the number of plugins loaded at the moment.
*
* Side effects:
* None
*
* Preconditions:
* Given factory was already initialized.
* To apply this function to an unitialized factory will cause
* an undefine dbehaviour
*
* Postconditions:
* None
*/
int tc_plugin_count(const TCFactory factory);
/*
* tc_module_count:
* get the number of module created and still valid by a given
* factory. Used mainly for debug purposes.
*
* Parameters:
* factory: handle to factory to analyze.
*
* Return Value:
* the number of module created and not yet destroyed at the moment.
*
* Side effects:
* None
*
* Preconditions:
* Given factory was already initialized.
* To apply this function to an unitialized factory will cause
* an undefine dbehaviour
*
* Postconditions:
* None
*/
int tc_instance_count(const TCFactory factory);
/*
* tc_compare_modules:
* compare two module (through it's handler) supposed to be the same
* type (class + name). Used mainly for debug purposes.
*
* This function *MUST* SCREW UP BADLY if internal checks
* are absoultely clean, so assert are used at this moment.
*
* Parameters:
* amod: handle to first module instance.
* bmod: handle to second module instance
*
* Return value:
* -1 totally different modules
* 0 same class (some shared data)
* +1 same module instance: the two handles point to same instance
*
* Side effects:
* client code can be abort()ed.
*
* Preconditions:
* both module handles must refer to valid modules.
*
* Postconditions:
* None
*/
int tc_compare_modules(const TCModule amod, const TCModule bmod);
#endif /* TCMODULE_CORE_H */