[MPlayer-dev-eng] dynamic loaded video filters

D Richard Felker III dalias at aerifal.cx
Sun Aug 18 05:16:12 CEST 2002


On Sat, Aug 17, 2002 at 08:24:58PM -0400, D Richard Felker III wrote:
> I've been considering writing a vf module that dlopen's a library
> containing a video filter, then replaces itself with what it just
> loaded. Source for dynamic loaded vf's would be identical to static
> ones; the dl filter would just look for vf_info_[modulename] and use
> it to bootstrap the module.
> 
> The benefits of this would be that it would allow experimental
> filters, or filters that are useful to just a few people but don't
> actually belong in mplayer itself, to be used without modifying the
> mplayer codebase.
> 
> It should be really simple to implement; I just want to check and make
> sure this is a desirable/acceptable feature to be included in mplayer
> before I bother writing it. Also, naturally it will be excluded if the
> user's system doesn't have a working libdl.

Oh well, I went and wrote it any way, for fun if nothing else. The
file is attached in case anyone wants to try it out and comment. Usage
is simple: -vop dl=name:args loads vf_name.so from the pwd,
LIBDIR/mplayer/plugins, or libdl's normal search path and passes args
to it. To make plugins out of existing mplayer filters, use a command
like:

gcc -shared -o vf_foo.so vf_foo.o

I've tested it with vf_scale and with my vf_halfpack which didn't make
it into mplayer, and both seem to work fine.

One caveat... mplayer needs to be compiled with -rdynamic or the
plugins can't find the symbols they need. I don't know if there's any
better way to handle this. If it's a problem I can make vf_dl so it
can be disabled at compiletime.

Finally, I don't know if this code is quite ready for inclusion in CVS
yet. Some mechanisms to disable it in the absence of libdl need to be
added, and there may be minor portability issues. I'll improve it
soon, but if anyone else feels like going ahead and making the
necessary changes to put it in CVS, feel free.

Rich



-------------- next part --------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>

#include <dlfcn.h>

#include "../config.h"
#include "../mp_msg.h"

#include "img_format.h"
#include "mp_image.h"
#include "vf.h"

struct vf_priv_s {
	void *dlhandle;
};

const char *libpath[] = {
	"./",
	LIBDIR "/mplayer/plugins/",
	"",
	NULL
};

static void uninit(vf_instance_t *vf)
{
	dlclose(vf->priv->dlhandle);
}

static int open(vf_instance_t *vf, char* args)
{
	vf_info_t *dvfi;
	vf_instance_t *dvf;
	void *h;
	char *name, *subargs;
	char *structname, *filename;
	char **path, *pathname;
	int namelen;

	if (!args) return 0;
	name = alloca(strlen(args));
	strcpy(name, args);
	subargs = strchr(name, ':');
	if (subargs) {
		*subargs = 0;
		subargs++;
	} else subargs = "";

	namelen = strlen(name);

	filename = alloca(namelen+7);
	sprintf(filename, "vf_%s.so", name);

	h = NULL;
	for (path = libpath; *path && !h; path++) {
		pathname = alloca(strlen(*path) + namelen + 1);
		strcpy(pathname, *path);
		strcat(pathname, filename);
		h = dlopen(pathname, RTLD_NOW);
	}
	
	if (!h) {
		return 0;
	}

	structname = alloca(strlen(name)+10);
	strcpy(structname, "vf_info_");
	strcat(structname, name);
	dvfi = dlsym(h, structname);

	if (!dvfi) {
		dlclose(h);
		return 0;
	}
	
	dvf = malloc(sizeof(vf_instance_t));
	memset(dvf, 0, sizeof(vf_instance_t));
	dvf->info = dvfi;
	dvf->next = vf->next;
	dvf->config = vf_next_config;
	dvf->control = vf_next_control;
	dvf->query_format = vf_next_query_format;
	dvf->put_image = vf_next_put_image;
	dvf->default_caps = VFCAP_ACCEPT_STRIDE;
	dvf->default_reqs = 0;
	if(dvf->info->open(dvf, subargs) <= 0) {
		free(dvf);
		dlclose(h);
		return 0;
	}

	vf->next = dvf;
	vf->uninit = uninit;
	vf->priv = malloc(sizeof(struct vf_priv_s));
	vf->priv->dlhandle = h;
	
	return 1;
}

vf_info_t vf_info_dl = {
	"dynamic video filter loader",
	"dl",
	"Richard Felker",
	"",
	open
};



More information about the MPlayer-dev-eng mailing list