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
participants (1)
-
Antti Ajanki