device: Add "klass" to GstDevices
authorOlivier Crête <tester@tester.ca>
Sun, 16 Mar 2014 19:56:59 +0000 (15:56 -0400)
committerOlivier Crête <tester@tester.ca>
Sun, 16 Mar 2014 22:15:18 +0000 (18:15 -0400)
gst/gstdevice.c
gst/gstdevice.h
gst/gstglobaldevicemonitor.c

index 64f3925..6a7b506 100644 (file)
@@ -31,7 +31,8 @@
 enum
 {
   PROP_DISPLAY_NAME = 1,
-  PROP_CAPS
+  PROP_CAPS,
+  PROP_KLASS
 };
 
 enum
@@ -43,6 +44,7 @@ enum
 struct _GstDevicePrivate
 {
   GstCaps *caps;
+  gchar *klass;
   gchar *display_name;
 };
 
@@ -77,6 +79,10 @@ gst_device_class_init (GstDeviceClass * klass)
       g_param_spec_boxed ("caps", "Device Caps",
           "The possible caps of a device", GST_TYPE_CAPS,
           G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property (object_class, PROP_KLASS,
+      g_param_spec_string ("klass", "Device Class",
+          "The Class of the device", "",
+          G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
   signals[REMOVED] = g_signal_new ("removed", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
@@ -97,6 +103,7 @@ gst_device_finalize (GObject * object)
   gst_caps_replace (&device->priv->caps, NULL);
 
   g_free (device->priv->display_name);
+  g_free (device->priv->klass);
 
   G_OBJECT_CLASS (gst_device_parent_class)->finalize (object);
 }
@@ -117,6 +124,9 @@ gst_device_get_property (GObject * object, guint prop_id,
       if (gstdevice->priv->caps)
         g_value_take_boxed (value, gst_device_get_caps (gstdevice));
       break;
+    case PROP_KLASS:
+      g_value_take_string (value, gst_device_get_klass (gstdevice));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -139,6 +149,9 @@ gst_device_set_property (GObject * object, guint prop_id,
     case PROP_CAPS:
       gst_caps_replace (&gstdevice->priv->caps, g_value_get_boxed (value));
       break;
+    case PROP_KLASS:
+      gstdevice->priv->klass = g_value_dup_string (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -199,7 +212,26 @@ gst_device_get_caps (GstDevice * device)
 gchar *
 gst_device_get_display_name (GstDevice * device)
 {
-  return g_strdup (device->priv->display_name);
+  return
+      g_strdup (device->priv->display_name ? device->priv->display_name : "");
+}
+
+/**
+ * gst_device_get_klass:
+ * @device: a #GstDevice
+ *
+ * Gets the "class" of a device. This is a "/" separated list of
+ * classes that represent this device. They are a subset of the
+ * classes of the #GstDeviceMonitor that produced this device.
+ *
+ * Returns: The device class. Free with g_free() after use.
+ *
+ * Since: 1.4
+ */
+gchar *
+gst_device_get_klass (GstDevice * device)
+{
+  return g_strdup (device->priv->klass ? device->priv->klass : "");
 }
 
 /**
@@ -229,3 +261,70 @@ gst_device_reconfigure_element (GstDevice * device, GstElement * element)
   else
     return FALSE;
 }
+
+/**
+ * gst_device_has_classesv:
+ * @device: a #GstDevice
+ * @classes: a %NULL terminated array of klasses to match, only match if all
+ *  classes are matched
+ *
+ * Check if @factory matches all of the given classes
+ *
+ * Returns: %TRUE if @device matches.
+ *
+ * Since: 1.4
+ */
+gboolean
+gst_device_has_classesv (GstDevice * device, gchar ** classes)
+{
+  g_return_val_if_fail (GST_IS_DEVICE (device), FALSE);
+
+
+  for (; classes[0]; classes++) {
+    const gchar *found;
+    guint len;
+
+    if (classes[0] == '\0')
+      continue;
+
+    found = strstr (device->priv->klass, classes[0]);
+
+    if (!found)
+      return FALSE;
+    if (found != device->priv->klass && *(found - 1) != '/')
+      return FALSE;
+
+    len = strlen (classes[0]);
+    if (found[len] != 0 && found[len] != '/')
+      return FALSE;
+  }
+
+  return TRUE;
+}
+
+/**
+ * gst_device_has_classes:
+ * @device: a #GstDevice
+ * @classes: a "/" separate list of klasses to match, only match if all classes
+ *  are matched
+ *
+ * Check if @device matches all of the given classes
+ *
+ * Returns: %TRUE if @device matches.
+ *
+ * Since: 1.4
+ */
+gboolean
+gst_device_has_classes (GstDevice * device, const gchar * classes)
+{
+  gchar **classesv;
+  gboolean res;
+
+  classesv = g_strsplit (classes, "/", 0);
+
+  res = gst_device_has_classesv (device, classesv);
+
+  g_strfreev (classesv);
+
+  return res;
+}
index dc71eeb..9a5d9b3 100644 (file)
@@ -68,9 +68,17 @@ GstElement * gst_device_create_element (GstDevice * device, const gchar * name);
 
 GstCaps *    gst_device_get_caps (GstDevice * device);
 gchar *      gst_device_get_display_name (GstDevice * device);
+gchar *      gst_device_get_klass (GstDevice * device);
 gboolean     gst_device_reconfigure_element (GstDevice * device,
                                              GstElement * element);
 
+gboolean      gst_device_has_classesv (GstDevice * device,
+                                       gchar ** classes);
+
+gboolean      gst_device_has_classes (GstDevice * device,
+                                      const gchar * classes);
+
+
 G_END_DECLS
 
 #endif /* __GST_DEVICE_H__ */
index 974dc7f..cf53713 100644 (file)
@@ -64,7 +64,7 @@ bus_sync_message (GstBus * bus, GstMessage * message,
   GstMessageType type = GST_MESSAGE_TYPE (message);
 
   if (type == GST_MESSAGE_DEVICE_ADDED || type == GST_MESSAGE_DEVICE_REMOVED) {
-    gboolean intersects;
+    gboolean matches;
     GstCaps *caps;
     GstDevice *device;
 
@@ -75,11 +75,12 @@ bus_sync_message (GstBus * bus, GstMessage * message,
 
     GST_OBJECT_LOCK (monitor);
     caps = gst_device_get_caps (device);
-    intersects = gst_caps_can_intersect (monitor->priv->caps, caps);
+    matches = gst_caps_can_intersect (monitor->priv->caps, caps) &&
+        gst_device_has_classes (device, monitor->priv->classes);
     gst_caps_unref (caps);
     GST_OBJECT_UNLOCK (monitor);
 
-    if (intersects)
+    if (matches)
       gst_bus_post (monitor->priv->bus, gst_message_ref (message));
   }
 }
@@ -204,7 +205,8 @@ again:
       GstDevice *dev = GST_DEVICE (item->data);
       GstCaps *caps = gst_device_get_caps (dev);
 
-      if (gst_caps_can_intersect (self->priv->caps, caps))
+      if (gst_caps_can_intersect (self->priv->caps, caps) &&
+          gst_device_has_classes (dev, self->priv->classes))
         devices = g_list_prepend (devices, gst_object_ref (dev));
       gst_caps_unref (caps);
     }