gboolean gst_device_monitor_start (GstDeviceMonitor * monitor) { guint i; g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), FALSE); GST_OBJECT_LOCK (monitor); if (monitor->priv->filters->len == 0) { GST_OBJECT_UNLOCK (monitor); GST_WARNING_OBJECT (monitor, "No filters have been set, will expose all " "devices found"); gst_device_monitor_add_filter (monitor, NULL, NULL); GST_OBJECT_LOCK (monitor); } if (monitor->priv->providers->len == 0) { GST_OBJECT_UNLOCK (monitor); GST_WARNING_OBJECT (monitor, "No providers match the current filters"); return FALSE; } gst_bus_set_flushing (monitor->priv->bus, FALSE); for (i = 0; i < monitor->priv->providers->len; i++) { GstDeviceProvider *provider = g_ptr_array_index (monitor->priv->providers, i); if (gst_device_provider_can_monitor (provider)) { if (!gst_device_provider_start (provider)) { gst_bus_set_flushing (monitor->priv->bus, TRUE); for (; i != 0; i--) gst_device_provider_stop (g_ptr_array_index (monitor->priv->providers, i - 1)); GST_OBJECT_UNLOCK (monitor); return FALSE; } } } monitor->priv->started = TRUE; GST_OBJECT_UNLOCK (monitor); return TRUE; }
gboolean gst_device_monitor_start (GstDeviceMonitor * monitor) { guint cookie, i; GList *pending = NULL, *started = NULL, *removed = NULL; g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), FALSE); GST_OBJECT_LOCK (monitor); if (monitor->priv->filters->len == 0) { GST_OBJECT_UNLOCK (monitor); GST_WARNING_OBJECT (monitor, "No filters have been set, will expose all " "devices found"); gst_device_monitor_add_filter (monitor, NULL, NULL); GST_OBJECT_LOCK (monitor); } if (monitor->priv->providers->len == 0) { GST_OBJECT_UNLOCK (monitor); GST_WARNING_OBJECT (monitor, "No providers match the current filters"); return FALSE; } gst_bus_set_flushing (monitor->priv->bus, FALSE); again: cookie = monitor->priv->cookie; g_list_free_full (pending, gst_object_unref); pending = NULL; removed = started; started = NULL; for (i = 0; i < monitor->priv->providers->len; i++) { GstDeviceProvider *provider; GList *find; provider = g_ptr_array_index (monitor->priv->providers, i); find = g_list_find (removed, provider); if (find) { /* this was already started, move to started list */ removed = g_list_remove_link (removed, find); started = g_list_concat (started, find); } else { /* not started, add to pending list */ pending = g_list_append (pending, gst_object_ref (provider)); } } g_list_free_full (removed, gst_object_unref); removed = NULL; while (pending) { GstDeviceProvider *provider = pending->data; if (gst_device_provider_can_monitor (provider)) { GST_OBJECT_UNLOCK (monitor); if (!gst_device_provider_start (provider)) goto start_failed; GST_OBJECT_LOCK (monitor); } started = g_list_prepend (started, provider); pending = g_list_delete_link (pending, pending); if (monitor->priv->cookie != cookie) goto again; } monitor->priv->started = TRUE; GST_OBJECT_UNLOCK (monitor); g_list_free_full (started, gst_object_unref); return TRUE; start_failed: { GST_OBJECT_LOCK (monitor); gst_bus_set_flushing (monitor->priv->bus, TRUE); GST_OBJECT_UNLOCK (monitor); while (started) { GstDeviceProvider *provider = started->data; gst_device_provider_stop (provider); gst_object_unref (provider); started = g_list_delete_link (started, started); } return FALSE; } }