[GnomeMeeting-devel-list] [PATCHES+CODE] PVideoInputManager support in pwlib+gm



Well, this is some code ; you'll find attached to this mail:
* vidin_manager_dlopen.cxx
* pwlib.patch
* gm.patch

== PWLib ==
* Copy the .cxx in src/ptlib/unix, it is a dlopen implementation of the
class;
* Apply the pwlib.patch; that will add the class' declaration to
include/ptlib/videoio.h, and adjust the src/ptlib/unix/Makefile to
include the .cxx;
* Compile the lib your usual way; the lib you will get will have it's
usual drivers+the manager: at this point, if you use your usual gm, you
shouldn't see any difference!

== GM ==
* Apply the gm.patch patch: it removes the support for the usual
drivers, and puts in the support for the manager;
* Compile the program your usual way; launch it and enjoy: the moving
logo works great! You have no driver for the manager.

You'll find the v4l and avc driver in the next mail; that should make
your brand-new gm+manager more usable (in the mean time, the dancing
logo is still there for your eyes ;-) ).

Snark

PS1: vidin_manager_dlopen.cxx is a name that sucks as long as it is
alone. But if some vidout_manager_dlopen.cxx or vidin_manager_other.cxx
where to appear in the future, then that name will suck less. 

PS2: My hope is that this manager can be used in all unix-like
platforms.

PS3: If you grep for "FIXME" in the code, you'll find how to help me :-)
diff -ur gnomemeeting-cvs-20030730.CVS/src/gnomemeeting.cpp gnomemeeting-cvs-20030730.CVS.patched/src/gnomemeeting.cpp
--- gnomemeeting-cvs-20030730.CVS/src/gnomemeeting.cpp	2003-06-22 19:33:41.000000000 +0200
+++ gnomemeeting-cvs-20030730.CVS.patched/src/gnomemeeting.cpp	2003-07-31 16:45:33.000000000 +0200
@@ -300,13 +300,7 @@
   gnomemeeting_sound_daemons_suspend ();
   gw->audio_player_devices = gnomemeeting_get_audio_player_devices ();
   gw->audio_recorder_devices = gnomemeeting_get_audio_recorder_devices ();
-  gw->video_devices = PVideoInputDevice::GetInputDeviceNames ();
-#ifdef TRY_1394DC
-  gw->video_devices += PVideoInput1394DcDevice::GetInputDeviceNames();
-#endif
-#ifdef TRY_1394AVC
-  gw->video_devices += PVideoInput1394AvcDevice::GetInputDeviceNames();
-#endif
+  gw->video_devices = PVideoInputManager::GetInputDeviceNames ();
   gw->video_devices += PString (_("Picture"));
   gw->audio_mixers = gnomemeeting_get_mixers ();
   gnomemeeting_mixers_mic_select ();
diff -ur gnomemeeting-cvs-20030730.CVS/src/videograbber.cpp gnomemeeting-cvs-20030730.CVS.patched/src/videograbber.cpp
--- gnomemeeting-cvs-20030730.CVS/src/videograbber.cpp	2003-06-14 00:08:10.000000000 +0200
+++ gnomemeeting-cvs-20030730.CVS.patched/src/videograbber.cpp	2003-07-31 16:45:33.000000000 +0200
@@ -331,23 +331,6 @@
     gnomemeeting_statusbar_flash (gw->statusbar, _("Opening Video device"));
     gnomemeeting_log_insert (gw->history_text_view, _("Opening Video device"));
     gnomemeeting_threads_leave ();
-    
-#ifdef TRY_1394AVC
-    if (video_device == "/dev/raw1394" ||
-       strncmp (video_device, "/dev/video1394", 14) == 0) {
-            grabber = new PVideoInput1394AvcDevice();
-       }
-    else
-#endif
-#ifdef TRY_1394DC
-    if (video_device == "/dev/raw1394" ||
-        strncmp (video_device, "/dev/video1394", 14) == 0)
-           grabber = new PVideoInput1394DcDevice();
-    else
-#endif
-      {
-	 grabber = new PVideoInputDevice();
-      }
 
     if (video_size == 0) { 
       
@@ -360,15 +343,14 @@
       width = GM_CIF_WIDTH; 
     }
     
-    grabber->SetPreferredColourFormat (color_format);
-
     /* no error if Picture is choosen as video device */
     if (!strcmp (video_device, _("Picture")))
       error_code = -2;
 
     if (error_code != -2) {
 
-      if (!grabber->Open (video_device, FALSE))
+      grabber = PVideoInputManager::GetOpenedDevice(video_device, FALSE);
+      if (grabber == NULL)
 	error_code = 0;
       else
 	if (!grabber->SetFrameSizeConverter (width, height, FALSE))
@@ -448,10 +430,6 @@
 
 	gnomemeeting_threads_leave ();
       }
-
-      /* delete the failed grabber and open the fake grabber, either
-       because there was an error, either because the user chose to do so */
-      delete grabber;
       
       gnomemeeting_threads_enter ();
       video_image = gconf_client_get_string (GCONF_CLIENT (client), "/apps/gnomemeeting/devices/video_image", NULL);
@@ -655,23 +633,6 @@
   gtk_progress_bar_set_text (GTK_PROGRESS_BAR (dw->progress), "");
   gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (dw->progress), 0.0);
   gnomemeeting_threads_leave ();
-
-#ifdef TRY_1394AVC
-    if (video_device == "/dev/raw1394" ||
-       strncmp (video_device, "/dev/video1394", 14) == 0) {
-            grabber = new PVideoInput1394AvcDevice();
-       }
-    else
-#endif
-#ifdef TRY_1394DC
-    if (video_device == "/dev/raw1394" ||
-        strncmp (video_device, "/dev/video1394", 14) == 0)
-           grabber = new PVideoInput1394DcDevice();
-    else
-#endif
-      {
-	 grabber = new PVideoInputDevice();
-      }
   
   while (cpt <= 3) {
 
@@ -682,7 +643,8 @@
     
     if (strcmp (video_device, _("Picture"))) {
       
-      if (!grabber->Open (video_device, FALSE))
+      grabber = PVideoInputManager::GetOpenedDevice(video_device, FALSE);
+      if (grabber == NULL)
 	error_code = 0;
       else
 	if (!grabber->SetFrameSizeConverter (width, height, FALSE))
@@ -752,8 +714,6 @@
   gdk_threads_leave ();
   g_free (msg);
 
-  delete (grabber);
-
   gdk_threads_enter ();
   gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (dw->progress), 1.0);
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dw->video_test_button),
// 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;
      // of course, I count on lazy evaluation

      delete dev;
      return NULL;
    }
  else
    { // doesn't look like a nice devName

      // FIXME! If the user is on CLI and asked to open a /dev/video3.14,
      // 1. we should try all plugins until we find one that fits;
      // 2. we should get our list of supported devices, and try to find
      //a match.

      // the second solution looks nicer, but my pattern-matching abilities are
      // quite small, as the previous fixme must have proven.

      return NULL;
    }

}

PStringList
PVideoInputManager::GetInputDeviceNames()
{
  struct video_plugin *ptr;
  PStringList Result;
 
  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
  
  for(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;
}
diff -ur pwlib-20030729.CVS/include/ptlib/videoio.h pwlib-20030729.CVS.patched/include/ptlib/videoio.h
--- pwlib-20030729.CVS/include/ptlib/videoio.h	2003-03-17 09:10:00.000000000 +0100
+++ pwlib-20030729.CVS.patched/include/ptlib/videoio.h	2003-07-31 16:05:18.000000000 +0200
@@ -862,5 +862,25 @@
 #include <ptlib/videoio.h>
 };
 
+class PVideoInputManager
+{
+public:
+  PVideoInputManager();
+  ~PVideoInputManager();
+
+  static PStringList GetInputDeviceNames();
+
+  static void LoadPluginDirectory(PDirectory);
+  static BOOL LoadPlugin(PString);
+  
+  static PVideoInputDevice *GetDevice(PString);
+  static PVideoInputDevice *GetOpenedDevice(PString, BOOL);
+
+private:
+
+  static void LoadAllPlugins();
+  
+};
+
 
 // End Of File ///////////////////////////////////////////////////////////////
diff -ur pwlib-20030729.CVS/src/ptlib/unix/Makefile pwlib-20030729.CVS.patched/src/ptlib/unix/Makefile
--- pwlib-20030729.CVS/src/ptlib/unix/Makefile	2003-07-28 20:44:01.000000000 +0200
+++ pwlib-20030729.CVS.patched/src/ptlib/unix/Makefile	2003-07-31 16:06:40.000000000 +0200
@@ -447,6 +447,7 @@
 VIDEO_SOURCE := $(COMMON_SRC_DIR)/vfakeio.cxx \
                 $(COMMON_SRC_DIR)/videoio.cxx \
 		$(VIDEO_CAPTURE_SOURCE) \
+		vidin_manager_dlopen.cxx \
 	        $(COMMON_SRC_DIR)/vconvert.cxx
 
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]