Re: [GnomeMeeting-devel-list] [PATCHES+CODE] PVideoInputManager support in pwlib+gm
- From: PUYDT Julien <julien puydt laposte net>
- To: GnomeMeeting Devel Liste <gnomemeeting-devel-list gnome org>
- Subject: Re: [GnomeMeeting-devel-list] [PATCHES+CODE] PVideoInputManager support in pwlib+gm
- Date: 31 Jul 2003 22:30:29 +0200
Le jeu 31/07/2003 à 17:27, PUYDT Julien a écrit :
> * vidin_manager_dlopen.cxx
new version:
* beautified the sources a little;
* worked on the third FIXME: now the full list of plugins is scanned to
find if any of them may be of use (untested yet, since it is a "CLI
feature", that I don't know gm can use);
> * pwlib.patch
unchanged
> * gm.patch
unchanged
Snark
// system includes
#include <dlfcn.h>
// PWLib includes
#include <ptlib.h>
#include <ptlib/videoio.h>
#include <ptlib/vconvert.h>
#include <ptlib/pdirect.h>
struct video_plugin {
const char *name;
void *handle;
PVideoInputDevice *(*Create)(void);
PStringList (*DeviceNames)(void);
struct video_plugin *next;
};
static struct video_plugin *plugins_list;
PVideoInputManager::PVideoInputManager()
{
PTRACE(3, "PVideoInputManager::PVideoInputManager called");
if(plugins_list == NULL)
LoadAllPlugins();
}
PVideoInputManager::~PVideoInputManager()
{
// well, you're not really supposed to create one anyway...
}
void
PVideoInputManager::LoadAllPlugins()
{
PTRACE(3, "Loading plugins...");
LoadPluginDirectory("/usr/lib/pwlib/video");
}
void
PVideoInputManager::LoadPluginDirectory(PDirectory plugdir)
{
PTRACE(4, "Considering loading plugins in " << plugdir);
if(!plugdir.Open())
{
PTRACE(4, "the dir isn't accessible");
return; // no love, no hope
}
do
{
(void)LoadPlugin(plugdir+plugdir.GetEntryName());
// we don't really care if it worked...
}
while(plugdir.Next());
}
BOOL
PVideoInputManager::LoadPlugin(PString filename)
{
void *handle = NULL;
struct video_plugin *plugin = NULL;
plugin = (struct video_plugin *)malloc(sizeof(struct video_plugin));
if(plugin == NULL)
{
PTRACE(1, "PVideoInputManager::LoadPlugin: ENOMEM");
return FALSE;
}
PTRACE(5, "PVideoInputManager::LoadPlugin: " << filename);
// first, we try to get a handle on the plugin
handle=dlopen(filename, RTLD_LAZY);
if(handle == NULL)
{
PTRACE(3, "PVideoInputManager::LoadPlugin: dlerror=" << dlerror());
free(plugin);
return FALSE;
}
plugin->handle = handle;
// second, we try to get its name
char *(*getname)(void);
getname = (char *(*)())dlsym(handle, "plugin_getname");
if(getname == NULL)
{
PTRACE(3, "PVideoInputManager::LoadPlugin: dlerror=" << dlerror());
goto wrong;
}
plugin->name = (*getname)();
// third, we try to get its creator
PVideoInputDevice *(*Create)();
Create = (PVideoInputDevice *(*)(void))dlsym(handle,"plugin_create");
if(Create == NULL)
{
PTRACE(3, "PVideoInputManager::LoadPlugin: dlerror=" << dlerror());
goto wrong;
}
plugin->Create = Create;
// fourth, we try to get its devices lister
PStringList (*DeviceNames)();
DeviceNames = (PStringList (*)(void))dlsym(handle, "plugin_getdevices");
if(DeviceNames == NULL)
{
PTRACE(3, "PVideoInputManager::LoadPlugin: dlerror=" << dlerror());
goto wrong;
}
plugin->DeviceNames = DeviceNames;
// finally, since we got all we wanted, we just add it to the list!
plugin->next = plugins_list;
plugins_list = plugin;
PTRACE(5, "PVideoInputManager::LoadPlugin: succeeded");
return TRUE;
wrong:
free(plugin);
(void)dlclose(handle);
return FALSE;
}
PVideoInputDevice*
PVideoInputManager::GetDevice(PString name)
{
for(struct video_plugin *ptr=plugins_list;
ptr != NULL;
ptr = ptr->next)
{
if(strcmp(name, ptr->name) == 0)
return ptr->Create();
}
return NULL;
}
PVideoInputDevice*
PVideoInputManager::GetOpenedDevice(PString devName, BOOL flag)
{
char driver[11]; // FIXME! Only ten chars for the driver name...
if(plugins_list == NULL)
LoadAllPlugins();
if(sscanf(devName, "%s", &driver) == 1)
{ // looks like a nice devName
PString filename = devName.Right(strlen(devName)-strlen(driver)-1);
// FIXME! this computation is awful!
PVideoInputDevice *dev = GetDevice(driver);
if(dev != NULL && dev->Open(filename, flag))
return dev;
if(dev != NULL)
delete dev;
return NULL;
}
else
{ // doesn't look like a nice devName
// (that can be a user on CLI, who wants us to open /dev/video3.14)
// FIXME: there is a nicer solution to implement that,
// but my pattern-matching abilities are quite small,
// as the previous fixme must have proven: search through the list of
// devices names we get from GetInputDeviceNames, and only ask to those
// drivers that claimed they could handle devName.
for(struct video_plugin *ptr=plugins_list;
ptr != NULL;
ptr = ptr->next)
{
PVideoInputDevice *dev=ptr->Create();
if(dev != NULL && dev->Open(devName, flag))
return dev;
if(dev != NULL)
delete dev;
}
return NULL;
}
}
PStringList
PVideoInputManager::GetInputDeviceNames()
{
PTRACE(3, "PVideoInputManager::GetInputDeviceNames called");
if(plugins_list == NULL)
LoadAllPlugins();
// we get through all the plugin lists, and add the name as a prefix,
// to be able to track down which takes care of what
PStringList Result;
for(struct video_plugin *ptr=plugins_list;
ptr != NULL;
ptr=ptr->next)
{
PStringList tmplist = ptr->DeviceNames();
for (PINDEX i = 0; i < tmplist.GetSize(); i++)
{
Result.AppendString((PString)ptr->name+" "+tmplist[i]);
}
}
return Result;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]