[rtmpdump] Proposal: dynamically loadable plugins
Antti Ajanki
antti.ajanki at iki.fi
Sun Jan 8 18:01:58 CET 2012
Hi,
I'm designing a plugin interface for librtmp for extending the
functionality through dynamically loadable libraries. For example, a
custom CDN authentication could be implemented as a plugin. Would
something like this be accepted into librtmp? I'm designing this
according to the needs of one particular CDN (the Finnish Yle Areena
website) but trying to make the interface general. I'm asking for
feedback on how to make the interface generally useful.
I propose that plugins register new URL options (similar to the ones
that RTMP_SetOpt() currently handles) and hooks that will be called if
the registered options are present in the URL. The plugin will need to
be explicitly activated by appending the correct URL option (this way
one misbehaving plugin won't break all RTMP downloads). If none of the
registered options are present, none of plugin's hooks will be called.
A plugin has following hooks:
void *create(RTMP *r) hook will the first hook to be called if a
registered URL option is present. This will be called only once for each
plugin even if there are multiple matching URL options. The return value
is a pointer to plugin's private data. It will be passed to other hooks
but librtmp won't use it otherwise. This function is meant for
allocating plugin's private data structures and setting callbacks (using
RTMP_AttachCallback(), see my previous mail) that implement the
authetication or whatever work the plugin is meant to do.
void parseOption(const AVal *name, const AVal *val, void *ctx) hook will
be called for each URL option, which the plugin has registered and is
present in the URL. The last parameter is the value returned by the
create hook. This function processes the option values and setups callbacks.
void delete(RTMP *r, void *ctx) hook will be called by RTMP_Free(). The
last parameter is the value returned by the create hook. This should
free the memory allocated by create and parseOption hooks.
To make this more concrete, a plugin is a shared object that exposes the
following entry point:
const RTMP_Plugin *rtmp_init_plugin();
This returns a pointer to a struct containing the hooks and other
information about the plugin:
typedef struct RTMP_Plugin
{
uint32_t requiredAPIVersion;
const char *name;
const char *version;
const char *author;
const char *homepage;
RTMPPluginOption *options;
void *(*create)(RTMP *r);
void (*delete)(RTMP *r, void *ctx);
} RTMP_Plugin;
requiredAPIVersion is the plugin API version (librtmp soname) for which
this plugin is compiled for. If the the librtmp instance, which is
trying to load this plugin, has different API version the plugin will
not be loaded.
name, version, author and homepage are strings that will be shown in the
--help message.
create and delete are the allocation and deallocation hooks as described
above.
options is an array of URL options that this plugin recognizes. The last
item must be { 0 }. RTMPPluginOption is the following struct:
typedef struct RTMPPluginOption {
const char *name; /* Name of the option in the SetupURL string */
const char *type; /* Type name to be shown in the help screen */
const char *usage; /* A short description in the help screen */
void (*parseOption)(const AVal *name, const AVal *val, void *ctx);
/* Function that will be called if the SetupURL string contains
* option called name. ctx is the user data pointer returned by
* the create hook. */
} RTMPPluginOption;
librtmp will scan for plugins in ~/.librtmp/plugins and in
$(LIBDIR)/librtmp/plugins when the first RTMP struct is allocated.
RTMP_SetupURL() will loop through all options in the input URL and call
the corresponding hooks, if one of the loaded plugins has registered a
handler for that option.
I'm hoping to be able to post a prototype implementation soon. Any
comments are welcome even before that.
Antti
More information about the rtmpdump
mailing list