device: Add "klass" to GstDevices

This commit is contained in:
Olivier Crête 2014-03-16 15:56:59 -04:00
parent b8078e2656
commit e743fac26b
3 changed files with 115 additions and 6 deletions

View 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;
}

View 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__ */

View 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);
}