static void gst_device_finalize (GObject * object) { GstDevice *device = GST_DEVICE (object); gst_caps_replace (&device->priv->caps, NULL); g_free (device->priv->display_name); g_free (device->priv->device_class); G_OBJECT_CLASS (gst_device_parent_class)->finalize (object); }
static void uevent_cb (GUdevClient * client, const gchar * action, GUdevDevice * device, GstV4l2DeviceProvider * self) { GstDeviceProvider *provider = GST_DEVICE_PROVIDER (self); /* Not V4L2, ignoring */ if (g_udev_device_get_property_as_int (device, "ID_V4L_VERSION") != 2) return; if (!strcmp (action, "add")) { GstDevice *gstdev = NULL; gstdev = gst_v4l2_device_provider_device_from_udev (self, device); if (gstdev) gst_device_provider_device_add (provider, gstdev); } else if (!strcmp (action, "remove")) { GstV4l2Device *gstdev = NULL; GList *item; GST_OBJECT_LOCK (self); for (item = provider->devices; item; item = item->next) { gstdev = item->data; if (!strcmp (gstdev->syspath, g_udev_device_get_sysfs_path (device))) { gst_object_ref (gstdev); break; } gstdev = NULL; } GST_OBJECT_UNLOCK (provider); if (gstdev) { gst_device_provider_device_remove (provider, GST_DEVICE (gstdev)); g_object_unref (gstdev); } } else { GST_WARNING ("Unhandled action %s", action); } }
GList * gst_device_monitor_get_devices (GstDeviceMonitor * monitor) { GList *devices = NULL, *hidden = NULL; guint i; guint cookie; g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), NULL); GST_OBJECT_LOCK (monitor); if (monitor->priv->filters->len == 0) { GST_OBJECT_UNLOCK (monitor); GST_WARNING_OBJECT (monitor, "No filters have been set"); return FALSE; } if (monitor->priv->providers->len == 0) { GST_OBJECT_UNLOCK (monitor); GST_WARNING_OBJECT (monitor, "No providers match the current filters"); return FALSE; } again: g_list_free_full (devices, gst_object_unref); g_list_free_full (hidden, g_free); devices = NULL; hidden = NULL; cookie = monitor->priv->cookie; for (i = 0; i < monitor->priv->providers->len; i++) { GList *tmpdev; GstDeviceProvider *provider = gst_object_ref (g_ptr_array_index (monitor->priv->providers, i)); GList *item; if (!is_provider_hidden (monitor, hidden, provider)) { GST_OBJECT_UNLOCK (monitor); tmpdev = gst_device_provider_get_devices (provider); GST_OBJECT_LOCK (monitor); update_hidden_providers_list (&hidden, provider); } else { tmpdev = NULL; } for (item = tmpdev; item; item = item->next) { GstDevice *dev = GST_DEVICE (item->data); GstCaps *caps = gst_device_get_caps (dev); guint j; for (j = 0; j < monitor->priv->filters->len; j++) { struct DeviceFilter *filter = g_ptr_array_index (monitor->priv->filters, j); if (gst_caps_can_intersect (filter->caps, caps) && gst_device_has_classesv (dev, filter->classesv)) { devices = g_list_prepend (devices, gst_object_ref (dev)); break; } } gst_caps_unref (caps); } g_list_free_full (tmpdev, gst_object_unref); gst_object_unref (provider); if (monitor->priv->cookie != cookie) goto again; } g_list_free_full (hidden, g_free); GST_OBJECT_UNLOCK (monitor); return g_list_reverse (devices); }
static GstDevice * gst_v4l2_device_provider_device_from_udev (GstV4l2DeviceProvider * provider, GUdevDevice * udev_device) { GstV4l2Device *gstdev; const gchar *device_path = g_udev_device_get_device_file (udev_device); const gchar *device_name, *str; GstStructure *props; props = gst_structure_new ("v4l2deviceprovider", "udev-probed", G_TYPE_BOOLEAN, TRUE, NULL); str = g_udev_device_get_property (udev_device, "ID_PATH"); if (!(str && *str)) { str = g_udev_device_get_sysfs_path (udev_device); } if (str && *str) gst_structure_set (props, "device.bus_path", G_TYPE_STRING, str, NULL); if ((str = g_udev_device_get_sysfs_path (udev_device)) && *str) gst_structure_set (props, "sysfs.path", G_TYPE_STRING, str, NULL); if ((str = g_udev_device_get_property (udev_device, "ID_ID")) && *str) gst_structure_set (props, "udev.id", G_TYPE_STRING, str, NULL); if ((str = g_udev_device_get_property (udev_device, "ID_BUS")) && *str) gst_structure_set (props, "device.bus", G_TYPE_STRING, str, NULL); if ((str = g_udev_device_get_property (udev_device, "SUBSYSTEM")) && *str) gst_structure_set (props, "device.subsystem", G_TYPE_STRING, str, NULL); if ((str = g_udev_device_get_property (udev_device, "ID_VENDOR_ID")) && *str) gst_structure_set (props, "device.vendor.id", G_TYPE_STRING, str, NULL); str = g_udev_device_get_property (udev_device, "ID_VENDOR_FROM_DATABASE"); if (!(str && *str)) { str = g_udev_device_get_property (udev_device, "ID_VENDOR_ENC"); if (!(str && *str)) { str = g_udev_device_get_property (udev_device, "ID_VENDOR"); } } if (str && *str) gst_structure_set (props, "device.vendor.name", G_TYPE_STRING, str, NULL); if ((str = g_udev_device_get_property (udev_device, "ID_MODEL_ID")) && *str) gst_structure_set (props, "device.product.id", G_TYPE_STRING, str, NULL); device_name = g_udev_device_get_property (udev_device, "ID_V4L_PRODUCT"); if (!(device_name && *device_name)) { device_name = g_udev_device_get_property (udev_device, "ID_MODEL_FROM_DATABASE"); if (!(device_name && *device_name)) { device_name = g_udev_device_get_property (udev_device, "ID_MODEL_ENC"); if (!(device_name && *device_name)) { device_name = g_udev_device_get_property (udev_device, "ID_MODEL"); } } } if (device_name && *device_name) gst_structure_set (props, "device.product.name", G_TYPE_STRING, device_name, NULL); if ((str = g_udev_device_get_property (udev_device, "ID_SERIAL")) && *str) gst_structure_set (props, "device.serial", G_TYPE_STRING, str, NULL); if ((str = g_udev_device_get_property (udev_device, "ID_V4L_CAPABILITIES")) && *str) gst_structure_set (props, "device.capabilities", G_TYPE_STRING, str, NULL); gstdev = gst_v4l2_device_provider_probe_device (provider, device_path, device_name, props); if (gstdev) gstdev->syspath = g_strdup (g_udev_device_get_sysfs_path (udev_device)); return GST_DEVICE (gstdev); }