[rtmpdump] Proposal: dynamically loadable plugins

Antti Ajanki antti.ajanki at iki.fi
Sun Jan 8 18:01:58 CET 2012


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 

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.


More information about the rtmpdump mailing list