devicemonitor: Use local includes and use gst_private before anything
[platform/upstream/gstreamer.git] / gst / gstdevice.c
1 /* GStreamer
2  * Copyright (C) 2012 Olivier Crete <olivier.crete@collabora.com>
3  *
4  * gstdevice.c: Device discovery
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 "gstdevice.h"
29
30 enum
31 {
32   PROP_DISPLAY_NAME = 1,
33   PROP_CAPS,
34   PROP_KLASS
35 };
36
37 enum
38 {
39   REMOVED,
40   LAST_SIGNAL
41 };
42
43 struct _GstDevicePrivate
44 {
45   GstCaps *caps;
46   gchar *klass;
47   gchar *display_name;
48 };
49
50
51 static guint signals[LAST_SIGNAL];
52
53 G_DEFINE_ABSTRACT_TYPE (GstDevice, gst_device, GST_TYPE_OBJECT);
54
55 static void gst_device_get_property (GObject * object, guint property_id,
56     GValue * value, GParamSpec * pspec);
57 static void gst_device_set_property (GObject * object, guint property_id,
58     const GValue * value, GParamSpec * pspec);
59 static void gst_device_finalize (GObject * object);
60
61
62 static void
63 gst_device_class_init (GstDeviceClass * klass)
64 {
65   GObjectClass *object_class = G_OBJECT_CLASS (klass);
66
67   g_type_class_add_private (klass, sizeof (GstDevicePrivate));
68
69   object_class->get_property = gst_device_get_property;
70   object_class->set_property = gst_device_set_property;
71   object_class->finalize = gst_device_finalize;
72
73   g_object_class_install_property (object_class, PROP_DISPLAY_NAME,
74       g_param_spec_string ("display-name", "Display Name",
75           "The user-friendly name of the device", "",
76           G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
77   g_object_class_install_property (object_class, PROP_CAPS,
78       g_param_spec_boxed ("caps", "Device Caps",
79           "The possible caps of a device", GST_TYPE_CAPS,
80           G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
81   g_object_class_install_property (object_class, PROP_KLASS,
82       g_param_spec_string ("klass", "Device Class",
83           "The Class of the device", "",
84           G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
85
86   signals[REMOVED] = g_signal_new ("removed", G_TYPE_FROM_CLASS (klass),
87       G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
88 }
89
90 static void
91 gst_device_init (GstDevice * device)
92 {
93   device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device, GST_TYPE_DEVICE,
94       GstDevicePrivate);
95 }
96
97 static void
98 gst_device_finalize (GObject * object)
99 {
100   GstDevice *device = GST_DEVICE (object);
101
102   gst_caps_replace (&device->priv->caps, NULL);
103
104   g_free (device->priv->display_name);
105   g_free (device->priv->klass);
106
107   G_OBJECT_CLASS (gst_device_parent_class)->finalize (object);
108 }
109
110 static void
111 gst_device_get_property (GObject * object, guint prop_id,
112     GValue * value, GParamSpec * pspec)
113 {
114   GstDevice *gstdevice;
115
116   gstdevice = GST_DEVICE_CAST (object);
117
118   switch (prop_id) {
119     case PROP_DISPLAY_NAME:
120       g_value_take_string (value, gst_device_get_display_name (gstdevice));
121       break;
122     case PROP_CAPS:
123       if (gstdevice->priv->caps)
124         g_value_take_boxed (value, gst_device_get_caps (gstdevice));
125       break;
126     case PROP_KLASS:
127       g_value_take_string (value, gst_device_get_klass (gstdevice));
128       break;
129     default:
130       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
131       break;
132   }
133 }
134
135
136 static void
137 gst_device_set_property (GObject * object, guint prop_id,
138     const GValue * value, GParamSpec * pspec)
139 {
140   GstDevice *gstdevice;
141
142   gstdevice = GST_DEVICE_CAST (object);
143
144   switch (prop_id) {
145     case PROP_DISPLAY_NAME:
146       gstdevice->priv->display_name = g_value_dup_string (value);
147       break;
148     case PROP_CAPS:
149       gst_caps_replace (&gstdevice->priv->caps, g_value_get_boxed (value));
150       break;
151     case PROP_KLASS:
152       gstdevice->priv->klass = g_value_dup_string (value);
153       break;
154     default:
155       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
156       break;
157   }
158 }
159
160 /**
161  * gst_device_create_element:
162  * @device: a #GstDevice
163  * @name: (allow-none): name of new element, or NULL to automatically
164  * create a unique name.
165  *
166  * Returns: (transfer full): a new #GstElement configured to use this device
167  *
168  * Since: 1.4
169  */
170 GstElement *
171 gst_device_create_element (GstDevice * device, const gchar * name)
172 {
173   GstDeviceClass *klass = GST_DEVICE_GET_CLASS (device);
174
175   if (klass->create_element)
176     return klass->create_element (device, name);
177   else
178     return NULL;
179 }
180
181 /**
182  * gst_device_get_caps:
183  * @device: a #GstDevice
184  *
185  * Getter for the #GstCaps that this device supports.
186  *
187  * Returns: The #GstCaps supported by this device. Unref with
188  * gst_caps_unref() when done.
189  *
190  * Since: 1.4
191  */
192 GstCaps *
193 gst_device_get_caps (GstDevice * device)
194 {
195   if (device->priv->caps)
196     return gst_caps_ref (device->priv->caps);
197   else
198     return NULL;
199 }
200
201 /**
202  * gst_device_get_display_name:
203  * @device: a #GstDevice
204  *
205  * Gets the user-friendly name of the device.
206  *
207  * Returns: The device name. Free with g_free() after use.
208  *
209  * Since: 1.4
210  */
211 gchar *
212 gst_device_get_display_name (GstDevice * device)
213 {
214   return
215       g_strdup (device->priv->display_name ? device->priv->display_name : "");
216 }
217
218 /**
219  * gst_device_get_klass:
220  * @device: a #GstDevice
221  *
222  * Gets the "class" of a device. This is a "/" separated list of
223  * classes that represent this device. They are a subset of the
224  * classes of the #GstDeviceMonitor that produced this device.
225  *
226  * Returns: The device class. Free with g_free() after use.
227  *
228  * Since: 1.4
229  */
230 gchar *
231 gst_device_get_klass (GstDevice * device)
232 {
233   return g_strdup (device->priv->klass ? device->priv->klass : "");
234 }
235
236 /**
237  * gst_device_reconfigure_element:
238  * @device: a #GstDevice
239  * @element: a #GstElement
240  *
241  * Tries to reconfigure an existing element to use the device. If this
242  * function fails, then one must destroy the element and create a new one
243  * using gst_device_create_element().
244  *
245  * Note: This should only be implemented for elements can change their
246  * device in the PLAYING state.
247  *
248  * Returns: %TRUE if the element could be reconfigured to use this device,
249  * %FALSE otherwise.
250  *
251  * Since: 1.4
252  */
253 gboolean
254 gst_device_reconfigure_element (GstDevice * device, GstElement * element)
255 {
256   GstDeviceClass *klass = GST_DEVICE_GET_CLASS (device);
257
258   if (klass->reconfigure_element)
259     return klass->reconfigure_element (device, element);
260   else
261     return FALSE;
262 }
263
264 /**
265  * gst_device_has_classesv:
266  * @device: a #GstDevice
267  * @classes: a %NULL terminated array of klasses to match, only match if all
268  *  classes are matched
269  *
270  * Check if @factory matches all of the given classes
271  *
272  * Returns: %TRUE if @device matches.
273  *
274  * Since: 1.4
275  */
276 gboolean
277 gst_device_has_classesv (GstDevice * device, gchar ** classes)
278 {
279   g_return_val_if_fail (GST_IS_DEVICE (device), FALSE);
280
281
282   for (; classes[0]; classes++) {
283     const gchar *found;
284     guint len;
285
286     if (classes[0] == '\0')
287       continue;
288
289     found = strstr (device->priv->klass, classes[0]);
290
291     if (!found)
292       return FALSE;
293     if (found != device->priv->klass && *(found - 1) != '/')
294       return FALSE;
295
296     len = strlen (classes[0]);
297     if (found[len] != 0 && found[len] != '/')
298       return FALSE;
299   }
300
301   return TRUE;
302 }
303
304 /**
305  * gst_device_has_classes:
306  * @device: a #GstDevice
307  * @classes: a "/" separate list of klasses to match, only match if all classes
308  *  are matched
309  *
310  * Check if @device matches all of the given classes
311  *
312  * Returns: %TRUE if @device matches.
313  *
314  * Since: 1.4
315  */
316 gboolean
317 gst_device_has_classes (GstDevice * device, const gchar * classes)
318 {
319   gchar **classesv;
320   gboolean res;
321
322   classesv = g_strsplit (classes, "/", 0);
323
324   res = gst_device_has_classesv (device, classesv);
325
326   g_strfreev (classesv);
327
328   return res;
329 }