Note: Modular build is currently supported only for Linux. The process of adding a module is, however, unified across platforms and whether or not building standalone modules.
- Table of contents
- Adding a module to the build system
- Module API
- Registering modules to UltraGrid runtime
- Examples
Easiest way is to add a module object to OBJ variable in Makefile.in. However, this variant is recommended only if module has no additional dependencies and should be linked statically with the binary, if it is not true, it is advisable to create a new target of the module as described below.
Module name is in format ultragrid_<class>_<name>.so
. Names of
categories can be found in file lib_common.cpp
, in struct
library_class_info.
You will need to use a macro ADD_MODULE(name, objs, libs)
defined in
configure.ac to register module to build system:
- name can be an empty string (""). In that case module will be linked only if UltraGrid is built statically (without modules support)
- if you provide name, it should be in format
<class>_<name>
(eg. vidcap_gl), _ultragrid will be appended automatically - second parameter should be a variable containing required objects for the module
- third parameter are libraries that are needed for the module to link with
Individual module have different APIs, these are most commonly described in its corresponding header file (eg. capture_filter.h or video_display.h), documentation for individual APIs should be in corresponding header files. Resulting module has to use that API.
Finally, when module is written, it should be registered with
REGISTER_MODULE
macro from lib_common.h. General syntax is:
REGISTER_MODULE(name, info, class_type, abi_version);
Eg.:
REGISTER_MODULE(blank, &capture_filter_blank, LIBRARY_CLASS_CAPTURE_FILTER, CAPTURE_FILTER_ABI_VERSION);
Parameters are following:
- name of the module (should be the same as
<name>
of the module), not in quotation marks! - info - pointer to structure defining API functions
- class_type is one of member from
enum library_class
defined in lib_common.h - abi_version is a class-specific number specifying ABI version number. It is usually defined in a header file corresponding with the class (eg. video_capture.h)library specific ABI version
This example shows capture filter blank.
Usual parameter check:
BLANK_LIBS=
BLANK_OBJ=
blank=no
define(blank_dep, libswscale)
AC_ARG_ENABLE(blank,
[ --disable-blank disable blank capture filter (default is auto)]
[ Requires: blank_dep],
[blank_req=$enableval],
[blank_req=$build_default]
)
Then pkg-config can check the requirements:
PKG_CHECK_MODULES([BLANK], [blank_dep], FOUND_BLANK_DEP=yes, FOUND_BLANK_DEP=no)
If user didn't have explicitly disabled (req != no
) the module and
dependencies were found, use values from pkg-config:
if test $blank_req != no -a $FOUND_BLANK_DEP = yes
then
CFLAGS="$CFLAGS ${BLANK_CFLAGS}"
CXXFLAGS="$CXXFLAGS ${BLANK_CFLAGS}"
BLANK_OBJ="src/capture_filter/blank.o"
ADD_MODULE("vcapfilter_blank", "$BLANK_OBJ", "$BLANK_LIBS")
blank=yes
fi
Following is not mandatory but useful for debugging:
if test $blank_req = yes -a $blank = no; then
AC_MSG_ERROR([Blank dep not found (libswscale)]);
fi
Also adding blank to the summary at the end of configure.ac is useful for user.
Only showing relevant parts of capture filter API registration.
#include <lib_common.h>
#include <video_capture.h>
static const struct capture_filter_info capture_filter_blank = {
.name = "blank",
.init = init,
.done = done,
.filter = filter,
};
REGISTER_MODULE(blank, &capture_filter_blank, LIBRARY_CLASS_CAPTURE_FILTER, CAPTURE_FILTER_ABI_VERSION);
Another example of registration of the DeckLink video capture in video_capture/decklink.cpp:
static const struct video_capture_info vidcap_decklink_info = {
vidcap_decklink_probe,
vidcap_decklink_init,
vidcap_decklink_done,
vidcap_decklink_grab,
};
REGISTER_MODULE(decklink, &vidcap_decklink_info, LIBRARY_CLASS_VIDEO_CAPTURE, VIDEO_CAPTURE_ABI_VERSION);