devicemonitor: Use local includes and use gst_private before anything
[platform/upstream/gstreamer.git] / gst / gstdevicemonitor.c
1 /* GStreamer
2  * Copyright (C) 2012 Olivier Crete <olivier.crete@collabora.com>
3  *
4  * gstdevicemonitor.c: Device probing and monitoring
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  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "gst_private.h"
27
28 #include "gstdevicemonitor.h"
29
30 #include "gstelementmetadata.h"
31 #include "gstquark.h"
32
33 struct _GstDeviceMonitorPrivate
34 {
35   GstBus *bus;
36
37   GMutex start_lock;
38
39   gboolean started_count;
40 };
41
42 /* this is used in gstelementfactory.c:gst_element_register() */
43 GQuark __gst_devicemonitorclass_factory = 0;
44
45 static void gst_device_monitor_class_init (GstDeviceMonitorClass * klass);
46 static void gst_device_monitor_init (GstDeviceMonitor * element);
47 static void gst_device_monitor_base_class_init (gpointer g_class);
48 static void gst_device_monitor_base_class_finalize (gpointer g_class);
49 static void gst_device_monitor_dispose (GObject * object);
50 static void gst_device_monitor_finalize (GObject * object);
51
52 static gpointer gst_device_monitor_parent_class = NULL;
53
54 GType
55 gst_device_monitor_get_type (void)
56 {
57   static volatile gsize gst_device_monitor_type = 0;
58
59   if (g_once_init_enter (&gst_device_monitor_type)) {
60     GType _type;
61     static const GTypeInfo element_info = {
62       sizeof (GstDeviceMonitorClass),
63       gst_device_monitor_base_class_init,
64       gst_device_monitor_base_class_finalize,
65       (GClassInitFunc) gst_device_monitor_class_init,
66       NULL,
67       NULL,
68       sizeof (GstDeviceMonitor),
69       0,
70       (GInstanceInitFunc) gst_device_monitor_init,
71       NULL
72     };
73
74     _type = g_type_register_static (GST_TYPE_OBJECT, "GstDeviceMonitor",
75         &element_info, G_TYPE_FLAG_ABSTRACT);
76
77     __gst_devicemonitorclass_factory =
78         g_quark_from_static_string ("GST_DEVICEMONITORCLASS_FACTORY");
79     g_once_init_leave (&gst_device_monitor_type, _type);
80   }
81   return gst_device_monitor_type;
82 }
83
84 static void
85 gst_device_monitor_base_class_init (gpointer g_class)
86 {
87   GstDeviceMonitorClass *klass = GST_DEVICE_MONITOR_CLASS (g_class);
88
89   /* Copy the element details here so elements can inherit the
90    * details from their base class and classes only need to set
91    * the details in class_init instead of base_init */
92   klass->metadata =
93       klass->metadata ? gst_structure_copy (klass->metadata) :
94       gst_structure_new_empty ("metadata");
95
96   klass->factory = g_type_get_qdata (G_TYPE_FROM_CLASS (klass),
97       __gst_devicemonitorclass_factory);
98 }
99
100 static void
101 gst_device_monitor_base_class_finalize (gpointer g_class)
102 {
103   GstDeviceMonitorClass *klass = GST_DEVICE_MONITOR_CLASS (g_class);
104
105   gst_structure_free (klass->metadata);
106 }
107
108 static void
109 gst_device_monitor_class_init (GstDeviceMonitorClass * klass)
110 {
111   GObjectClass *gobject_class = (GObjectClass *) klass;
112
113   gst_device_monitor_parent_class = g_type_class_peek_parent (klass);
114
115   g_type_class_add_private (klass, sizeof (GstDeviceMonitorPrivate));
116
117   gobject_class->dispose = gst_device_monitor_dispose;
118   gobject_class->finalize = gst_device_monitor_finalize;
119 }
120
121 static void
122 gst_device_monitor_init (GstDeviceMonitor * monitor)
123 {
124   monitor->priv = G_TYPE_INSTANCE_GET_PRIVATE (monitor,
125       GST_TYPE_DEVICE_MONITOR, GstDeviceMonitorPrivate);
126
127   g_mutex_init (&monitor->priv->start_lock);
128
129   monitor->priv->bus = gst_bus_new ();
130   gst_bus_set_flushing (monitor->priv->bus, TRUE);
131 }
132
133
134 static void
135 gst_device_monitor_dispose (GObject * object)
136 {
137   GstDeviceMonitor *monitor = GST_DEVICE_MONITOR (object);
138
139   gst_object_replace ((GstObject **) & monitor->priv->bus, NULL);
140
141   GST_OBJECT_LOCK (monitor);
142   g_list_free_full (monitor->devices, (GDestroyNotify) gst_object_unparent);
143   monitor->devices = NULL;
144   GST_OBJECT_UNLOCK (monitor);
145
146   G_OBJECT_CLASS (gst_device_monitor_parent_class)->dispose (object);
147 }
148
149 static void
150 gst_device_monitor_finalize (GObject * object)
151 {
152   GstDeviceMonitor *monitor = GST_DEVICE_MONITOR (object);
153
154   g_mutex_clear (&monitor->priv->start_lock);
155
156   G_OBJECT_CLASS (gst_device_monitor_parent_class)->finalize (object);
157 }
158
159 /**
160  * gst_device_monitor_class_add_metadata:
161  * @klass: class to set metadata for
162  * @key: the key to set
163  * @value: the value to set
164  *
165  * Set @key with @value as metadata in @klass.
166  */
167 void
168 gst_device_monitor_class_add_metadata (GstDeviceMonitorClass * klass,
169     const gchar * key, const gchar * value)
170 {
171   g_return_if_fail (GST_IS_DEVICE_MONITOR_CLASS (klass));
172   g_return_if_fail (key != NULL);
173   g_return_if_fail (value != NULL);
174
175   gst_structure_set ((GstStructure *) klass->metadata,
176       key, G_TYPE_STRING, value, NULL);
177 }
178
179 /**
180  * gst_device_monitor_class_add_static_metadata:
181  * @klass: class to set metadata for
182  * @key: the key to set
183  * @value: the value to set
184  *
185  * Set @key with @value as metadata in @klass.
186  *
187  * Same as gst_device_monitor_class_add_metadata(), but @value must be a static string
188  * or an inlined string, as it will not be copied. (GStreamer plugins will
189  * be made resident once loaded, so this function can be used even from
190  * dynamically loaded plugins.)
191  *
192  * Since: 1.4
193  */
194 void
195 gst_device_monitor_class_add_static_metadata (GstDeviceMonitorClass * klass,
196     const gchar * key, const gchar * value)
197 {
198   GValue val = G_VALUE_INIT;
199
200   g_return_if_fail (GST_IS_DEVICE_MONITOR_CLASS (klass));
201   g_return_if_fail (key != NULL);
202   g_return_if_fail (value != NULL);
203
204   g_value_init (&val, G_TYPE_STRING);
205   g_value_set_static_string (&val, value);
206   gst_structure_take_value ((GstStructure *) klass->metadata, key, &val);
207 }
208
209 /**
210  * gst_device_monitor_class_set_metadata:
211  * @klass: class to set metadata for
212  * @longname: The long English name of the device monitor. E.g. "File Sink"
213  * @classification: String describing the type of device monitor, as an unordered list
214  * separated with slashes ('/'). See draft-klass.txt of the design docs
215  * for more details and common types. E.g: "Sink/File"
216  * @description: Sentence describing the purpose of the device monitor.
217  * E.g: "Write stream to a file"
218  * @author: Name and contact details of the author(s). Use \n to separate
219  * multiple author metadata. E.g: "Joe Bloggs &lt;joe.blogs at foo.com&gt;"
220  *
221  * Sets the detailed information for a #GstDeviceMonitorClass.
222  * <note>This function is for use in _class_init functions only.</note>
223  *
224  * Since: 1.4
225  */
226 void
227 gst_device_monitor_class_set_metadata (GstDeviceMonitorClass * klass,
228     const gchar * longname, const gchar * classification,
229     const gchar * description, const gchar * author)
230 {
231   g_return_if_fail (GST_IS_DEVICE_MONITOR_CLASS (klass));
232   g_return_if_fail (longname != NULL && *longname != '\0');
233   g_return_if_fail (classification != NULL && *classification != '\0');
234   g_return_if_fail (description != NULL && *description != '\0');
235   g_return_if_fail (author != NULL && *author != '\0');
236
237   gst_structure_id_set ((GstStructure *) klass->metadata,
238       GST_QUARK (ELEMENT_METADATA_LONGNAME), G_TYPE_STRING, longname,
239       GST_QUARK (ELEMENT_METADATA_KLASS), G_TYPE_STRING, classification,
240       GST_QUARK (ELEMENT_METADATA_DESCRIPTION), G_TYPE_STRING, description,
241       GST_QUARK (ELEMENT_METADATA_AUTHOR), G_TYPE_STRING, author, NULL);
242 }
243
244 /**
245  * gst_device_monitor_class_set_static_metadata:
246  * @klass: class to set metadata for
247  * @longname: The long English name of the element. E.g. "File Sink"
248  * @classification: String describing the type of element, as an unordered list
249  * separated with slashes ('/'). See draft-klass.txt of the design docs
250  * for more details and common types. E.g: "Sink/File"
251  * @description: Sentence describing the purpose of the element.
252  * E.g: "Write stream to a file"
253  * @author: Name and contact details of the author(s). Use \n to separate
254  * multiple author metadata. E.g: "Joe Bloggs &lt;joe.blogs at foo.com&gt;"
255  *
256  * Sets the detailed information for a #GstDeviceMonitorClass.
257  * <note>This function is for use in _class_init functions only.</note>
258  *
259  * Same as gst_device_monitor_class_set_metadata(), but @longname, @classification,
260  * @description, and @author must be static strings or inlined strings, as
261  * they will not be copied. (GStreamer plugins will be made resident once
262  * loaded, so this function can be used even from dynamically loaded plugins.)
263  *
264  * Since: 1.4
265  */
266 void
267 gst_device_monitor_class_set_static_metadata (GstDeviceMonitorClass * klass,
268     const gchar * longname, const gchar * classification,
269     const gchar * description, const gchar * author)
270 {
271   GstStructure *s = (GstStructure *) klass->metadata;
272   GValue val = G_VALUE_INIT;
273
274   g_return_if_fail (GST_IS_DEVICE_MONITOR_CLASS (klass));
275   g_return_if_fail (longname != NULL && *longname != '\0');
276   g_return_if_fail (classification != NULL && *classification != '\0');
277   g_return_if_fail (description != NULL && *description != '\0');
278   g_return_if_fail (author != NULL && *author != '\0');
279
280   g_value_init (&val, G_TYPE_STRING);
281
282   g_value_set_static_string (&val, longname);
283   gst_structure_id_set_value (s, GST_QUARK (ELEMENT_METADATA_LONGNAME), &val);
284
285   g_value_set_static_string (&val, classification);
286   gst_structure_id_set_value (s, GST_QUARK (ELEMENT_METADATA_KLASS), &val);
287
288   g_value_set_static_string (&val, description);
289   gst_structure_id_set_value (s, GST_QUARK (ELEMENT_METADATA_DESCRIPTION),
290       &val);
291
292   g_value_set_static_string (&val, author);
293   gst_structure_id_take_value (s, GST_QUARK (ELEMENT_METADATA_AUTHOR), &val);
294 }
295
296 /**
297  * gst_device_monitor_class_get_metadata:
298  * @klass: class to get metadata for
299  * @key: the key to get
300  *
301  * Get metadata with @key in @klass.
302  *
303  * Returns: the metadata for @key.
304  *
305  * Since: 1.4
306  */
307 const gchar *
308 gst_device_monitor_class_get_metadata (GstDeviceMonitorClass * klass,
309     const gchar * key)
310 {
311   g_return_val_if_fail (GST_IS_DEVICE_MONITOR_CLASS (klass), NULL);
312   g_return_val_if_fail (key != NULL, NULL);
313
314   return gst_structure_get_string ((GstStructure *) klass->metadata, key);
315 }
316
317 /**
318  * gst_device_monitor_get_devices:
319  * @monitor: A #GstDeviceMonitor
320  *
321  * Gets a list of devices that this monitor understands. This may actually
322  * probe the hardware if the monitor is not currently started.
323  *
324  * Returns: (transfer full) (element-type GstDevice): a #GList of
325  *   #GstDevice
326  *
327  * Since: 1.4
328  */
329
330 GList *
331 gst_device_monitor_get_devices (GstDeviceMonitor * monitor)
332 {
333   GstDeviceMonitorClass *klass;
334   GList *devices = NULL;
335   gboolean started;
336   GList *item;
337
338   g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), NULL);
339   klass = GST_DEVICE_MONITOR_GET_CLASS (monitor);
340
341   g_mutex_lock (&monitor->priv->start_lock);
342   started = (monitor->priv->started_count > 0);
343
344   if (started) {
345     GST_OBJECT_LOCK (monitor);
346     for (item = monitor->devices; item; item = item->next)
347       devices = g_list_prepend (devices, gst_object_ref (item->data));
348     GST_OBJECT_UNLOCK (monitor);
349   } else if (klass->probe)
350     devices = klass->probe (monitor);
351
352   g_mutex_unlock (&monitor->priv->start_lock);
353
354   return devices;
355 }
356
357 /**
358  * gst_device_monitor_start:
359  * @monitor: A #GstDeviceMonitor
360  *
361  * Starts monitoring the devices. This will cause #GST_MESSAGE_DEVICE messages
362  * to be posted on the monitor's bus when devices are added or removed from
363  * the system.
364  *
365  * Since the #GstDeviceMonitor is a singleton,
366  * gst_device_monitor_start() may already have been called by another
367  * user of the object, gst_device_monitor_stop() needs to be called the same
368  * number of times.
369  *
370  * Returns: %TRUE if the device monitoring could be started
371  *
372  * Since: 1.4
373  */
374
375 gboolean
376 gst_device_monitor_start (GstDeviceMonitor * monitor)
377 {
378   GstDeviceMonitorClass *klass;
379   gboolean ret = FALSE;
380
381   g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), FALSE);
382   klass = GST_DEVICE_MONITOR_GET_CLASS (monitor);
383
384   g_mutex_lock (&monitor->priv->start_lock);
385
386   if (monitor->priv->started_count > 0) {
387     ret = TRUE;
388     goto started;
389   }
390
391   if (klass->start)
392     ret = klass->start (monitor);
393
394   if (ret) {
395     monitor->priv->started_count++;
396     gst_bus_set_flushing (monitor->priv->bus, FALSE);
397   }
398
399 started:
400
401   g_mutex_unlock (&monitor->priv->start_lock);
402
403   return ret;
404 }
405
406 /**
407  * gst_device_monitor_stop:
408  * @monitor: A #GstDeviceMonitor
409  *
410  * Decreases the use-count by one. If the use count reaches zero, this
411  * #GstDeviceMonitor will stop monitoring the devices. This needs to be
412  * called the same number of times that gst_device_monitor_start() was called.
413  *
414  * Since: 1.4
415  */
416
417 void
418 gst_device_monitor_stop (GstDeviceMonitor * monitor)
419 {
420   GstDeviceMonitorClass *klass;
421
422   g_return_if_fail (GST_IS_DEVICE_MONITOR (monitor));
423   klass = GST_DEVICE_MONITOR_GET_CLASS (monitor);
424
425   g_mutex_lock (&monitor->priv->start_lock);
426
427   if (monitor->priv->started_count == 1) {
428     gst_bus_set_flushing (monitor->priv->bus, TRUE);
429     if (klass->stop)
430       klass->stop (monitor);
431     GST_OBJECT_LOCK (monitor);
432     g_list_free_full (monitor->devices, (GDestroyNotify) gst_object_unparent);
433     monitor->devices = NULL;
434     GST_OBJECT_UNLOCK (monitor);
435   } else if (monitor->priv->started_count < 1) {
436     g_critical ("Trying to stop a GstDeviceMonitor %s which is already stopped",
437         GST_OBJECT_NAME (monitor));
438   }
439
440   monitor->priv->started_count--;
441   g_mutex_unlock (&monitor->priv->start_lock);
442 }
443
444
445 /**
446  * gst_device_monitor_get_factory:
447  * @monitor: a #GstDeviceMonitor to request the device monitor factory of.
448  *
449  * Retrieves the factory that was used to create this device monitor.
450  *
451  * Returns: (transfer none): the #GstDeviceMonitorFactory used for creating this
452  *     device monitor. no refcounting is needed.
453  *
454  * Since: 1.4
455  */
456 GstDeviceMonitorFactory *
457 gst_device_monitor_get_factory (GstDeviceMonitor * monitor)
458 {
459   g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), NULL);
460
461   return GST_DEVICE_MONITOR_GET_CLASS (monitor)->factory;
462 }
463
464 /**
465  * gst_device_monitor_can_monitor:
466  * @monitor: a #GstDeviceMonitor
467  *
468  * If this function returns %TRUE, then the device monitor can monitor if
469  * devices are added or removed. Otherwise, it can only do static probing.
470  *
471  * Returns: %TRUE if the #GstDeviceMonitor support monitoring, %FALSE otherwise
472  */
473 gboolean
474 gst_device_monitor_can_monitor (GstDeviceMonitor * monitor)
475 {
476   GstDeviceMonitorClass *klass;
477
478   g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), FALSE);
479   klass = GST_DEVICE_MONITOR_GET_CLASS (monitor);
480
481   if (klass->start)
482     return TRUE;
483   else
484     return FALSE;
485 }
486
487 /**
488  * gst_device_monitor_get_bus:
489  * @monitor: a #GstDeviceMonitor
490  *
491  * Gets the #GstBus of this #GstDeviceMonitor
492  *
493  * Returns: (transfer full): a #GstBus
494  *
495  * Since: 1.4
496  */
497 GstBus *
498 gst_device_monitor_get_bus (GstDeviceMonitor * monitor)
499 {
500   g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), NULL);
501
502   return gst_object_ref (monitor->priv->bus);
503 }
504
505 /**
506  * gst_device_monitor_device_add:
507  * @monitor: a #GstDeviceMonitor
508  * @device: (transfer full): a #GstDevice that has been added
509  *
510  * Posts a message on the monitor's #GstBus to inform applications that
511  * a new device has been added.
512  *
513  * This is for use by subclasses.
514  *
515  * Since: 1.4
516  */
517 void
518 gst_device_monitor_device_add (GstDeviceMonitor * monitor, GstDevice * device)
519 {
520   GstMessage *message;
521
522   if (!gst_object_set_parent (GST_OBJECT (device), GST_OBJECT (monitor))) {
523     GST_WARNING_OBJECT (monitor, "Could not parent device %p to monitor,"
524         " it already has a parent", device);
525     return;
526   }
527
528   GST_OBJECT_LOCK (monitor);
529   monitor->devices = g_list_prepend (monitor->devices, gst_object_ref (device));
530   GST_OBJECT_UNLOCK (monitor);
531
532   message = gst_message_new_device_added (GST_OBJECT (monitor), device);
533   gst_bus_post (monitor->priv->bus, message);
534   gst_object_unref (device);
535 }
536
537
538 /**
539  * gst_device_monitor_device_remove:
540  * @monitor: a #GstDeviceMonitor
541  * @device: a #GstDevice that has been removed
542  *
543  * Posts a message on the monitor's #GstBus to inform applications that
544  * a device has been removed.
545  *
546  * This is for use by subclasses.
547  *
548  * Since: 1.4
549  */
550 void
551 gst_device_monitor_device_remove (GstDeviceMonitor * monitor,
552     GstDevice * device)
553 {
554   GstMessage *message;
555   GList *item;
556
557   GST_OBJECT_LOCK (monitor);
558   item = g_list_find (monitor->devices, device);
559   if (item) {
560     monitor->devices = g_list_delete_link (monitor->devices, item);
561   }
562   GST_OBJECT_UNLOCK (monitor);
563
564   message = gst_message_new_device_removed (GST_OBJECT (monitor), device);
565   g_signal_emit_by_name (device, "removed");
566   gst_bus_post (monitor->priv->bus, message);
567   if (item)
568     gst_object_unparent (GST_OBJECT (device));
569 }