devicemonitor: Add GstDeviceMonitor and related
[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/gst_private.h"
27
28 #include <gst/gstdevice.h>
29 #include <gst/gst.h>
30
31 enum
32 {
33   PROP_DISPLAY_NAME = 1,
34   PROP_CAPS
35 };
36
37 enum
38 {
39   REMOVED,
40   LAST_SIGNAL
41 };
42
43 struct _GstDevicePrivate
44 {
45   GstCaps *caps;
46   gchar *display_name;
47 };
48
49
50 static guint signals[LAST_SIGNAL];
51
52 G_DEFINE_ABSTRACT_TYPE (GstDevice, gst_device, GST_TYPE_OBJECT);
53
54 static void gst_device_get_property (GObject * object, guint property_id,
55     GValue * value, GParamSpec * pspec);
56 static void gst_device_set_property (GObject * object, guint property_id,
57     const GValue * value, GParamSpec * pspec);
58 static void gst_device_finalize (GObject * object);
59
60
61 static void
62 gst_device_class_init (GstDeviceClass * klass)
63 {
64   GObjectClass *object_class = G_OBJECT_CLASS (klass);
65
66   g_type_class_add_private (klass, sizeof (GstDevicePrivate));
67
68   object_class->get_property = gst_device_get_property;
69   object_class->set_property = gst_device_set_property;
70   object_class->finalize = gst_device_finalize;
71
72   g_object_class_install_property (object_class, PROP_DISPLAY_NAME,
73       g_param_spec_string ("display-name", "Display Name",
74           "The user-friendly name of the device", "",
75           G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
76   g_object_class_install_property (object_class, PROP_CAPS,
77       g_param_spec_boxed ("caps", "Device Caps",
78           "The possible caps of a device", GST_TYPE_CAPS,
79           G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
80
81   signals[REMOVED] = g_signal_new ("removed", G_TYPE_FROM_CLASS (klass),
82       G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
83 }
84
85 static void
86 gst_device_init (GstDevice * device)
87 {
88   device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device, GST_TYPE_DEVICE,
89       GstDevicePrivate);
90 }
91
92 static void
93 gst_device_finalize (GObject * object)
94 {
95   GstDevice *device = GST_DEVICE (object);
96
97   gst_caps_replace (&device->priv->caps, NULL);
98
99   g_free (device->priv->display_name);
100
101   G_OBJECT_CLASS (gst_device_parent_class)->finalize (object);
102 }
103
104 static void
105 gst_device_get_property (GObject * object, guint prop_id,
106     GValue * value, GParamSpec * pspec)
107 {
108   GstDevice *gstdevice;
109
110   gstdevice = GST_DEVICE_CAST (object);
111
112   switch (prop_id) {
113     case PROP_DISPLAY_NAME:
114       g_value_take_string (value, gst_device_get_display_name (gstdevice));
115       break;
116     case PROP_CAPS:
117       if (gstdevice->priv->caps)
118         g_value_take_boxed (value, gst_device_get_caps (gstdevice));
119       break;
120     default:
121       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
122       break;
123   }
124 }
125
126
127 static void
128 gst_device_set_property (GObject * object, guint prop_id,
129     const GValue * value, GParamSpec * pspec)
130 {
131   GstDevice *gstdevice;
132
133   gstdevice = GST_DEVICE_CAST (object);
134
135   switch (prop_id) {
136     case PROP_DISPLAY_NAME:
137       gstdevice->priv->display_name = g_value_dup_string (value);
138       break;
139     case PROP_CAPS:
140       gst_caps_replace (&gstdevice->priv->caps, g_value_get_boxed (value));
141       break;
142     default:
143       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
144       break;
145   }
146 }
147
148 /**
149  * gst_device_create_element:
150  * @device: a #GstDevice
151  * @name: (allow-none): name of new element, or NULL to automatically
152  * create a unique name.
153  *
154  * Returns: (transfer full): a new #GstElement configured to use this device
155  *
156  * Since: 1.4
157  */
158 GstElement *
159 gst_device_create_element (GstDevice * device, const gchar * name)
160 {
161   GstDeviceClass *klass = GST_DEVICE_GET_CLASS (device);
162
163   if (klass->create_element)
164     return klass->create_element (device, name);
165   else
166     return NULL;
167 }
168
169 /**
170  * gst_device_get_caps:
171  * @device: a #GstDevice
172  *
173  * Getter for the #GstCaps that this device supports.
174  *
175  * Returns: The #GstCaps supported by this device. Unref with
176  * gst_caps_unref() when done.
177  *
178  * Since: 1.4
179  */
180 GstCaps *
181 gst_device_get_caps (GstDevice * device)
182 {
183   if (device->priv->caps)
184     return gst_caps_ref (device->priv->caps);
185   else
186     return NULL;
187 }
188
189 /**
190  * gst_device_get_display_name:
191  * @device: a #GstDevice
192  *
193  * Gets the user-friendly name of the device.
194  *
195  * Returns: The device name. Free with g_free() after use.
196  *
197  * Since: 1.4
198  */
199 gchar *
200 gst_device_get_display_name (GstDevice * device)
201 {
202   return g_strdup (device->priv->display_name);
203 }
204
205 /**
206  * gst_device_reconfigure_element:
207  * @device: a #GstDevice
208  * @element: a #GstElement
209  *
210  * Tries to reconfigure an existing element to use the device. If this
211  * function fails, then one must destroy the element and create a new one
212  * using gst_device_create_element().
213  *
214  * Note: This should only be implemented for elements can change their
215  * device in the PLAYING state.
216  *
217  * Returns: %TRUE if the element could be reconfigured to use this device,
218  * %FALSE otherwise.
219  *
220  * Since: 1.4
221  */
222 gboolean
223 gst_device_reconfigure_element (GstDevice * device, GstElement * element)
224 {
225   GstDeviceClass *klass = GST_DEVICE_GET_CLASS (device);
226
227   if (klass->reconfigure_element)
228     return klass->reconfigure_element (device, element);
229   else
230     return FALSE;
231 }