Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 1 | /* GStreamer |
| 2 | * Copyright (C) 2013 Olivier Crete <olivier.crete@collabora.com> |
| 3 | * |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 4 | * gstdevicemonitor.c: device monitor |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 5 | * |
| 6 | * This library is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU Library General Public |
| 8 | * License as published by the Free Software Foundation; either |
| 9 | * version 2 of the License, or (at your option) any later version. |
| 10 | * |
| 11 | * This library is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 14 | * Library General Public License for more details. |
| 15 | * |
| 16 | * You should have received a copy of the GNU Library General Public |
| 17 | * License along with this library; if not, write to the |
| 18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
| 19 | * Boston, MA 02111-1307, USA. |
| 20 | */ |
Olivier Crête | 77db6bf | 2014-06-20 16:55:06 -0400 | [diff] [blame] | 21 | |
| 22 | /** |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 23 | * SECTION:gstdevicemonitor |
Thibault Saunier | a87b455 | 2017-01-16 11:26:16 -0300 | [diff] [blame] | 24 | * @title: GstDeviceMonitor |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 25 | * @short_description: A device monitor and prober |
Olivier Crête | 7992174 | 2014-06-26 14:28:09 -0400 | [diff] [blame] | 26 | * @see_also: #GstDevice, #GstDeviceProvider |
Olivier Crête | 77db6bf | 2014-06-20 16:55:06 -0400 | [diff] [blame] | 27 | * |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 28 | * Applications should create a #GstDeviceMonitor when they want |
Olivier Crête | 77db6bf | 2014-06-20 16:55:06 -0400 | [diff] [blame] | 29 | * to probe, list and monitor devices of a specific type. The |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 30 | * #GstDeviceMonitor will create the appropriate |
Olivier Crête | 7992174 | 2014-06-26 14:28:09 -0400 | [diff] [blame] | 31 | * #GstDeviceProvider objects and manage them. It will then post |
Olivier Crête | 77db6bf | 2014-06-20 16:55:06 -0400 | [diff] [blame] | 32 | * messages on its #GstBus for devices that have been added and |
| 33 | * removed. |
| 34 | * |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 35 | * The device monitor will monitor all devices matching the filters that |
| 36 | * the application has set. |
| 37 | * |
Tim-Philipp Müller | 0e0e78e | 2014-06-27 10:44:32 +0100 | [diff] [blame] | 38 | * The basic use pattern of a device monitor is as follows: |
Olivier Crête | 67440ce | 2014-06-26 17:22:25 -0400 | [diff] [blame] | 39 | * |[ |
| 40 | * static gboolean |
| 41 | * my_bus_func (GstBus * bus, GstMessage * message, gpointer user_data) |
| 42 | * { |
| 43 | * GstDevice *device; |
Tim-Philipp Müller | c06d9f7 | 2014-09-03 17:38:16 +0100 | [diff] [blame] | 44 | * gchar *name; |
Olivier Crête | 67440ce | 2014-06-26 17:22:25 -0400 | [diff] [blame] | 45 | * |
| 46 | * switch (GST_MESSAGE_TYPE (message)) { |
| 47 | * case GST_MESSAGE_DEVICE_ADDED: |
| 48 | * gst_message_parse_device_added (message, &device); |
| 49 | * name = gst_device_get_display_name (device); |
| 50 | * g_print("Device added: %s\n", name); |
| 51 | * g_free (name); |
Guillaume Desmottes | 514beb7 | 2016-07-13 15:43:21 +0200 | [diff] [blame] | 52 | * gst_object_unref (device); |
Olivier Crête | 67440ce | 2014-06-26 17:22:25 -0400 | [diff] [blame] | 53 | * break; |
| 54 | * case GST_MESSAGE_DEVICE_REMOVED: |
| 55 | * gst_message_parse_device_removed (message, &device); |
| 56 | * name = gst_device_get_display_name (device); |
| 57 | * g_print("Device removed: %s\n", name); |
| 58 | * g_free (name); |
Guillaume Desmottes | 514beb7 | 2016-07-13 15:43:21 +0200 | [diff] [blame] | 59 | * gst_object_unref (device); |
Olivier Crête | 67440ce | 2014-06-26 17:22:25 -0400 | [diff] [blame] | 60 | * break; |
| 61 | * default: |
| 62 | * break; |
| 63 | * } |
| 64 | * |
| 65 | * return G_SOURCE_CONTINUE; |
| 66 | * } |
| 67 | * |
| 68 | * GstDeviceMonitor * |
| 69 | * setup_raw_video_source_device_monitor (void) { |
| 70 | * GstDeviceMonitor *monitor; |
| 71 | * GstBus *bus; |
| 72 | * GstCaps *caps; |
| 73 | * |
| 74 | * monitor = gst_device_monitor_new (); |
| 75 | * |
| 76 | * bus = gst_device_monitor_get_bus (monitor); |
| 77 | * gst_bus_add_watch (bus, my_bus_func, NULL); |
| 78 | * gst_object_unref (bus); |
| 79 | * |
Tim-Philipp Müller | c06d9f7 | 2014-09-03 17:38:16 +0100 | [diff] [blame] | 80 | * caps = gst_caps_new_empty_simple ("video/x-raw"); |
Olivier Crête | 67440ce | 2014-06-26 17:22:25 -0400 | [diff] [blame] | 81 | * gst_device_monitor_add_filter (monitor, "Video/Source", caps); |
| 82 | * gst_caps_unref (caps); |
| 83 | * |
| 84 | * gst_device_monitor_start (monitor); |
| 85 | * |
| 86 | * return monitor; |
| 87 | * } |
| 88 | * ]| |
| 89 | * |
Olivier Crête | 77db6bf | 2014-06-20 16:55:06 -0400 | [diff] [blame] | 90 | * Since: 1.4 |
| 91 | */ |
| 92 | |
| 93 | |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 94 | #ifdef HAVE_CONFIG_H |
| 95 | #include "config.h" |
| 96 | #endif |
| 97 | |
Edward Hervey | fb9ca6f | 2014-03-17 09:51:45 +0100 | [diff] [blame] | 98 | #include "gst_private.h" |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 99 | #include "gstdevicemonitor.h" |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 100 | |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 101 | struct _GstDeviceMonitorPrivate |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 102 | { |
| 103 | gboolean started; |
| 104 | |
| 105 | GstBus *bus; |
| 106 | |
Olivier Crête | 7992174 | 2014-06-26 14:28:09 -0400 | [diff] [blame] | 107 | GPtrArray *providers; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 108 | guint cookie; |
| 109 | |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 110 | GPtrArray *filters; |
| 111 | |
| 112 | guint last_id; |
Wim Taymans | 5a7b7e6 | 2015-07-16 18:56:00 +0200 | [diff] [blame] | 113 | GList *hidden; |
| 114 | gboolean show_all; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 115 | }; |
| 116 | |
Wim Taymans | 5a7b7e6 | 2015-07-16 18:56:00 +0200 | [diff] [blame] | 117 | #define DEFAULT_SHOW_ALL FALSE |
| 118 | |
| 119 | enum |
| 120 | { |
| 121 | PROP_SHOW_ALL = 1, |
| 122 | }; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 123 | |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 124 | G_DEFINE_TYPE (GstDeviceMonitor, gst_device_monitor, GST_TYPE_OBJECT); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 125 | |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 126 | static void gst_device_monitor_dispose (GObject * object); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 127 | |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 128 | struct DeviceFilter |
| 129 | { |
| 130 | guint id; |
| 131 | |
| 132 | gchar **classesv; |
| 133 | GstCaps *caps; |
| 134 | }; |
| 135 | |
| 136 | static void |
| 137 | device_filter_free (struct DeviceFilter *filter) |
| 138 | { |
| 139 | g_strfreev (filter->classesv); |
| 140 | gst_caps_unref (filter->caps); |
| 141 | |
| 142 | g_slice_free (struct DeviceFilter, filter); |
| 143 | } |
| 144 | |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 145 | static void |
Wim Taymans | 5a7b7e6 | 2015-07-16 18:56:00 +0200 | [diff] [blame] | 146 | gst_device_monitor_get_property (GObject * object, guint prop_id, |
| 147 | GValue * value, GParamSpec * pspec) |
| 148 | { |
| 149 | GstDeviceMonitor *monitor = GST_DEVICE_MONITOR (object); |
| 150 | |
| 151 | switch (prop_id) { |
| 152 | case PROP_SHOW_ALL: |
| 153 | g_value_set_boolean (value, |
| 154 | gst_device_monitor_get_show_all_devices (monitor)); |
| 155 | break; |
| 156 | default: |
| 157 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
| 158 | break; |
| 159 | } |
| 160 | } |
| 161 | |
| 162 | static void |
| 163 | gst_device_monitor_set_property (GObject * object, guint prop_id, |
| 164 | const GValue * value, GParamSpec * pspec) |
| 165 | { |
| 166 | GstDeviceMonitor *monitor = GST_DEVICE_MONITOR (object); |
| 167 | |
| 168 | switch (prop_id) { |
| 169 | case PROP_SHOW_ALL: |
| 170 | gst_device_monitor_set_show_all_devices (monitor, |
| 171 | g_value_get_boolean (value)); |
| 172 | break; |
| 173 | default: |
| 174 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
| 175 | break; |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | |
| 180 | static void |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 181 | gst_device_monitor_class_init (GstDeviceMonitorClass * klass) |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 182 | { |
| 183 | GObjectClass *object_class = G_OBJECT_CLASS (klass); |
| 184 | |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 185 | g_type_class_add_private (klass, sizeof (GstDeviceMonitorPrivate)); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 186 | |
Wim Taymans | 5a7b7e6 | 2015-07-16 18:56:00 +0200 | [diff] [blame] | 187 | object_class->get_property = gst_device_monitor_get_property; |
| 188 | object_class->set_property = gst_device_monitor_set_property; |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 189 | object_class->dispose = gst_device_monitor_dispose; |
Wim Taymans | 5a7b7e6 | 2015-07-16 18:56:00 +0200 | [diff] [blame] | 190 | |
| 191 | g_object_class_install_property (object_class, PROP_SHOW_ALL, |
| 192 | g_param_spec_boolean ("show-all", "Show All", |
| 193 | "Show all devices, even those from hidden providers", |
| 194 | DEFAULT_SHOW_ALL, G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE)); |
| 195 | } |
| 196 | |
| 197 | /* must be called with monitor lock */ |
| 198 | static gboolean |
| 199 | is_provider_hidden (GstDeviceMonitor * monitor, GList * hidden, |
| 200 | GstDeviceProvider * provider) |
| 201 | { |
| 202 | GstDeviceProviderFactory *factory; |
| 203 | |
| 204 | if (monitor->priv->show_all) |
| 205 | return FALSE; |
| 206 | |
| 207 | factory = gst_device_provider_get_factory (provider); |
| 208 | if (g_list_find_custom (hidden, GST_OBJECT_NAME (factory), |
| 209 | (GCompareFunc) g_strcmp0)) |
| 210 | return TRUE; |
| 211 | |
| 212 | return FALSE; |
| 213 | } |
| 214 | |
| 215 | /* must be called with monitor lock */ |
| 216 | static void |
| 217 | update_hidden_providers_list (GList ** hidden, GstDeviceProvider * provider) |
| 218 | { |
| 219 | gchar **obs; |
| 220 | |
| 221 | obs = gst_device_provider_get_hidden_providers (provider); |
| 222 | if (obs) { |
| 223 | gint i; |
| 224 | |
| 225 | for (i = 0; obs[i]; i++) |
| 226 | *hidden = g_list_prepend (*hidden, obs[i]); |
| 227 | |
| 228 | g_free (obs); |
| 229 | } |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 230 | } |
| 231 | |
| 232 | static void |
| 233 | bus_sync_message (GstBus * bus, GstMessage * message, |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 234 | GstDeviceMonitor * monitor) |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 235 | { |
Tim-Philipp Müller | 06ef8cd | 2014-03-16 15:19:49 +0000 | [diff] [blame] | 236 | GstMessageType type = GST_MESSAGE_TYPE (message); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 237 | |
Tim-Philipp Müller | 06ef8cd | 2014-03-16 15:19:49 +0000 | [diff] [blame] | 238 | if (type == GST_MESSAGE_DEVICE_ADDED || type == GST_MESSAGE_DEVICE_REMOVED) { |
Jan Alexander Steffens (heftig) | d9b2049 | 2017-11-06 20:23:12 +0100 | [diff] [blame] | 239 | gboolean matches = TRUE; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 240 | GstDevice *device; |
Wim Taymans | 5a7b7e6 | 2015-07-16 18:56:00 +0200 | [diff] [blame] | 241 | GstDeviceProvider *provider; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 242 | |
Tim-Philipp Müller | 06ef8cd | 2014-03-16 15:19:49 +0000 | [diff] [blame] | 243 | if (type == GST_MESSAGE_DEVICE_ADDED) |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 244 | gst_message_parse_device_added (message, &device); |
| 245 | else |
| 246 | gst_message_parse_device_removed (message, &device); |
| 247 | |
| 248 | GST_OBJECT_LOCK (monitor); |
Wim Taymans | 5a7b7e6 | 2015-07-16 18:56:00 +0200 | [diff] [blame] | 249 | provider = |
| 250 | GST_DEVICE_PROVIDER (gst_object_get_parent (GST_OBJECT (device))); |
| 251 | if (is_provider_hidden (monitor, monitor->priv->hidden, provider)) { |
| 252 | matches = FALSE; |
Jan Alexander Steffens (heftig) | d9b2049 | 2017-11-06 20:23:12 +0100 | [diff] [blame] | 253 | } else { |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 254 | guint i; |
| 255 | |
| 256 | for (i = 0; i < monitor->priv->filters->len; i++) { |
| 257 | struct DeviceFilter *filter = |
| 258 | g_ptr_array_index (monitor->priv->filters, i); |
| 259 | GstCaps *caps; |
| 260 | |
| 261 | caps = gst_device_get_caps (device); |
| 262 | matches = gst_caps_can_intersect (filter->caps, caps) && |
| 263 | gst_device_has_classesv (device, filter->classesv); |
| 264 | gst_caps_unref (caps); |
| 265 | if (matches) |
| 266 | break; |
| 267 | } |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 268 | } |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 269 | GST_OBJECT_UNLOCK (monitor); |
| 270 | |
Wim Taymans | ffa90b2 | 2015-08-08 17:59:51 +0200 | [diff] [blame] | 271 | gst_object_unref (provider); |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 272 | gst_object_unref (device); |
| 273 | |
Olivier Crête | e743fac | 2014-03-16 15:56:59 -0400 | [diff] [blame] | 274 | if (matches) |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 275 | gst_bus_post (monitor->priv->bus, gst_message_ref (message)); |
| 276 | } |
| 277 | } |
| 278 | |
| 279 | |
| 280 | static void |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 281 | gst_device_monitor_init (GstDeviceMonitor * self) |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 282 | { |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 283 | self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 284 | GST_TYPE_DEVICE_MONITOR, GstDeviceMonitorPrivate); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 285 | |
Wim Taymans | 5a7b7e6 | 2015-07-16 18:56:00 +0200 | [diff] [blame] | 286 | self->priv->show_all = DEFAULT_SHOW_ALL; |
| 287 | |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 288 | self->priv->bus = gst_bus_new (); |
| 289 | gst_bus_set_flushing (self->priv->bus, TRUE); |
| 290 | |
Olivier Crête | 7992174 | 2014-06-26 14:28:09 -0400 | [diff] [blame] | 291 | self->priv->providers = g_ptr_array_new (); |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 292 | self->priv->filters = g_ptr_array_new_with_free_func ( |
| 293 | (GDestroyNotify) device_filter_free); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 294 | |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 295 | self->priv->last_id = 1; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 296 | } |
| 297 | |
| 298 | |
| 299 | static void |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 300 | gst_device_monitor_remove (GstDeviceMonitor * self, guint i) |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 301 | { |
Olivier Crête | 7992174 | 2014-06-26 14:28:09 -0400 | [diff] [blame] | 302 | GstDeviceProvider *provider = g_ptr_array_index (self->priv->providers, i); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 303 | GstBus *bus; |
| 304 | |
Wim Taymans | 8caf9b7 | 2015-07-16 17:25:24 +0200 | [diff] [blame] | 305 | g_ptr_array_remove_index (self->priv->providers, i); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 306 | |
Olivier Crête | 7992174 | 2014-06-26 14:28:09 -0400 | [diff] [blame] | 307 | bus = gst_device_provider_get_bus (provider); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 308 | g_signal_handlers_disconnect_by_func (bus, bus_sync_message, self); |
| 309 | gst_object_unref (bus); |
| 310 | |
Olivier Crête | 7992174 | 2014-06-26 14:28:09 -0400 | [diff] [blame] | 311 | gst_object_unref (provider); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 312 | } |
| 313 | |
| 314 | static void |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 315 | gst_device_monitor_dispose (GObject * object) |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 316 | { |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 317 | GstDeviceMonitor *self = GST_DEVICE_MONITOR (object); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 318 | |
Sebastian Dröge | 154eefe | 2014-11-28 14:17:54 +0100 | [diff] [blame] | 319 | g_return_if_fail (!self->priv->started); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 320 | |
Olivier Crête | 7992174 | 2014-06-26 14:28:09 -0400 | [diff] [blame] | 321 | if (self->priv->providers) { |
| 322 | while (self->priv->providers->len) |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 323 | gst_device_monitor_remove (self, self->priv->providers->len - 1); |
Olivier Crête | 7992174 | 2014-06-26 14:28:09 -0400 | [diff] [blame] | 324 | g_ptr_array_unref (self->priv->providers); |
| 325 | self->priv->providers = NULL; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 326 | } |
| 327 | |
Guillaume Desmottes | 6881084 | 2014-06-30 08:59:18 +0000 | [diff] [blame] | 328 | if (self->priv->filters) { |
| 329 | g_ptr_array_unref (self->priv->filters); |
| 330 | self->priv->filters = NULL; |
| 331 | } |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 332 | |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 333 | gst_object_replace ((GstObject **) & self->priv->bus, NULL); |
| 334 | |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 335 | G_OBJECT_CLASS (gst_device_monitor_parent_class)->dispose (object); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 336 | } |
| 337 | |
| 338 | /** |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 339 | * gst_device_monitor_get_devices: |
Olivier Crête | 7992174 | 2014-06-26 14:28:09 -0400 | [diff] [blame] | 340 | * @monitor: A #GstDeviceProvider |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 341 | * |
| 342 | * Gets a list of devices from all of the relevant monitors. This may actually |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 343 | * probe the hardware if the monitor is not currently started. |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 344 | * |
Arun Raghavan | b502838 | 2017-10-22 18:05:30 +0530 | [diff] [blame] | 345 | * Returns: (transfer full) (element-type GstDevice) (nullable): a #GList of |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 346 | * #GstDevice |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 347 | * |
| 348 | * Since: 1.4 |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 349 | */ |
| 350 | |
| 351 | GList * |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 352 | gst_device_monitor_get_devices (GstDeviceMonitor * monitor) |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 353 | { |
Wim Taymans | 5a7b7e6 | 2015-07-16 18:56:00 +0200 | [diff] [blame] | 354 | GList *devices = NULL, *hidden = NULL; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 355 | guint i; |
| 356 | guint cookie; |
| 357 | |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 358 | g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), NULL); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 359 | |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 360 | GST_OBJECT_LOCK (monitor); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 361 | |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 362 | if (monitor->priv->filters->len == 0) { |
| 363 | GST_OBJECT_UNLOCK (monitor); |
| 364 | GST_WARNING_OBJECT (monitor, "No filters have been set"); |
Arun Raghavan | 41a59cd | 2017-05-27 05:19:20 +0530 | [diff] [blame] | 365 | return NULL; |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 366 | } |
| 367 | |
| 368 | if (monitor->priv->providers->len == 0) { |
| 369 | GST_OBJECT_UNLOCK (monitor); |
| 370 | GST_WARNING_OBJECT (monitor, "No providers match the current filters"); |
Arun Raghavan | 41a59cd | 2017-05-27 05:19:20 +0530 | [diff] [blame] | 371 | return NULL; |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 372 | } |
| 373 | |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 374 | again: |
| 375 | |
| 376 | g_list_free_full (devices, gst_object_unref); |
Wim Taymans | 5a7b7e6 | 2015-07-16 18:56:00 +0200 | [diff] [blame] | 377 | g_list_free_full (hidden, g_free); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 378 | devices = NULL; |
Wim Taymans | 5a7b7e6 | 2015-07-16 18:56:00 +0200 | [diff] [blame] | 379 | hidden = NULL; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 380 | |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 381 | cookie = monitor->priv->cookie; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 382 | |
Olivier Crête | 7992174 | 2014-06-26 14:28:09 -0400 | [diff] [blame] | 383 | for (i = 0; i < monitor->priv->providers->len; i++) { |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 384 | GList *tmpdev; |
Olivier Crête | 7992174 | 2014-06-26 14:28:09 -0400 | [diff] [blame] | 385 | GstDeviceProvider *provider = |
| 386 | gst_object_ref (g_ptr_array_index (monitor->priv->providers, i)); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 387 | GList *item; |
| 388 | |
Wim Taymans | 5a7b7e6 | 2015-07-16 18:56:00 +0200 | [diff] [blame] | 389 | if (!is_provider_hidden (monitor, hidden, provider)) { |
| 390 | GST_OBJECT_UNLOCK (monitor); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 391 | |
Wim Taymans | 5a7b7e6 | 2015-07-16 18:56:00 +0200 | [diff] [blame] | 392 | tmpdev = gst_device_provider_get_devices (provider); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 393 | |
Wim Taymans | 5a7b7e6 | 2015-07-16 18:56:00 +0200 | [diff] [blame] | 394 | GST_OBJECT_LOCK (monitor); |
| 395 | update_hidden_providers_list (&hidden, provider); |
| 396 | } else { |
| 397 | tmpdev = NULL; |
| 398 | } |
| 399 | |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 400 | |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 401 | for (item = tmpdev; item; item = item->next) { |
| 402 | GstDevice *dev = GST_DEVICE (item->data); |
| 403 | GstCaps *caps = gst_device_get_caps (dev); |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 404 | guint j; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 405 | |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 406 | for (j = 0; j < monitor->priv->filters->len; j++) { |
| 407 | struct DeviceFilter *filter = |
| 408 | g_ptr_array_index (monitor->priv->filters, j); |
Wim Taymans | 5a7b7e6 | 2015-07-16 18:56:00 +0200 | [diff] [blame] | 409 | |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 410 | if (gst_caps_can_intersect (filter->caps, caps) && |
| 411 | gst_device_has_classesv (dev, filter->classesv)) { |
| 412 | devices = g_list_prepend (devices, gst_object_ref (dev)); |
| 413 | break; |
| 414 | } |
| 415 | } |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 416 | gst_caps_unref (caps); |
| 417 | } |
| 418 | |
| 419 | g_list_free_full (tmpdev, gst_object_unref); |
Olivier Crête | 7992174 | 2014-06-26 14:28:09 -0400 | [diff] [blame] | 420 | gst_object_unref (provider); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 421 | |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 422 | if (monitor->priv->cookie != cookie) |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 423 | goto again; |
| 424 | } |
Wim Taymans | 5a7b7e6 | 2015-07-16 18:56:00 +0200 | [diff] [blame] | 425 | g_list_free_full (hidden, g_free); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 426 | |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 427 | GST_OBJECT_UNLOCK (monitor); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 428 | |
Wim Taymans | 8caf9b7 | 2015-07-16 17:25:24 +0200 | [diff] [blame] | 429 | return g_list_reverse (devices); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 430 | } |
| 431 | |
| 432 | /** |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 433 | * gst_device_monitor_start: |
| 434 | * @monitor: A #GstDeviceMonitor |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 435 | * |
| 436 | * Starts monitoring the devices, one this has succeeded, the |
Olivier Crête | 77db6bf | 2014-06-20 16:55:06 -0400 | [diff] [blame] | 437 | * %GST_MESSAGE_DEVICE_ADDED and %GST_MESSAGE_DEVICE_REMOVED messages |
| 438 | * will be emitted on the bus when the list of devices changes. |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 439 | * |
| 440 | * Returns: %TRUE if the device monitoring could be started |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 441 | * |
| 442 | * Since: 1.4 |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 443 | */ |
| 444 | |
| 445 | gboolean |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 446 | gst_device_monitor_start (GstDeviceMonitor * monitor) |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 447 | { |
Wim Taymans | eedd9cb | 2015-07-16 18:47:20 +0200 | [diff] [blame] | 448 | guint cookie, i; |
| 449 | GList *pending = NULL, *started = NULL, *removed = NULL; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 450 | |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 451 | g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), FALSE); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 452 | |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 453 | GST_OBJECT_LOCK (monitor); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 454 | |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 455 | if (monitor->priv->filters->len == 0) { |
| 456 | GST_OBJECT_UNLOCK (monitor); |
Tim-Philipp Müller | 0e0e78e | 2014-06-27 10:44:32 +0100 | [diff] [blame] | 457 | GST_WARNING_OBJECT (monitor, "No filters have been set, will expose all " |
| 458 | "devices found"); |
| 459 | gst_device_monitor_add_filter (monitor, NULL, NULL); |
| 460 | GST_OBJECT_LOCK (monitor); |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 461 | } |
| 462 | |
Olivier Crête | 7992174 | 2014-06-26 14:28:09 -0400 | [diff] [blame] | 463 | if (monitor->priv->providers->len == 0) { |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 464 | GST_OBJECT_UNLOCK (monitor); |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 465 | GST_WARNING_OBJECT (monitor, "No providers match the current filters"); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 466 | return FALSE; |
| 467 | } |
| 468 | |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 469 | gst_bus_set_flushing (monitor->priv->bus, FALSE); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 470 | |
Wim Taymans | eedd9cb | 2015-07-16 18:47:20 +0200 | [diff] [blame] | 471 | again: |
| 472 | cookie = monitor->priv->cookie; |
| 473 | |
| 474 | g_list_free_full (pending, gst_object_unref); |
| 475 | pending = NULL; |
| 476 | removed = started; |
| 477 | started = NULL; |
| 478 | |
Olivier Crête | 7992174 | 2014-06-26 14:28:09 -0400 | [diff] [blame] | 479 | for (i = 0; i < monitor->priv->providers->len; i++) { |
Wim Taymans | eedd9cb | 2015-07-16 18:47:20 +0200 | [diff] [blame] | 480 | GstDeviceProvider *provider; |
| 481 | GList *find; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 482 | |
Wim Taymans | eedd9cb | 2015-07-16 18:47:20 +0200 | [diff] [blame] | 483 | provider = g_ptr_array_index (monitor->priv->providers, i); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 484 | |
Wim Taymans | eedd9cb | 2015-07-16 18:47:20 +0200 | [diff] [blame] | 485 | find = g_list_find (removed, provider); |
| 486 | if (find) { |
| 487 | /* this was already started, move to started list */ |
| 488 | removed = g_list_remove_link (removed, find); |
| 489 | started = g_list_concat (started, find); |
| 490 | } else { |
| 491 | /* not started, add to pending list */ |
| 492 | pending = g_list_append (pending, gst_object_ref (provider)); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 493 | } |
| 494 | } |
Wim Taymans | eedd9cb | 2015-07-16 18:47:20 +0200 | [diff] [blame] | 495 | g_list_free_full (removed, gst_object_unref); |
| 496 | removed = NULL; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 497 | |
Wim Taymans | eedd9cb | 2015-07-16 18:47:20 +0200 | [diff] [blame] | 498 | while (pending) { |
| 499 | GstDeviceProvider *provider = pending->data; |
| 500 | |
| 501 | if (gst_device_provider_can_monitor (provider)) { |
| 502 | GST_OBJECT_UNLOCK (monitor); |
| 503 | |
| 504 | if (!gst_device_provider_start (provider)) |
| 505 | goto start_failed; |
| 506 | |
| 507 | GST_OBJECT_LOCK (monitor); |
| 508 | } |
| 509 | started = g_list_prepend (started, provider); |
| 510 | pending = g_list_delete_link (pending, pending); |
| 511 | |
| 512 | if (monitor->priv->cookie != cookie) |
| 513 | goto again; |
| 514 | } |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 515 | monitor->priv->started = TRUE; |
| 516 | GST_OBJECT_UNLOCK (monitor); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 517 | |
Wim Taymans | eedd9cb | 2015-07-16 18:47:20 +0200 | [diff] [blame] | 518 | g_list_free_full (started, gst_object_unref); |
| 519 | |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 520 | return TRUE; |
Wim Taymans | eedd9cb | 2015-07-16 18:47:20 +0200 | [diff] [blame] | 521 | |
| 522 | start_failed: |
| 523 | { |
| 524 | GST_OBJECT_LOCK (monitor); |
| 525 | gst_bus_set_flushing (monitor->priv->bus, TRUE); |
| 526 | GST_OBJECT_UNLOCK (monitor); |
| 527 | |
| 528 | while (started) { |
| 529 | GstDeviceProvider *provider = started->data; |
| 530 | |
| 531 | gst_device_provider_stop (provider); |
| 532 | gst_object_unref (provider); |
| 533 | |
| 534 | started = g_list_delete_link (started, started); |
| 535 | } |
| 536 | return FALSE; |
| 537 | } |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 538 | } |
| 539 | |
| 540 | /** |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 541 | * gst_device_monitor_stop: |
Olivier Crête | 7992174 | 2014-06-26 14:28:09 -0400 | [diff] [blame] | 542 | * @monitor: A #GstDeviceProvider |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 543 | * |
| 544 | * Stops monitoring the devices. |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 545 | * |
| 546 | * Since: 1.4 |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 547 | */ |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 548 | void |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 549 | gst_device_monitor_stop (GstDeviceMonitor * monitor) |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 550 | { |
| 551 | guint i; |
Wim Taymans | eedd9cb | 2015-07-16 18:47:20 +0200 | [diff] [blame] | 552 | GList *started = NULL; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 553 | |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 554 | g_return_if_fail (GST_IS_DEVICE_MONITOR (monitor)); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 555 | |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 556 | gst_bus_set_flushing (monitor->priv->bus, TRUE); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 557 | |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 558 | GST_OBJECT_LOCK (monitor); |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 559 | for (i = 0; i < monitor->priv->providers->len; i++) { |
| 560 | GstDeviceProvider *provider = |
| 561 | g_ptr_array_index (monitor->priv->providers, i); |
| 562 | |
Wim Taymans | eedd9cb | 2015-07-16 18:47:20 +0200 | [diff] [blame] | 563 | started = g_list_prepend (started, gst_object_ref (provider)); |
| 564 | } |
| 565 | GST_OBJECT_UNLOCK (monitor); |
| 566 | |
| 567 | while (started) { |
| 568 | GstDeviceProvider *provider = started->data; |
| 569 | |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 570 | if (gst_device_provider_can_monitor (provider)) |
| 571 | gst_device_provider_stop (provider); |
Wim Taymans | eedd9cb | 2015-07-16 18:47:20 +0200 | [diff] [blame] | 572 | |
| 573 | started = g_list_delete_link (started, started); |
| 574 | gst_object_unref (provider); |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 575 | } |
Wim Taymans | eedd9cb | 2015-07-16 18:47:20 +0200 | [diff] [blame] | 576 | |
| 577 | GST_OBJECT_LOCK (monitor); |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 578 | monitor->priv->started = FALSE; |
| 579 | GST_OBJECT_UNLOCK (monitor); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 580 | |
| 581 | } |
| 582 | |
Wim Taymans | 5a7b7e6 | 2015-07-16 18:56:00 +0200 | [diff] [blame] | 583 | static void |
| 584 | provider_hidden (GstDeviceProvider * provider, const gchar * hidden, |
| 585 | GstDeviceMonitor * monitor) |
| 586 | { |
| 587 | GST_OBJECT_LOCK (monitor); |
| 588 | monitor->priv->hidden = |
| 589 | g_list_prepend (monitor->priv->hidden, g_strdup (hidden)); |
| 590 | GST_OBJECT_UNLOCK (monitor); |
| 591 | } |
| 592 | |
| 593 | static void |
| 594 | provider_unhidden (GstDeviceProvider * provider, const gchar * hidden, |
| 595 | GstDeviceMonitor * monitor) |
| 596 | { |
| 597 | GList *find; |
| 598 | |
| 599 | GST_OBJECT_LOCK (monitor); |
| 600 | find = |
| 601 | g_list_find_custom (monitor->priv->hidden, hidden, |
| 602 | (GCompareFunc) g_strcmp0); |
| 603 | if (find) { |
| 604 | g_free (find->data); |
| 605 | monitor->priv->hidden = g_list_delete_link (monitor->priv->hidden, find); |
| 606 | } |
| 607 | GST_OBJECT_UNLOCK (monitor); |
| 608 | } |
| 609 | |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 610 | /** |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 611 | * gst_device_monitor_add_filter: |
| 612 | * @monitor: a device monitor |
Evan Nemerson | 5abc82e | 2014-06-30 23:39:18 -0700 | [diff] [blame] | 613 | * @classes: (allow-none): device classes to use as filter or %NULL for any class |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 614 | * @caps: (allow-none): the #GstCaps to filter or %NULL for ANY |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 615 | * |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 616 | * Adds a filter for which #GstDevice will be monitored, any device that matches |
Nirbheek Chauhan | 20c89fa | 2016-01-15 00:30:59 +0530 | [diff] [blame] | 617 | * all these classes and the #GstCaps will be returned. |
| 618 | * |
| 619 | * If this function is called multiple times to add more filters, each will be |
| 620 | * matched independently. That is, adding more filters will not further restrict |
| 621 | * what devices are matched. |
| 622 | * |
| 623 | * The #GstCaps supported by the device as returned by gst_device_get_caps() are |
| 624 | * not intersected with caps filters added using this function. |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 625 | * |
| 626 | * Filters must be added before the #GstDeviceMonitor is started. |
| 627 | * |
Nicolas Dufresne | 48700c7 | 2015-06-14 10:25:52 -0400 | [diff] [blame] | 628 | * Returns: The id of the new filter or 0 if no provider matched the filter's |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 629 | * classes. |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 630 | * |
| 631 | * Since: 1.4 |
| 632 | */ |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 633 | guint |
| 634 | gst_device_monitor_add_filter (GstDeviceMonitor * monitor, |
| 635 | const gchar * classes, GstCaps * caps) |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 636 | { |
| 637 | GList *factories = NULL; |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 638 | struct DeviceFilter *filter; |
| 639 | guint id = 0; |
| 640 | gboolean matched = FALSE; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 641 | |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 642 | g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), 0); |
| 643 | g_return_val_if_fail (!monitor->priv->started, 0); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 644 | |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 645 | GST_OBJECT_LOCK (monitor); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 646 | |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 647 | filter = g_slice_new0 (struct DeviceFilter); |
| 648 | filter->id = monitor->priv->last_id++; |
| 649 | if (caps) |
| 650 | filter->caps = gst_caps_ref (caps); |
| 651 | else |
| 652 | filter->caps = gst_caps_new_any (); |
| 653 | if (classes) |
| 654 | filter->classesv = g_strsplit (classes, "/", 0); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 655 | |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 656 | factories = gst_device_provider_factory_list_get_device_providers (1); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 657 | |
| 658 | while (factories) { |
Olivier Crête | 7992174 | 2014-06-26 14:28:09 -0400 | [diff] [blame] | 659 | GstDeviceProviderFactory *factory = factories->data; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 660 | |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 661 | if (gst_device_provider_factory_has_classesv (factory, filter->classesv)) { |
| 662 | GstDeviceProvider *provider; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 663 | |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 664 | provider = gst_device_provider_factory_get (factory); |
| 665 | |
| 666 | if (provider) { |
| 667 | guint i; |
| 668 | |
| 669 | for (i = 0; i < monitor->priv->providers->len; i++) { |
| 670 | if (g_ptr_array_index (monitor->priv->providers, i) == provider) { |
| 671 | gst_object_unref (provider); |
| 672 | provider = NULL; |
| 673 | matched = TRUE; |
| 674 | break; |
| 675 | } |
| 676 | } |
| 677 | } |
| 678 | |
| 679 | if (provider) { |
| 680 | GstBus *bus = gst_device_provider_get_bus (provider); |
| 681 | |
Wim Taymans | 5a7b7e6 | 2015-07-16 18:56:00 +0200 | [diff] [blame] | 682 | update_hidden_providers_list (&monitor->priv->hidden, provider); |
| 683 | g_signal_connect (provider, "provider-hidden", |
| 684 | (GCallback) provider_hidden, monitor); |
| 685 | g_signal_connect (provider, "provider-unhidden", |
| 686 | (GCallback) provider_unhidden, monitor); |
| 687 | |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 688 | matched = TRUE; |
| 689 | gst_bus_enable_sync_message_emission (bus); |
| 690 | g_signal_connect (bus, "sync-message", |
| 691 | G_CALLBACK (bus_sync_message), monitor); |
| 692 | gst_object_unref (bus); |
| 693 | g_ptr_array_add (monitor->priv->providers, provider); |
| 694 | monitor->priv->cookie++; |
| 695 | } |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 696 | } |
| 697 | |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 698 | factories = g_list_remove (factories, factory); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 699 | gst_object_unref (factory); |
| 700 | } |
| 701 | |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 702 | /* Ensure there is no leak here */ |
| 703 | g_assert (factories == NULL); |
| 704 | |
Nirbheek Chauhan | 4d6c7cc | 2016-01-15 00:25:05 +0530 | [diff] [blame] | 705 | if (matched) |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 706 | id = filter->id; |
Nirbheek Chauhan | 4d6c7cc | 2016-01-15 00:25:05 +0530 | [diff] [blame] | 707 | g_ptr_array_add (monitor->priv->filters, filter); |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 708 | |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 709 | GST_OBJECT_UNLOCK (monitor); |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 710 | |
| 711 | return id; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 712 | } |
| 713 | |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 714 | /** |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 715 | * gst_device_monitor_remove_filter: |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 716 | * @monitor: a device monitor |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 717 | * @filter_id: the id of the filter |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 718 | * |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 719 | * Removes a filter from the #GstDeviceMonitor using the id that was returned |
| 720 | * by gst_device_monitor_add_filter(). |
Olivier Crête | 77db6bf | 2014-06-20 16:55:06 -0400 | [diff] [blame] | 721 | * |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 722 | * Returns: %TRUE of the filter id was valid, %FALSE otherwise |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 723 | * |
| 724 | * Since: 1.4 |
| 725 | */ |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 726 | gboolean |
| 727 | gst_device_monitor_remove_filter (GstDeviceMonitor * monitor, guint filter_id) |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 728 | { |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 729 | guint i, j; |
| 730 | gboolean removed = FALSE; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 731 | |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 732 | g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), FALSE); |
| 733 | g_return_val_if_fail (!monitor->priv->started, FALSE); |
| 734 | g_return_val_if_fail (filter_id > 0, FALSE); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 735 | |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 736 | GST_OBJECT_LOCK (monitor); |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 737 | for (i = 0; i < monitor->priv->filters->len; i++) { |
| 738 | struct DeviceFilter *filter = g_ptr_array_index (monitor->priv->filters, i); |
| 739 | |
| 740 | if (filter->id == filter_id) { |
| 741 | g_ptr_array_remove_index (monitor->priv->filters, i); |
| 742 | removed = TRUE; |
| 743 | break; |
| 744 | } |
| 745 | } |
| 746 | |
| 747 | if (removed) { |
| 748 | for (i = 0; i < monitor->priv->providers->len; i++) { |
| 749 | GstDeviceProvider *provider = |
| 750 | g_ptr_array_index (monitor->priv->providers, i); |
| 751 | GstDeviceProviderFactory *factory = |
| 752 | gst_device_provider_get_factory (provider); |
| 753 | gboolean valid = FALSE; |
| 754 | |
| 755 | for (j = 0; j < monitor->priv->filters->len; j++) { |
| 756 | struct DeviceFilter *filter = |
| 757 | g_ptr_array_index (monitor->priv->filters, j); |
| 758 | |
| 759 | if (gst_device_provider_factory_has_classesv (factory, |
| 760 | filter->classesv)) { |
| 761 | valid = TRUE; |
| 762 | break; |
| 763 | } |
| 764 | } |
| 765 | |
| 766 | if (!valid) { |
| 767 | monitor->priv->cookie++; |
| 768 | gst_device_monitor_remove (monitor, i); |
| 769 | i--; |
| 770 | } |
| 771 | } |
| 772 | } |
| 773 | |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 774 | GST_OBJECT_UNLOCK (monitor); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 775 | |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 776 | return removed; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 777 | } |
| 778 | |
Olivier Crête | 6d12b33 | 2014-06-26 17:13:12 -0400 | [diff] [blame] | 779 | |
| 780 | |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 781 | /** |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 782 | * gst_device_monitor_new: |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 783 | * |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 784 | * Create a new #GstDeviceMonitor |
Olivier Crête | 77db6bf | 2014-06-20 16:55:06 -0400 | [diff] [blame] | 785 | * |
Sebastian Dröge | f119e93 | 2017-05-15 18:58:38 +0300 | [diff] [blame] | 786 | * Returns: (transfer full): a new device monitor. |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 787 | * |
| 788 | * Since: 1.4 |
| 789 | */ |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 790 | GstDeviceMonitor * |
| 791 | gst_device_monitor_new (void) |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 792 | { |
Sebastian Dröge | f119e93 | 2017-05-15 18:58:38 +0300 | [diff] [blame] | 793 | GstDeviceMonitor *monitor; |
| 794 | |
| 795 | monitor = g_object_new (GST_TYPE_DEVICE_MONITOR, NULL); |
| 796 | |
| 797 | /* Clear floating flag */ |
| 798 | gst_object_ref_sink (monitor); |
| 799 | |
| 800 | return monitor; |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 801 | } |
| 802 | |
| 803 | /** |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 804 | * gst_device_monitor_get_bus: |
Olivier Crête | 7992174 | 2014-06-26 14:28:09 -0400 | [diff] [blame] | 805 | * @monitor: a #GstDeviceProvider |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 806 | * |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 807 | * Gets the #GstBus of this #GstDeviceMonitor |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 808 | * |
| 809 | * Returns: (transfer full): a #GstBus |
Tim-Philipp Müller | bd26fa7 | 2014-06-14 16:30:49 +0100 | [diff] [blame] | 810 | * |
| 811 | * Since: 1.4 |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 812 | */ |
| 813 | GstBus * |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 814 | gst_device_monitor_get_bus (GstDeviceMonitor * monitor) |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 815 | { |
Olivier Crête | c2583ca | 2014-06-26 15:08:46 -0400 | [diff] [blame] | 816 | g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), NULL); |
Olivier Crête | 448d180 | 2013-01-08 21:30:44 -0500 | [diff] [blame] | 817 | |
| 818 | return gst_object_ref (monitor->priv->bus); |
| 819 | } |
Wim Taymans | 62f6207 | 2015-07-17 10:18:02 +0200 | [diff] [blame] | 820 | |
| 821 | /** |
| 822 | * gst_device_monitor_get_providers: |
| 823 | * @monitor: a #GstDeviceMonitor |
| 824 | * |
| 825 | * Get a list of the currently selected device provider factories. |
| 826 | * |
| 827 | * This |
| 828 | * |
| 829 | * Returns: (transfer full) (array zero-terminated=1) (element-type gchar*): |
| 830 | * A list of device provider factory names that are currently being |
| 831 | * monitored by @monitor or %NULL when nothing is being monitored. |
| 832 | * |
| 833 | * Since: 1.6 |
| 834 | */ |
| 835 | gchar ** |
| 836 | gst_device_monitor_get_providers (GstDeviceMonitor * monitor) |
| 837 | { |
| 838 | guint i, len; |
| 839 | gchar **res = NULL; |
| 840 | |
| 841 | g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), NULL); |
| 842 | |
| 843 | GST_OBJECT_LOCK (monitor); |
| 844 | len = monitor->priv->providers->len; |
| 845 | if (len == 0) |
| 846 | goto done; |
| 847 | |
| 848 | res = g_new (gchar *, len + 1); |
| 849 | |
| 850 | for (i = 0; i < len; i++) { |
| 851 | GstDeviceProvider *provider = |
| 852 | g_ptr_array_index (monitor->priv->providers, i); |
| 853 | GstDeviceProviderFactory *factory = |
| 854 | gst_device_provider_get_factory (provider); |
| 855 | |
| 856 | res[i] = g_strdup (GST_OBJECT_NAME (factory)); |
| 857 | } |
| 858 | res[i] = NULL; |
| 859 | |
| 860 | done: |
| 861 | GST_OBJECT_UNLOCK (monitor); |
| 862 | |
| 863 | return res; |
| 864 | } |
Wim Taymans | 5a7b7e6 | 2015-07-16 18:56:00 +0200 | [diff] [blame] | 865 | |
| 866 | /** |
| 867 | * gst_device_monitor_set_show_all_devices: |
| 868 | * @monitor: a #GstDeviceMonitor |
| 869 | * @show_all: show all devices |
| 870 | * |
| 871 | * Set if all devices should be visible, even those devices from hidden |
| 872 | * providers. Setting @show_all to true might show some devices multiple times. |
| 873 | * |
| 874 | * Since: 1.6 |
| 875 | */ |
| 876 | void |
| 877 | gst_device_monitor_set_show_all_devices (GstDeviceMonitor * monitor, |
| 878 | gboolean show_all) |
| 879 | { |
| 880 | g_return_if_fail (GST_IS_DEVICE_MONITOR (monitor)); |
| 881 | |
| 882 | GST_OBJECT_LOCK (monitor); |
| 883 | monitor->priv->show_all = show_all; |
| 884 | GST_OBJECT_UNLOCK (monitor); |
| 885 | } |
| 886 | |
| 887 | /** |
| 888 | * gst_device_monitor_get_show_all_devices: |
| 889 | * @monitor: a #GstDeviceMonitor |
| 890 | * |
| 891 | * Get if @monitor is curretly showing all devices, even those from hidden |
| 892 | * providers. |
| 893 | * |
| 894 | * Returns: %TRUE when all devices will be shown. |
| 895 | * |
| 896 | * Since: 1.6 |
| 897 | */ |
| 898 | gboolean |
| 899 | gst_device_monitor_get_show_all_devices (GstDeviceMonitor * monitor) |
| 900 | { |
| 901 | gboolean res; |
| 902 | |
| 903 | g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), FALSE); |
| 904 | |
| 905 | GST_OBJECT_LOCK (monitor); |
| 906 | res = monitor->priv->show_all; |
| 907 | GST_OBJECT_UNLOCK (monitor); |
| 908 | |
| 909 | return res; |
| 910 | } |