[cheese] device-monitor: port to GstDeviceMonitor



commit 8dda8bf18b5fb82f6b1087dc4e2ccb2415d5611b
Author: Wim Taymans <wtaymans redhat com>
Date:   Fri Jul 10 16:05:29 2015 +0200

    device-monitor: port to GstDeviceMonitor
    
    Use GstDeviceMonitor to monitor the GStreamer devices.

 configure.ac                             |    2 +-
 libcheese/cheese-camera-device-monitor.c |  305 ++++++++----------------------
 libcheese/cheese-camera-device-monitor.h |    7 +-
 libcheese/cheese-camera-device.c         |  269 +++++---------------------
 libcheese/cheese-camera-device.h         |    9 +-
 libcheese/cheese-camera.c                |  141 +++++---------
 libcheese/cheese-camera.h                |    4 +-
 src/cheese-preferences.vala              |   16 +-
 src/vapi/cheese-common.vapi              |   17 +-
 tests/cheese-test-monitor.c              |    6 +-
 10 files changed, 207 insertions(+), 569 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 9e37cb2..ca69c3d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -63,7 +63,7 @@ IT_PROG_INTLTOOL([0.50.0])
 GLIB_REQUIRED="glib-2.0 >= 2.39.90"
 GTK_REQUIRED="gtk+-3.0 >= 3.13.4"
 GDK_PIXBUF_REQUIRED="gdk-pixbuf-2.0"
-GSTREAMER_REQUIRED="gstreamer-pbutils-1.0 gstreamer-plugins-bad-1.0"
+GSTREAMER_REQUIRED="gstreamer-pbutils-1.0 gstreamer-plugins-bad-1.0 >= 1.4"
 LIBGNOMEDESKTOP_REQUIRED="gnome-desktop-3.0"
 CLUTTER_REQUIRED="clutter-1.0 >= 1.13.2"
 CLUTTERGTK_REQUIRED="clutter-gtk-1.0"
diff --git a/libcheese/cheese-camera-device-monitor.c b/libcheese/cheese-camera-device-monitor.c
index 9ef6473..48520ed 100644
--- a/libcheese/cheese-camera-device-monitor.c
+++ b/libcheese/cheese-camera-device-monitor.c
@@ -26,46 +26,25 @@
 #include <glib-object.h>
 #include <string.h>
 
-#ifdef HAVE_UDEV
-  #define G_UDEV_API_IS_SUBJECT_TO_CHANGE 1
-  #include <gudev/gudev.h>
-#else
-  #include <fcntl.h>
-  #include <unistd.h>
-  #include <sys/ioctl.h>
-  #if USE_SYS_VIDEOIO_H > 0
-    #include <sys/types.h>
-    #include <sys/videoio.h>
-  #elif defined (__sun)
-    #include <sys/types.h>
-    #include <sys/videodev2.h>
-  #endif /* USE_SYS_VIDEOIO_H */
-#endif
-
 #include "cheese-camera-device-monitor.h"
 
 /**
  * SECTION:cheese-camera-device-monitor
- * @short_description: Simple object to enumerate v4l devices
+ * @short_description: Simple object to enumerate video devices
  * @stability: Unstable
  * @include: cheese/cheese-camera-device-monitor.h
  *
- * #CheeseCameraDeviceMonitor provides a basic interface for video4linux device
+ * #CheeseCameraDeviceMonitor provides a basic interface for video device
  * enumeration and hotplugging.
  *
- * It uses either GUdev or some platform specific code to list video devices.
- * It is also capable (right now in Linux only, with the udev backend) to
+ * It uses GstDeviceMonitor to list video devices. It is also capable to
  * monitor device plugging and emit a CheeseCameraDeviceMonitor::added or
  * CheeseCameraDeviceMonitor::removed signal when an event happens.
  */
 
 struct _CheeseCameraDeviceMonitorPrivate
 {
-#ifdef HAVE_UDEV
-  GUdevClient *client;
-#else
-  guint filler;
-#endif /* HAVE_UDEV */
+  GstDeviceMonitor *monitor;
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (CheeseCameraDeviceMonitor, cheese_camera_device_monitor, G_TYPE_OBJECT)
@@ -92,165 +71,100 @@ cheese_camera_device_monitor_error_quark (void)
   return g_quark_from_static_string ("cheese-camera-error-quark");
 }
 
-#ifdef HAVE_UDEV
-
 /*
  * cheese_camera_device_monitor_set_up_device:
- * @udevice: the device information from udev
+ * @device: the device information from GStreamer
  *
- * Creates a new #CheeseCameraDevice for the supplied @udevice.
+ * Creates a new #CheeseCameraDevice for the supplied @device.
  *
- * Returns: a new #CheeseCameraDevice, or %NULL if @udevice was not a V4L
- * capture device
+ * Returns: a new #CheeseCameraDevice, or %NULL if @device was not an
+ * acceptable capture device
  */
 static CheeseCameraDevice*
-cheese_camera_device_monitor_set_up_device (GUdevDevice *udevice)
+cheese_camera_device_monitor_set_up_device (GstDevice *device)
 {
-  const char *device_file;
-  const char *product_name;
-  const char *vendor;
-  const char *product;
-  const char *bus;
-  GError      *error = NULL;
-  gint        vendor_id   = 0;
-  gint        product_id  = 0;
-  gint        v4l_version = 0;
-  CheeseCameraDevice *device;
-
-  const gchar *devpath = g_udev_device_get_property (udevice, "DEVPATH");
-
-  GST_INFO ("Checking udev device '%s'", devpath);
-
-  bus = g_udev_device_get_property (udevice, "ID_BUS");
-  if (g_strcmp0 (bus, "usb") == 0)
-  {
-    vendor = g_udev_device_get_property (udevice, "ID_VENDOR_ID");
-    if (vendor != NULL)
-      vendor_id = g_ascii_strtoll (vendor, NULL, 16);
-    product = g_udev_device_get_property (udevice, "ID_MODEL_ID");
-    if (product != NULL)
-      product_id = g_ascii_strtoll (product, NULL, 16);
-    if (vendor_id == 0 || product_id == 0)
-    {
-      GST_WARNING ("Error getting vendor and product id");
-    }
-    else
-    {
-      GST_INFO ("Found device %04x:%04x, getting capabilities...", vendor_id, product_id);
-    }
-  }
-  else
-  {
-    GST_INFO ("Not an usb device, skipping vendor and model id retrieval");
-  }
+  CheeseCameraDevice *newdev;
+  GError *error = NULL;
 
-  device_file = g_udev_device_get_device_file (udevice);
-  if (device_file == NULL)
-  {
-    GST_WARNING ("Error getting V4L device");
-    return NULL;
-  }
+  newdev = cheese_camera_device_new (device, &error);
 
-  /* vbi devices support capture capability too, but cannot be used,
-   * so detect them by device name */
-  if (strstr (device_file, "vbi"))
-  {
-    GST_INFO ("Skipping vbi device: %s", device_file);
-    return NULL;
-  }
-
-  v4l_version = g_udev_device_get_property_as_int (udevice, "ID_V4L_VERSION");
-  if (v4l_version == 2 || v4l_version == 1)
-  {
-    const char *caps;
-
-    caps = g_udev_device_get_property (udevice, "ID_V4L_CAPABILITIES");
-    if (caps == NULL || strstr (caps, ":capture:") == NULL)
-    {
-      GST_WARNING ("Device %s seems to not have the capture capability, (radio tuner?)"
-                   "Removing it from device list.", device_file);
-      return NULL;
-    }
-    product_name = g_udev_device_get_property (udevice, "ID_V4L_PRODUCT");
-  }
-  else if (v4l_version == 0)
-  {
-    GST_ERROR ("Fix your udev installation to include v4l_id, ignoring %s", device_file);
-    return NULL;
-  }
-  else
-  {
-    g_assert_not_reached ();
-  }
-
-  device = cheese_camera_device_new (devpath,
-                                     device_file,
-                                     product_name,
-                                     v4l_version,
-                                     &error);
-
-  if (device == NULL)
-    GST_WARNING ("Device initialization for %s failed: %s ",
-                 device_file,
+  if (newdev == NULL)
+    GST_WARNING ("Device initialization for %p failed: %s ",
+                 device,
                  (error != NULL) ? error->message : "Unknown reason");
 
-  return device;
+  return newdev;
 }
 
 /*
  * cheese_camera_device_monitor_added:
  * @monitor: a #CheeseCameraDeviceMonitor
- * @udevice: the device information, from udev, for the device that was added
+ * @device: the device information, from GStreamer, for the device that was added
  *
  * Emits the ::added signal.
  */
 static void
 cheese_camera_device_monitor_added (CheeseCameraDeviceMonitor *monitor,
-                                    GUdevDevice               *udevice)
+                                    GstDevice                 *device)
 {
-  CheeseCameraDevice *device = cheese_camera_device_monitor_set_up_device (udevice);
+  CheeseCameraDevice *newdev = cheese_camera_device_monitor_set_up_device (device);
   /* Ignore non-video devices, GNOME bug #677544. */
-  if (device)
-    g_signal_emit (monitor, monitor_signals[ADDED], 0, device);
+  if (newdev) {
+    g_object_set_data (G_OBJECT (device), "cheese-camera-device", newdev);
+    g_signal_emit (monitor, monitor_signals[ADDED], 0, newdev);
+  }
 }
 
 /*
  * cheese_camera_device_monitor_removed:
  * @monitor: a #CheeseCameraDeviceMonitor
- * @udevice: the device information, from udev, for the device that was removed
+ * @device: the device information, from GStreamer, for the device that was removed
  *
  * Emits the ::removed signal.
  */
 static void
 cheese_camera_device_monitor_removed (CheeseCameraDeviceMonitor *monitor,
-                                      GUdevDevice               *udevice)
+                                      GstDevice                 *device)
 {
-  g_signal_emit (monitor, monitor_signals[REMOVED], 0,
-                 g_udev_device_get_property (udevice, "DEVPATH"));
+  CheeseCameraDevice *olddev;
+
+  olddev = g_object_get_data (G_OBJECT (device), "cheese-camera-device");
+  if (olddev)
+    g_signal_emit (monitor, monitor_signals[REMOVED], 0, olddev);
 }
 
 /*
- * cheese_camera_device_monitor_uevent_cb:
- * @client: a #GUdevClient
- * @action: the string representing the action type of the uevent
- * @udevice: the #GUdevDevice to which the uevent refers
- * @monitor: a #CheeseCameraDeviceMonitor
+ * cheese_camera_device_monitor_bus_func:
+ * @bus: a #GstBus
+ * @message: the message posted on the bus
  *
- * Check if the uevent corresponds to device addition or removal, and if so,
+ * Check if the message corresponds to device addition or removal, and if so,
  * pass it on to cheese_camera_device_monitor_added() or
  * cheese_camera_device_monitor_removed() for emitting the ::added and
  * ::removed signals.
  */
-static void
-cheese_camera_device_monitor_uevent_cb (GUdevClient               *client,
-                                        const gchar               *action,
-                                        GUdevDevice               *udevice,
-                                        CheeseCameraDeviceMonitor *monitor)
+static gboolean
+cheese_camera_device_monitor_bus_func (GstBus     *bus,
+                                       GstMessage *message,
+                                       gpointer user_data)
 {
-  if (g_str_equal (action, "remove"))
-    cheese_camera_device_monitor_removed (monitor, udevice);
-  else if (g_str_equal (action, "add"))
-    cheese_camera_device_monitor_added (monitor, udevice);
+  CheeseCameraDeviceMonitor *monitor = user_data;
+  GstDevice *device;
+
+  switch (GST_MESSAGE_TYPE (message))
+  {
+    case GST_MESSAGE_DEVICE_ADDED:
+      gst_message_parse_device_added (message, &device);
+      cheese_camera_device_monitor_added (monitor, device);
+      break;
+    case GST_MESSAGE_DEVICE_REMOVED:
+      gst_message_parse_device_removed (message, &device);
+      cheese_camera_device_monitor_removed (monitor, device);
+      break;
+    default:
+      break;
+  }
+  return G_SOURCE_CONTINUE;
 }
 
 /*
@@ -266,7 +180,7 @@ static void
 cheese_camera_device_monitor_add_devices (gpointer data, gpointer user_data)
 {
   cheese_camera_device_monitor_added ((CheeseCameraDeviceMonitor *) user_data,
-    (GUdevDevice *) data);
+    (GstDevice *) data);
   g_object_unref (data);
 }
 
@@ -288,11 +202,11 @@ cheese_camera_device_monitor_coldplug (CheeseCameraDeviceMonitor *monitor)
 
     priv = cheese_camera_device_monitor_get_instance_private (monitor);
 
-    g_return_if_fail (priv->client != NULL);
+    g_return_if_fail (priv->monitor != NULL);
 
-  GST_INFO ("Probing devices with udev...");
+  GST_INFO ("Probing devices with GStreamer monitor...");
 
-    devices = g_udev_client_query_by_subsystem (priv->client, "video4linux");
+  devices = gst_device_monitor_get_devices (priv->monitor);
 
   if (devices == NULL) GST_WARNING ("No device found");
 
@@ -301,88 +215,16 @@ cheese_camera_device_monitor_coldplug (CheeseCameraDeviceMonitor *monitor)
   g_list_free (devices);
 }
 
-#else /* HAVE_UDEV */
-void
-cheese_camera_device_monitor_coldplug (CheeseCameraDeviceMonitor *monitor)
-{
-  #if 0
-  CheeseCameraDeviceMonitorPrivate *priv = monitor->priv;
-  struct v4l2_capability            v2cap;
-  struct video_capability           v1cap;
-  int                               fd, ok;
-
-  if ((fd = open (device_path, O_RDONLY | O_NONBLOCK)) < 0)
-  {
-    g_warning ("Failed to open %s: %s", device_path, strerror (errno));
-    return;
-  }
-  ok = ioctl (fd, VIDIOC_QUERYCAP, &v2cap);
-  if (ok < 0)
-  {
-    ok = ioctl (fd, VIDIOCGCAP, &v1cap);
-    if (ok < 0)
-    {
-      g_warning ("Error while probing v4l capabilities for %s: %s",
-                 device_path, strerror (errno));
-      close (fd);
-      return;
-    }
-    g_print ("Detected v4l device: %s\n", v1cap.name);
-    g_print ("Device type: %d\n", v1cap.type);
-    gstreamer_src = "v4lsrc";
-    product_name  = v1cap.name;
-  }
-  else
-  {
-    guint cap = v2cap.capabilities;
-    g_print ("Detected v4l2 device: %s\n", v2cap.card);
-    g_print ("Driver: %s, version: %d\n", v2cap.driver, v2cap.version);
-
-    /* g_print ("Bus info: %s\n", v2cap.bus_info); */ /* Doesn't seem anything useful */
-    g_print ("Capabilities: 0x%08X\n", v2cap.capabilities);
-    if (!(cap & V4L2_CAP_VIDEO_CAPTURE))
-    {
-      g_print ("Device %s seems to not have the capture capability, (radio tuner?)\n"
-               "Removing it from device list.\n", device_path);
-      close (fd);
-      return;
-    }
-    gstreamer_src = "v4l2src";
-    product_name  = (char *) v2cap.card;
-  }
-  close (fd);
-
-  GList *devices, *l;
-
-  g_print ("Probing devices with udev...\n");
-
-  if (priv->client == NULL)
-    return;
-
-  devices = g_udev_client_query_by_subsystem (priv->client, "video4linux");
-
-  /* Initialize camera structures */
-  for (l = devices; l != NULL; l = l->next)
-  {
-    cheese_camera_device_monitor_added (monitor, l->data);
-    g_object_unref (l->data);
-  }
-  g_list_free (devices);
-  #endif
-}
-
-#endif /* HAVE_UDEV */
-
 static void
 cheese_camera_device_monitor_finalize (GObject *object)
 {
-#ifdef HAVE_UDEV
     CheeseCameraDeviceMonitorPrivate *priv;
 
     priv = cheese_camera_device_monitor_get_instance_private (CHEESE_CAMERA_DEVICE_MONITOR (object));
 
-  g_clear_object (&priv->client);
-#endif /* HAVE_UDEV */
+  gst_device_monitor_stop (priv->monitor);
+  g_clear_object (&priv->monitor);
+
   G_OBJECT_CLASS (cheese_camera_device_monitor_parent_class)->finalize (object);
 }
 
@@ -416,7 +258,7 @@ cheese_camera_device_monitor_class_init (CheeseCameraDeviceMonitorClass *klass)
   /**
    * CheeseCameraDeviceMonitor::removed:
    * @monitor: the #CheeseCameraDeviceMonitor that emitted the signal
-   * @uuid: UUID for the device on the system
+   * @device: the #CheeseCameraDevice that was removed
    *
    * The ::removed signal is emitted when a camera is unplugged, or disabled on
    * the system.
@@ -426,20 +268,27 @@ cheese_camera_device_monitor_class_init (CheeseCameraDeviceMonitorClass *klass)
                                            G_STRUCT_OFFSET (CheeseCameraDeviceMonitorClass, removed),
                                            NULL, NULL,
                                            g_cclosure_marshal_VOID__STRING,
-                                           G_TYPE_NONE, 1, G_TYPE_STRING);
+                                           G_TYPE_NONE, 1, CHEESE_TYPE_CAMERA_DEVICE);
 }
 
 static void
 cheese_camera_device_monitor_init (CheeseCameraDeviceMonitor *monitor)
 {
-#ifdef HAVE_UDEV
     CheeseCameraDeviceMonitorPrivate *priv = cheese_camera_device_monitor_get_instance_private (monitor);
-  const gchar *const subsystems[] = {"video4linux", NULL};
+  GstBus *bus;
+  GstCaps *caps;
+
+  priv->monitor = gst_device_monitor_new ();
+
+  bus = gst_device_monitor_get_bus (priv->monitor);
+  gst_bus_add_watch (bus, cheese_camera_device_monitor_bus_func, monitor);
+  gst_object_unref (bus);
+
+  caps = gst_caps_new_empty_simple ("video/x-raw");
+  gst_device_monitor_add_filter (priv->monitor, "Video/Source", caps);
+  gst_caps_unref (caps);
 
-  priv->client = g_udev_client_new (subsystems);
-  g_signal_connect (G_OBJECT (priv->client), "uevent",
-                    G_CALLBACK (cheese_camera_device_monitor_uevent_cb), monitor);
-#endif /* HAVE_UDEV */
+  gst_device_monitor_start (priv->monitor);
 }
 
 /**
diff --git a/libcheese/cheese-camera-device-monitor.h b/libcheese/cheese-camera-device-monitor.h
index 1089000..f11d0a4 100644
--- a/libcheese/cheese-camera-device-monitor.h
+++ b/libcheese/cheese-camera-device-monitor.h
@@ -67,9 +67,10 @@ struct _CheeseCameraDeviceMonitorClass
   GObjectClass parent_class;
 
   /*< public >*/
-  void (*added)(CheeseCameraDeviceMonitor *monitor,
-                CheeseCameraDevice        *device);
-  void (*removed)(CheeseCameraDeviceMonitor *monitor, const gchar *uuid);
+  void (*added)   (CheeseCameraDeviceMonitor *monitor,
+                   CheeseCameraDevice        *device);
+  void (*removed) (CheeseCameraDeviceMonitor *monitor,
+                   CheeseCameraDevice        *device);
 };
 
 GType                      cheese_camera_device_monitor_get_type (void);
diff --git a/libcheese/cheese-camera-device.c b/libcheese/cheese-camera-device.c
index f4ff19d..d96f78d 100644
--- a/libcheese/cheese-camera-device.c
+++ b/libcheese/cheese-camera-device.c
@@ -86,9 +86,7 @@ enum
 {
   PROP_0,
   PROP_NAME,
-  PROP_DEVICE_NODE,
-  PROP_UUID,
-  PROP_V4LAPI_VERSION,
+  PROP_DEVICE,
   PROP_LAST
 };
 
@@ -96,15 +94,12 @@ static GParamSpec *properties[PROP_LAST];
 
 typedef struct
 {
-  gchar *device_node;
-  gchar *uuid;
-  const gchar *src;
-  gchar *name;
-  guint  v4lapi_version;
-  GstCaps *caps;
-  GList   *formats; /* list members are CheeseVideoFormatFull structs. */
+  GstDevice *device;
+  gchar     *name;
+  GstCaps   *caps;
+  GList     *formats; /* list members are CheeseVideoFormatFull structs. */
 
-  GError *construct_error;
+  GError    *construct_error;
 } CheeseCameraDevicePrivate;
 
 G_DEFINE_TYPE_WITH_CODE (CheeseCameraDevice, cheese_camera_device,
@@ -520,101 +515,34 @@ cheese_camera_device_update_format_table (CheeseCameraDevice *device)
 static void
 cheese_camera_device_get_caps (CheeseCameraDevice *device)
 {
-    CheeseCameraDevicePrivate *priv;
-  gchar               *pipeline_desc;
-  GstElement          *pipeline;
-  GstStateChangeReturn ret;
-  GstMessage          *msg;
-  GstBus              *bus;
-  GError              *err = NULL;
-
-    priv = cheese_camera_device_get_instance_private (device);
-  pipeline_desc = g_strdup_printf ("%s name=source device=%s ! fakesink",
-                                   priv->src, priv->device_node);
-  pipeline = gst_parse_launch (pipeline_desc, &err);
-  if ((pipeline != NULL) && (err == NULL))
-  {
-    /* Start the pipeline and wait for max. 10 seconds for it to start up */
-    gst_element_set_state (pipeline, GST_STATE_READY);
-    ret = gst_element_get_state (pipeline, NULL, NULL, 10 * GST_SECOND);
-
-    /* Check if any error messages were posted on the bus */
-    bus = gst_element_get_bus (pipeline);
-    msg = gst_bus_pop_filtered (bus, GST_MESSAGE_ERROR);
-    gst_object_unref (bus);
-
-    if ((msg == NULL) && (ret == GST_STATE_CHANGE_SUCCESS))
-    {
-      GstElement *src;
-      GstPad     *pad;
-      GstCaps    *caps;
-
-      src = gst_bin_get_by_name (GST_BIN (pipeline), "source");
+  CheeseCameraDevicePrivate *priv;
+  GstCaps *caps;
 
-      GST_LOG ("Device: %s (%s)\n", priv->name, priv->device_node);
-      pad        = gst_element_get_static_pad (src, "src");
-      caps       = gst_pad_get_allowed_caps (pad);
+  priv = cheese_camera_device_get_instance_private (device);
 
-      gst_caps_unref (priv->caps);
-      priv->caps = cheese_camera_device_filter_caps (device, caps, supported_formats);
+  caps = gst_device_get_caps (priv->device);
+  if (caps == NULL)
+    caps = gst_caps_new_empty_simple ("video/x-raw");
 
-      if (!gst_caps_is_empty (priv->caps))
-        cheese_camera_device_update_format_table (device);
-      else
-      {
-        g_set_error_literal (&priv->construct_error,
-                             CHEESE_CAMERA_DEVICE_ERROR,
-                             CHEESE_CAMERA_DEVICE_ERROR_UNSUPPORTED_CAPS,
-                             _("Device capabilities not supported"));
-      }
+  gst_caps_unref (priv->caps);
+  priv->caps = cheese_camera_device_filter_caps (device, caps, supported_formats);
 
-      gst_object_unref (pad);
-      gst_caps_unref (caps);
-      gst_object_unref (src);
-    }
-    else
-    {
-      if (msg)
-      {
-        gchar *dbg_info = NULL;
-        gst_message_parse_error (msg, &err, &dbg_info);
-        GST_WARNING ("Failed to start the capability probing pipeline");
-        GST_WARNING ("Error from element %s: %s, %s",
-                     GST_OBJECT_NAME (msg->src),
-                     err->message,
-                     (dbg_info) ? dbg_info : "no extra debug detail");
-        g_error_free (err);
-        err = NULL;
-
-        /* construct_error is meant to be displayed in the UI
-         * (although it currently isn't displayed in cheese),
-         * err->message from gstreamer is too technical for this
-         * purpose, the idea is warn the user about an error and point
-         * him to the logs for more info */
-        g_set_error (&priv->construct_error,
-                     CHEESE_CAMERA_DEVICE_ERROR,
-                     CHEESE_CAMERA_DEVICE_ERROR_FAILED_INITIALIZATION,
-                     _("Failed to initialize device %s for capability probing"),
-                     priv->device_node);
-      }
-    }
-    gst_element_set_state (pipeline, GST_STATE_NULL);
-    gst_object_unref (pipeline);
+  if (!gst_caps_is_empty (priv->caps))
+    cheese_camera_device_update_format_table (device);
+  else
+  {
+    g_set_error_literal (&priv->construct_error,
+                         CHEESE_CAMERA_DEVICE_ERROR,
+                         CHEESE_CAMERA_DEVICE_ERROR_UNSUPPORTED_CAPS,
+                         _("Device capabilities not supported"));
   }
-
-  if (err)
-    g_error_free (err);
-
-  g_free (pipeline_desc);
+  gst_caps_unref (caps);
 }
 
 static void
 cheese_camera_device_constructed (GObject *object)
 {
   CheeseCameraDevice        *device = CHEESE_CAMERA_DEVICE (object);
-    CheeseCameraDevicePrivate *priv = cheese_camera_device_get_instance_private (device);
-
-  priv->src = (priv->v4lapi_version == 2) ? "v4l2src" : "v4lsrc";
 
   cheese_camera_device_get_caps (device);
 
@@ -633,14 +561,8 @@ cheese_camera_device_get_property (GObject *object, guint prop_id, GValue *value
     case PROP_NAME:
       g_value_set_string (value, priv->name);
       break;
-    case PROP_DEVICE_NODE:
-      g_value_set_string (value, priv->device_node);
-      break;
-    case PROP_UUID:
-      g_value_set_string (value, priv->uuid);
-      break;
-    case PROP_V4LAPI_VERSION:
-      g_value_set_uint (value, priv->v4lapi_version);
+    case PROP_DEVICE:
+      g_value_set_object (value, priv->device);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -657,22 +579,15 @@ cheese_camera_device_set_property (GObject *object, guint prop_id, const GValue
   switch (prop_id)
   {
     case PROP_NAME:
-      if (priv->name)
-        g_free (priv->name);
+      g_free (priv->name);
       priv->name = g_value_dup_string (value);
       break;
-    case PROP_UUID:
-      if (priv->uuid)
-        g_free (priv->uuid);
-      priv->uuid = g_value_dup_string (value);
-      break;
-    case PROP_DEVICE_NODE:
-      if (priv->device_node)
-        g_free (priv->device_node);
-      priv->device_node = g_value_dup_string (value);
-      break;
-    case PROP_V4LAPI_VERSION:
-      priv->v4lapi_version = g_value_get_uint (value);
+    case PROP_DEVICE:
+      if (priv->device)
+        g_object_unref (priv->device);
+      priv->device = g_value_dup_object (value);
+      g_free (priv->name);
+      priv->name = gst_device_get_display_name (priv->device);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -686,8 +601,7 @@ cheese_camera_device_finalize (GObject *object)
   CheeseCameraDevice        *device = CHEESE_CAMERA_DEVICE (object);
     CheeseCameraDevicePrivate *priv = cheese_camera_device_get_instance_private (device);
 
-  g_free (priv->device_node);
-  g_free (priv->uuid);
+  g_object_unref (priv->device);
   g_free (priv->name);
 
   gst_caps_unref (priv->caps);
@@ -725,44 +639,17 @@ cheese_camera_device_class_init (CheeseCameraDeviceClass *klass)
                                                G_PARAM_STATIC_STRINGS);
 
   /**
-   * CheeseCameraDevice:device-node:
+   * CheeseCameraDevice:device:
    *
-   * Path to the device node of the video capture device.
+   * GStreamer device object of the video capture device.
    */
-  properties[PROP_DEVICE_NODE] = g_param_spec_string ("device-node",
-                                                      "Device node",
-                                                      "Path to the device node of the video capture device",
-                                                      NULL,
-                                                      G_PARAM_READWRITE |
-                                                      G_PARAM_CONSTRUCT_ONLY |
-                                                      G_PARAM_STATIC_STRINGS);
-
-  /**
-   * CheeseCameraDevice:uuid:
-   *
-   * UUID of the video capture device.
-   */
-  properties[PROP_UUID] = g_param_spec_string ("uuid",
-                                               "Device UUID",
-                                               "UUID of the video capture device",
-                                               NULL,
-                                               G_PARAM_READWRITE |
-                                               G_PARAM_CONSTRUCT_ONLY |
-                                               G_PARAM_STATIC_STRINGS);
-
-  /**
-   * CheeseCameraDevice:v4l-api-version:
-   *
-   * Version of the Video4Linux API that the device supports. Currently, either
-   * 1 or 2 are supported.
-   */
-  properties[PROP_V4LAPI_VERSION] = g_param_spec_uint ("v4l-api-version",
-                                                       "Video4Linux API version",
-                                                       "Version of the Video4Linux API that the device 
supports",
-                                                       1, 2, 2,
-                                                       G_PARAM_READWRITE |
-                                                       G_PARAM_CONSTRUCT_ONLY |
-                                                       G_PARAM_STATIC_STRINGS);
+  properties[PROP_DEVICE] = g_param_spec_object ("device",
+                                                 "Device",
+                                                 "The GStreamer device object of the video capture device",
+                                                 GST_TYPE_DEVICE,
+                                                 G_PARAM_READWRITE |
+                                                 G_PARAM_CONSTRUCT_ONLY |
+                                                 G_PARAM_STATIC_STRINGS);
 
   g_object_class_install_properties (object_class, PROP_LAST, properties);
 }
@@ -815,32 +702,21 @@ cheese_camera_device_initable_init (GInitable    *initable,
 
 /**
  * cheese_camera_device_new:
- * @uuid: UUID of the device, as supplied by udev
- * @device_node: (type filename): path to the device node of the video capture
- * device
- * @name: human-readable name of the device, as supplied by udev
- * @v4l_api_version: version of the Video4Linux API that the device uses. Currently
- * either 1 or 2
+ * @device: The GStreamer the device, as supplied by GstDeviceMonitor
  * @error: a location to store errors
  *
- * Tries to create a new #CheeseCameraDevice with the supplied parameters. If
+ * Tries to create a new #CheeseCameraDevice with the supplied device. If
  * construction fails, %NULL is returned, and @error is set.
  *
  * Returns: a new #CheeseCameraDevice, or %NULL
  */
 CheeseCameraDevice *
-cheese_camera_device_new (const gchar *uuid,
-                          const gchar *device_node,
-                          const gchar *name,
-                          guint        v4l_api_version,
-                          GError     **error)
+cheese_camera_device_new (GstDevice *device,
+                          GError    **error)
 {
   return CHEESE_CAMERA_DEVICE (g_initable_new (CHEESE_TYPE_CAMERA_DEVICE,
                                                NULL, error,
-                                               "uuid", uuid,
-                                               "device-node", device_node,
-                                               "name", name,
-                                               "v4l-api-version", v4l_api_version,
+                                               "device", device,
                                                NULL));
 }
 
@@ -887,36 +763,14 @@ cheese_camera_device_get_name (CheeseCameraDevice *device)
 }
 
 /**
- * cheese_camera_device_get_uuid:
- * @device: a #CheeseCameraDevice
- *
- * Get the UUID of the @device, as reported by udev.
- *
- * Returns: (transfer none): the UUID of the video capture device
- */
-const gchar *
-cheese_camera_device_get_uuid (CheeseCameraDevice *device)
-{
-    CheeseCameraDevicePrivate *priv;
-
-  g_return_val_if_fail (CHEESE_IS_CAMERA_DEVICE (device), NULL);
-
-    priv = cheese_camera_device_get_instance_private (device);
-
-    return priv->uuid;
-}
-
-/**
  * cheese_camera_device_get_src:
  * @device: a #CheeseCameraDevice
  *
- * Get the name of the source GStreamer element for the @device. Currently,
- * this will be either v4lsrc or v4l2src, depending on the version of the
- * Video4Linux API that the device supports.
+ * Get the source GStreamer element for the @device.
  *
- * Returns: (transfer none): the name of the source GStreamer element
+ * Returns: (transfer full): the source GStreamer element
  */
-const gchar *
+GstElement *
 cheese_camera_device_get_src (CheeseCameraDevice *device)
 {
     CheeseCameraDevicePrivate *priv;
@@ -925,28 +779,7 @@ cheese_camera_device_get_src (CheeseCameraDevice *device)
 
     priv = cheese_camera_device_get_instance_private (device);
 
-    return priv->src;
-}
-
-/**
- * cheese_camera_device_get_device_node:
- * @device: a #CheeseCameraDevice
- *
- * Get the path to the device node associated with the @device.
- *
- * Returns: (transfer none): the path to the device node of the video capture
- * device
- */
-const gchar *
-cheese_camera_device_get_device_node (CheeseCameraDevice *device)
-{
-    CheeseCameraDevicePrivate *priv;
-
-  g_return_val_if_fail (CHEESE_IS_CAMERA_DEVICE (device), NULL);
-
-    priv = cheese_camera_device_get_instance_private (device);
-
-    return priv->device_node;
+    return gst_device_create_element (priv->device, NULL);
 }
 
 /**
diff --git a/libcheese/cheese-camera-device.h b/libcheese/cheese-camera-device.h
index 4590461..4f5d819 100644
--- a/libcheese/cheese-camera-device.h
+++ b/libcheese/cheese-camera-device.h
@@ -64,10 +64,7 @@ GType cheese_video_format_get_type (void);
 #define CHEESE_TYPE_CAMERA_DEVICE (cheese_camera_device_get_type ())
 G_DECLARE_FINAL_TYPE (CheeseCameraDevice, cheese_camera_device, CHEESE, CAMERA_DEVICE, GObject)
 
-CheeseCameraDevice *cheese_camera_device_new (const gchar *uuid,
-                                              const gchar *device_node,
-                                              const gchar *name,
-                                              guint        v4l_api_version,
+CheeseCameraDevice *cheese_camera_device_new (GstDevice   *device,
                                               GError     **error);
 
 GstCaps *cheese_camera_device_get_caps_for_format (CheeseCameraDevice *device,
@@ -76,9 +73,7 @@ CheeseVideoFormat *cheese_camera_device_get_best_format (CheeseCameraDevice *dev
 GList *            cheese_camera_device_get_format_list (CheeseCameraDevice *device);
 
 const gchar *cheese_camera_device_get_name (CheeseCameraDevice *device);
-const gchar *cheese_camera_device_get_src (CheeseCameraDevice *device);
-const gchar *cheese_camera_device_get_uuid (CheeseCameraDevice *device);
-const gchar *cheese_camera_device_get_device_node (CheeseCameraDevice *device);
+GstElement * cheese_camera_device_get_src (CheeseCameraDevice *device);
 
 G_END_DECLS
 
diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
index f15f216..095636b 100644
--- a/libcheese/cheese-camera.c
+++ b/libcheese/cheese-camera.c
@@ -84,7 +84,7 @@ struct _CheeseCameraPrivate
   gchar *photo_filename;
 
   guint num_camera_devices;
-  gchar *device_node;
+  CheeseCameraDevice *device;
 
   /* an array of CheeseCameraDevices */
   GPtrArray *camera_devices;
@@ -106,7 +106,7 @@ enum
 {
   PROP_0,
   PROP_VIDEO_TEXTURE,
-  PROP_DEVICE_NODE,
+  PROP_DEVICE,
   PROP_FORMAT,
   PROP_NUM_CAMERA_DEVICES,
   PROP_LAST
@@ -312,34 +312,23 @@ cheese_camera_add_device (CheeseCameraDeviceMonitor *monitor,
 /*
  * cheese_camera_remove_device:
  * @monitor: a #CheeseCameraDeviceMonitor
- * @uuid: UUId of a #CheeseCameraDevice
+ * @device: a #CheeseCameraDevice
  * @camera: a #CheeseCamera
  *
  * Handle the CheeseCameraDeviceMonitor::removed signal and remove the
- * #CheeseCameraDevice associated with the UUID from the list of current
- * devices.
+ * #CheeseCameraDevice from the list of current devices.
  */
 static void
 cheese_camera_remove_device (CheeseCameraDeviceMonitor *monitor,
-                             const gchar               *uuid,
+                            CheeseCameraDevice        *device,
                              CheeseCamera              *camera)
 {
-  guint i;
-
-    CheeseCameraPrivate *priv = cheese_camera_get_instance_private (camera);
+  CheeseCameraPrivate *priv = cheese_camera_get_instance_private (camera);
 
-  for (i = 0; i < priv->num_camera_devices; i++)
+  if (g_ptr_array_remove (priv->camera_devices, (gpointer) device))
   {
-    CheeseCameraDevice *device = (CheeseCameraDevice *) g_ptr_array_index (priv->camera_devices, i);
-    const gchar *device_uuid = cheese_camera_device_get_uuid (device);
-
-    if (strcmp (device_uuid, uuid) == 0)
-    {
-        g_ptr_array_remove (priv->camera_devices, (gpointer) device);
-        priv->num_camera_devices--;
-        g_object_notify_by_pspec (G_OBJECT (camera), properties[PROP_NUM_CAMERA_DEVICES]);
-        break;
-    }
+     priv->num_camera_devices--;
+     g_object_notify_by_pspec (G_OBJECT (camera), properties[PROP_NUM_CAMERA_DEVICES]);
   }
 }
 
@@ -381,45 +370,48 @@ cheese_camera_set_camera_source (CheeseCamera *camera)
 {
     CheeseCameraPrivate *priv = cheese_camera_get_instance_private (camera);
 
-  GError *err = NULL;
-  gchar  *camera_input;
-
-  guint               i;
+  guint i;
   CheeseCameraDevice *selected_camera;
+  GstElement *src, *filter;
+  GstPad *srcpad;
 
   if (priv->video_source)
     gst_object_unref (priv->video_source);
 
   /* If we have a matching video device use that one, otherwise use the first */
   priv->selected_device = 0;
-  selected_camera       = g_ptr_array_index (priv->camera_devices, 0);
+  selected_camera = g_ptr_array_index (priv->camera_devices, 0);
 
   for (i = 1; i < priv->num_camera_devices; i++)
   {
-    CheeseCameraDevice *device = g_ptr_array_index (priv->camera_devices, i);
-    if (g_strcmp0 (cheese_camera_device_get_device_node (device),
-                   priv->device_node) == 0)
+    CheeseCameraDevice *dev = g_ptr_array_index (priv->camera_devices, i);
+    if (dev == priv->device)
     {
-      selected_camera       = device;
+      selected_camera       = dev;
       priv->selected_device = i;
       break;
     }
   }
 
-  camera_input = g_strdup_printf (
-    "%s name=video_source device=%s ! capsfilter name=video_source_filter",
-    cheese_camera_device_get_src (selected_camera),
-    cheese_camera_device_get_device_node (selected_camera));
-
-  priv->video_source = gst_parse_bin_from_description (camera_input, TRUE, &err);
-  g_free (camera_input);
-
+  priv->video_source = gst_bin_new (NULL);
   if (priv->video_source == NULL)
   {
-    g_clear_error(&err);
     return FALSE;
   }
 
+  src = cheese_camera_device_get_src (selected_camera);
+  gst_bin_add (GST_BIN (priv->video_source), src);
+
+  filter = gst_element_factory_make ("capsfilter", "video_source_filter");
+  gst_bin_add (GST_BIN (priv->video_source), filter);
+
+  gst_element_link (src, filter);
+
+  srcpad = gst_element_get_static_pad (filter, "src");
+  gst_element_add_pad (priv->video_source,
+                       gst_ghost_pad_new ("src", srcpad));
+  gst_object_unref (srcpad);
+
   return TRUE;
 }
 
@@ -1270,7 +1262,7 @@ cheese_camera_finalize (GObject *object)
   if (priv->photo_filename)
     g_free (priv->photo_filename);
   g_free (priv->current_effect_desc);
-  g_free (priv->device_node);
+  g_object_unref (priv->device);
   g_boxed_free (CHEESE_TYPE_VIDEO_FORMAT, priv->current_format);
 
   /* Free CheeseCameraDevice array */
@@ -1296,8 +1288,8 @@ cheese_camera_get_property (GObject *object, guint prop_id, GValue *value,
     case PROP_VIDEO_TEXTURE:
       g_value_set_pointer (value, priv->video_texture);
       break;
-    case PROP_DEVICE_NODE:
-      g_value_set_string (value, priv->device_node);
+    case PROP_DEVICE:
+      g_value_set_object (value, priv->device);
       break;
     case PROP_FORMAT:
       g_value_set_boxed (value, priv->current_format);
@@ -1326,9 +1318,9 @@ cheese_camera_set_property (GObject *object, guint prop_id, const GValue *value,
     case PROP_VIDEO_TEXTURE:
       priv->video_texture = g_value_get_pointer (value);
       break;
-    case PROP_DEVICE_NODE:
-      g_free (priv->device_node);
-      priv->device_node = g_value_dup_string (value);
+    case PROP_DEVICE:
+      g_object_unref (priv->device);
+      priv->device = g_value_dup_object (value);
       break;
     case PROP_FORMAT:
       if (priv->current_format != NULL)
@@ -1422,16 +1414,16 @@ cheese_camera_class_init (CheeseCameraClass *klass)
                                                          G_PARAM_STATIC_STRINGS);
 
   /**
-   * CheeseCamera:device-node:
+   * CheeseCamera:device:
    *
-   * The path to the device node for the video capture device.
+   * The device object to capture from.
    */
-  properties[PROP_DEVICE_NODE] = g_param_spec_string ("device-node",
-                                                      "Device node",
-                                                      "The path to the device node for the video capture 
device",
-                                                      "",
-                                                      G_PARAM_READWRITE |
-                                                      G_PARAM_STATIC_STRINGS);
+  properties[PROP_DEVICE] = g_param_spec_object ("device",
+                                                 "Device",
+                                                 "The device object to capture from",
+                                                 CHEESE_TYPE_CAMERA_DEVICE,
+                                                 G_PARAM_READWRITE |
+                                                 G_PARAM_STATIC_STRINGS);
 
   /**
    * CheeseCamera:format:
@@ -1506,57 +1498,30 @@ cheese_camera_new (ClutterTexture *video_texture, const gchar *camera_device_nod
 }
 
 /**
- * cheese_camera_set_device_by_device_node:
+ * cheese_camera_set_device:
  * @camera: a #CheeseCamera
- * @file: (type filename): the device node path
+ * @device: the device object
  *
- * Set the active video capture device of the @camera, matching by device node
- * path.
+ * Set the active video capture device of the @camera.
  */
 void
-cheese_camera_set_device_by_device_node (CheeseCamera *camera, const gchar *file)
+cheese_camera_set_device (CheeseCamera *camera, CheeseCameraDevice *device)
 {
   g_return_if_fail (CHEESE_IS_CAMERA (camera));
 
-  g_object_set (camera, "device-node", file, NULL);
-}
-
-/*
- * cheese_camera_set_device_by_uuid:
- * @camera: a #CheeseCamera
- * @uuid: UUID of a #CheeseCameraDevice
- *
- * Set the active video capture device of the @camera, matching by UUID.
- */
-static void
-cheese_camera_set_device_by_dev_uuid (CheeseCamera *camera, const gchar *uuid)
-{
-    CheeseCameraPrivate *priv = cheese_camera_get_instance_private (camera);
-    guint i;
-
-  for (i = 0; i < priv->num_camera_devices; i++)
-  {
-    CheeseCameraDevice *device = g_ptr_array_index (priv->camera_devices, i);
-    if (strcmp (cheese_camera_device_get_uuid (device), uuid) == 0)
-    {
-      g_object_set (camera,
-                    "device-node", cheese_camera_device_get_uuid (device),
-                    NULL);
-      break;
-    }
-  }
+  g_object_set (camera, "device", device, NULL);
 }
 
 /**
  * cheese_camera_setup:
  * @camera: a #CheeseCamera
- * @uuid: (allow-none): UUID of the video capture device, or %NULL
+ * @device: (allow-none): the video capture device, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Setup a video capture device.
  */
 void
-cheese_camera_setup (CheeseCamera *camera, const gchar *uuid, GError **error)
+cheese_camera_setup (CheeseCamera *camera, CheeseCameraDevice *device, GError **error)
 {
   CheeseCameraPrivate *priv;
   GError  *tmp_error = NULL;
@@ -1575,9 +1540,9 @@ cheese_camera_setup (CheeseCamera *camera, const gchar *uuid, GError **error)
     return;
   }
 
-  if (uuid != NULL)
+  if (device != NULL)
   {
-    cheese_camera_set_device_by_dev_uuid (camera, uuid);
+    cheese_camera_set_device (camera, device);
   }
 
 
diff --git a/libcheese/cheese-camera.h b/libcheese/cheese-camera.h
index bbad2bd..cd69a9e 100644
--- a/libcheese/cheese-camera.h
+++ b/libcheese/cheese-camera.h
@@ -101,7 +101,7 @@ CheeseCamera *cheese_camera_new (ClutterTexture *video_texture,
                                  gint            y_resolution);
 
 const CheeseVideoFormat *cheese_camera_get_current_video_format (CheeseCamera *camera);
-void                     cheese_camera_setup (CheeseCamera *camera, const gchar *uuid, GError **error);
+void                     cheese_camera_setup (CheeseCamera *camera, CheeseCameraDevice *device, GError 
**error);
 void                     cheese_camera_play (CheeseCamera *camera);
 void                     cheese_camera_stop (CheeseCamera *camera);
 void                     cheese_camera_set_effect (CheeseCamera *camera, CheeseEffect *effect);
@@ -114,7 +114,7 @@ gboolean            cheese_camera_take_photo (CheeseCamera *camera, const gchar
 gboolean            cheese_camera_take_photo_pixbuf (CheeseCamera *camera);
 CheeseCameraDevice *cheese_camera_get_selected_device (CheeseCamera *camera);
 GPtrArray *         cheese_camera_get_camera_devices (CheeseCamera *camera);
-void                cheese_camera_set_device_by_device_node (CheeseCamera *camera, const gchar *file);
+void                cheese_camera_set_device (CheeseCamera *camera, CheeseCameraDevice *device);
 void                cheese_camera_switch_camera_device (CheeseCamera *camera);
 GList *             cheese_camera_get_video_formats (CheeseCamera *camera);
 void                cheese_camera_set_video_format (CheeseCamera      *camera,
diff --git a/src/cheese-preferences.vala b/src/cheese-preferences.vala
index 21b68f3..8a3eb7e 100644
--- a/src/cheese-preferences.vala
+++ b/src/cheese-preferences.vala
@@ -108,7 +108,7 @@ public PreferencesDialog (Cheese.Camera camera)
 
     devices.foreach(add_camera_device);
 
-    settings.set_string ("camera", camera.get_selected_device ().get_device_node ());
+    settings.set_string ("camera", camera.get_selected_device ().get_name ());
     setup_resolutions_for_device (camera.get_selected_device ());
   }
 
@@ -196,10 +196,10 @@ public PreferencesDialog (Cheese.Camera camera)
 
     combo.get_active_iter (out iter);
     combo.model.get (iter, 1, out dev);
-    camera.set_device_by_device_node (dev.get_device_node ());
+    camera.set_device (dev);
     camera.switch_camera_device ();
     setup_resolutions_for_device (camera.get_selected_device ());
-    settings.set_string ("camera", dev.get_device_node ());
+    settings.set_string ("camera", dev.get_name ());
   }
 
   /**
@@ -387,7 +387,7 @@ public PreferencesDialog (Cheese.Camera camera)
         camera_model.get (iter, 1, out new_device, -1);
 
         // Found the device that was removed.
-        if (strcmp (old_device.device_node, new_device.device_node) != 0)
+        if (old_device != new_device)
         {
             remove_camera_device (iter, new_device, active_device);
             device_removed = true;
@@ -406,7 +406,7 @@ public PreferencesDialog (Cheese.Camera camera)
       }
     }
 
-    settings.set_string ("camera", camera.get_selected_device ().get_device_node ());
+    settings.set_string ("camera", camera.get_selected_device ().get_name ());
     setup_resolutions_for_device (camera.get_selected_device ());
   }
 
@@ -425,10 +425,10 @@ public PreferencesDialog (Cheese.Camera camera)
 
     camera_model.append (out iter);
     camera_model.set (iter,
-                      0, dev.get_name () + " (" + dev.get_device_node () + ")",
+                      0, dev.get_name (),
                       1, dev);
 
-    if (camera.get_selected_device ().get_device_node () == dev.get_device_node ())
+    if (camera.get_selected_device () == dev)
         source_combo.set_active_iter (iter);
 
     if (camera_model.iter_n_children (null) > 1)
@@ -448,7 +448,7 @@ public PreferencesDialog (Cheese.Camera camera)
       unowned GLib.PtrArray devices = camera.get_camera_devices ();
 
       // Check if the camera that we want to remove, is the active one
-      if (strcmp (device_node.device_node, active_device_node.device_node) == 0)
+      if (device_node == active_device_node)
       {
         if (devices.len > 0)
           set_new_available_camera_device (iter);
diff --git a/src/vapi/cheese-common.vapi b/src/vapi/cheese-common.vapi
index a926725..702d701 100644
--- a/src/vapi/cheese-common.vapi
+++ b/src/vapi/cheese-common.vapi
@@ -43,8 +43,7 @@ namespace Cheese
     public bool                        has_camera ();
     public void                        play ();
     public void                        set_balance_property (string property, double value);
-    public void                        set_device_by_device_node (string file);
-    public void                        set_device_by_uuid (string uuid);
+    public void                        set_device (Cheese.CameraDevice device);
     public void                        set_effect (Cheese.Effect effect);
     public void                        toggle_effects_pipeline (bool active);
     public void                        connect_effect_texture (Cheese.Effect effect, Clutter.Texture 
texture);
@@ -77,17 +76,13 @@ namespace Cheese
     public CameraDevice (string uuid, string device_node, string name, int v4lapi_version) throws GLib.Error;
     public Cheese.VideoFormat get_best_format ();
     public Gst.Caps get_caps_for_format (Cheese.VideoFormat format);
-    public unowned string             get_device_node ();
     public GLib.List<unowned Cheese.VideoFormat> get_format_list ();
-    public unowned string             get_uuid ();
     public unowned string             get_name ();
-    public unowned string             get_src ();
+    public Gst.Element                get_src ();
     [NoAccessorMethod]
-    public uint v4l_api_version {get; construct;}
-    public string device_node {get; construct;}
+    public Gst.Device device {get; construct;}
     [NoAccessorMethod]
-    public string uuid {owned get; construct;}
-    public string name {get; construct;}
+    public string name {get;}
   }
 
   [CCode (cheader_filename = "cheese-camera-device-monitor.h")]
@@ -96,8 +91,8 @@ namespace Cheese
     [CCode (has_construct_function = false)]
     public CameraDeviceMonitor ();
     public void                coldplug ();
-    public virtual signal void added (string uuid, string device_file, string product_name, uint 
api_version);
-    public virtual signal void removed (string id);
+    public virtual signal void added (Gst.Device device);
+    public virtual signal void removed (Gst.Device device);
   }
 
 
diff --git a/tests/cheese-test-monitor.c b/tests/cheese-test-monitor.c
index 1afb871..e2b9917 100644
--- a/tests/cheese-test-monitor.c
+++ b/tests/cheese-test-monitor.c
@@ -10,16 +10,16 @@ added_cb (CheeseCameraDeviceMonitor *monitor,
          CheeseCameraDevice        *device,
          gpointer                   user_data)
 {
-  g_message ("Added new device with ID '%s'", cheese_camera_device_get_uuid (device));
+  g_message ("Added new device with name '%s'", cheese_camera_device_get_name (device));
   g_object_unref (device);
 }
 
 static void
 removed_cb (CheeseCameraDeviceMonitor *monitor,
-            const gchar               *uuid,
+            const gchar               *name,
             gpointer                   user_data)
 {
-  g_message ("Removed device with ID '%s'", uuid);
+  g_message ("Removed device with name '%s'", name);
 }
 
 int



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