1 /*
2 * Copyright (C) 2012,2013 Intel Corporation.
3 *
4 * Authors: Krzesimir Nowak <krnowak@openismus.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif /* HAVE_CONFIG_H_ */
25 #include "gupnp-dlna-gst-audio-information.h"
26 #include "gupnp-dlna-gst-info-utils.h"
27
28 G_DEFINE_TYPE (GUPnPDLNAGstAudioInformation,
29 gupnp_dlna_gst_audio_information,
30 GUPNP_TYPE_DLNA_AUDIO_INFORMATION)
31
32 struct _GUPnPDLNAGstAudioInformationPrivate {
33 GstDiscovererInfo *info;
34 GList *stream_list;
35 GstDiscovererAudioInfo *audio_info;
36 GstCaps *caps;
37 };
38
39 enum
40 {
41 PROP_0,
42
43 PROP_INFO
44 };
45
46 static GstDiscovererAudioInfo *
get_audio_info(GUPnPDLNAGstAudioInformation * gst_info)47 get_audio_info (GUPnPDLNAGstAudioInformation *gst_info)
48 {
49 GUPnPDLNAGstAudioInformationPrivate *priv = gst_info->priv;
50
51 if (!priv->audio_info) {
52 GList *iter;
53
54 if (!priv->stream_list) {
55 priv->stream_list =
56 gst_discoverer_info_get_stream_list (priv->info);
57 if (!priv->stream_list)
58 return NULL;
59 }
60
61 for (iter = priv->stream_list; iter; iter = iter->next) {
62 GstDiscovererStreamInfo *stream =
63 GST_DISCOVERER_STREAM_INFO (iter->data);
64 GType stream_type = G_TYPE_FROM_INSTANCE (stream);
65
66 if (stream_type == GST_TYPE_DISCOVERER_AUDIO_INFO) {
67 priv->audio_info =
68 GST_DISCOVERER_AUDIO_INFO (stream);
69
70 break;
71 }
72 }
73 }
74
75 return priv->audio_info;
76 }
77
78 static GstCaps *
get_caps(GUPnPDLNAGstAudioInformation * gst_info)79 get_caps (GUPnPDLNAGstAudioInformation *gst_info)
80 {
81 GUPnPDLNAGstAudioInformationPrivate *priv = gst_info->priv;
82
83 if (!priv->caps)
84 priv->caps = gst_discoverer_stream_info_get_caps
85 (GST_DISCOVERER_STREAM_INFO (get_audio_info (gst_info)));
86
87 return priv->caps;
88 }
89
90 static GUPnPDLNAIntValue
get_int_value(GUPnPDLNAGstAudioInformation * gst_info,const gchar * name)91 get_int_value (GUPnPDLNAGstAudioInformation *gst_info,
92 const gchar *name)
93 {
94 GstCaps *caps = get_caps (gst_info);
95 GstDiscovererStreamInfo *stream =
96 GST_DISCOVERER_STREAM_INFO (get_audio_info (gst_info));
97 GstDiscovererInfo *info = gst_info->priv->info;
98
99 return gupnp_dlna_gst_get_int_value (caps, stream, info, name);
100 }
101
102 static GUPnPDLNAStringValue
get_string_value(GUPnPDLNAGstAudioInformation * gst_info,const gchar * name)103 get_string_value (GUPnPDLNAGstAudioInformation *gst_info,
104 const gchar *name)
105 {
106 GstCaps *caps = get_caps (gst_info);
107 GstDiscovererStreamInfo *stream =
108 GST_DISCOVERER_STREAM_INFO (get_audio_info (gst_info));
109 GstDiscovererInfo *info = gst_info->priv->info;
110
111 return gupnp_dlna_gst_get_string_value (caps, stream, info, name);
112 }
113
114 static GUPnPDLNAIntValue
backend_get_bitrate(GUPnPDLNAAudioInformation * self)115 backend_get_bitrate (GUPnPDLNAAudioInformation *self)
116 {
117 GUPnPDLNAGstAudioInformation* gst_info =
118 GUPNP_DLNA_GST_AUDIO_INFORMATION (self);
119 GstDiscovererAudioInfo *audio_info = get_audio_info (gst_info);
120 guint data = gst_discoverer_audio_info_get_bitrate (audio_info);
121 GUPnPDLNAIntValue value = GUPNP_DLNA_INT_VALUE_UNSET;
122
123 if (data > 0 && data <= G_MAXINT) {
124 value.state = GUPNP_DLNA_VALUE_STATE_SET;
125 value.value = (gint) data;
126 }
127
128 return value;
129 }
130
131 static GUPnPDLNAIntValue
backend_get_channels(GUPnPDLNAAudioInformation * self)132 backend_get_channels (GUPnPDLNAAudioInformation *self)
133 {
134 GUPnPDLNAGstAudioInformation* gst_info =
135 GUPNP_DLNA_GST_AUDIO_INFORMATION (self);
136 GstDiscovererAudioInfo *audio_info = get_audio_info (gst_info);
137 guint data = gst_discoverer_audio_info_get_channels (audio_info);
138 GUPnPDLNAIntValue value = GUPNP_DLNA_INT_VALUE_UNSET;
139
140 if (data > 0 && data <= G_MAXINT) {
141 value.state = GUPNP_DLNA_VALUE_STATE_SET;
142 value.value = (gint) data;
143 }
144
145 return value;
146 }
147
148 static GUPnPDLNAIntValue
backend_get_depth(GUPnPDLNAAudioInformation * self)149 backend_get_depth (GUPnPDLNAAudioInformation *self)
150 {
151 GUPnPDLNAGstAudioInformation* gst_info =
152 GUPNP_DLNA_GST_AUDIO_INFORMATION (self);
153 GstDiscovererAudioInfo *audio_info = get_audio_info (gst_info);
154 guint data = gst_discoverer_audio_info_get_depth (audio_info);
155 GUPnPDLNAIntValue value = GUPNP_DLNA_INT_VALUE_UNSET;
156
157 if (data > 0 && data <= G_MAXINT) {
158 value.state = GUPNP_DLNA_VALUE_STATE_SET;
159 value.value = (gint) data;
160 }
161
162 return value;
163 }
164
165 static GUPnPDLNAIntValue
backend_get_layer(GUPnPDLNAAudioInformation * self)166 backend_get_layer (GUPnPDLNAAudioInformation *self)
167 {
168 GUPnPDLNAGstAudioInformation* gst_info =
169 GUPNP_DLNA_GST_AUDIO_INFORMATION (self);
170
171 return get_int_value (gst_info, "layer");
172 }
173
174 static GUPnPDLNAStringValue
backend_get_level(GUPnPDLNAAudioInformation * self)175 backend_get_level (GUPnPDLNAAudioInformation *self)
176 {
177 GUPnPDLNAGstAudioInformation* gst_info =
178 GUPNP_DLNA_GST_AUDIO_INFORMATION (self);
179 return get_string_value (gst_info, "level");
180 }
181
182 static GUPnPDLNAIntValue
backend_get_mpeg_audio_version(GUPnPDLNAAudioInformation * self)183 backend_get_mpeg_audio_version (GUPnPDLNAAudioInformation *self)
184 {
185 GUPnPDLNAGstAudioInformation* gst_info =
186 GUPNP_DLNA_GST_AUDIO_INFORMATION (self);
187
188 return get_int_value (gst_info, "mpegaudioversion");
189 }
190
191 static GUPnPDLNAIntValue
backend_get_mpeg_version(GUPnPDLNAAudioInformation * self)192 backend_get_mpeg_version (GUPnPDLNAAudioInformation *self)
193 {
194 GUPnPDLNAGstAudioInformation* gst_info =
195 GUPNP_DLNA_GST_AUDIO_INFORMATION (self);
196
197 return get_int_value (gst_info, "mpegversion");
198 }
199
200 static GUPnPDLNAStringValue
backend_get_profile(GUPnPDLNAAudioInformation * self)201 backend_get_profile (GUPnPDLNAAudioInformation *self)
202 {
203 GUPnPDLNAGstAudioInformation* gst_info =
204 GUPNP_DLNA_GST_AUDIO_INFORMATION (self);
205
206 return get_string_value (gst_info, "profile");
207 }
208
209 static GUPnPDLNAIntValue
backend_get_rate(GUPnPDLNAAudioInformation * self)210 backend_get_rate (GUPnPDLNAAudioInformation *self)
211 {
212 GUPnPDLNAGstAudioInformation* gst_info =
213 GUPNP_DLNA_GST_AUDIO_INFORMATION (self);
214 GstDiscovererAudioInfo *audio_info = get_audio_info (gst_info);
215 guint data = gst_discoverer_audio_info_get_sample_rate (audio_info);
216 GUPnPDLNAIntValue value = GUPNP_DLNA_INT_VALUE_UNSET;
217
218 if (data > 0 && data <= G_MAXINT) {
219 value.state = GUPNP_DLNA_VALUE_STATE_SET;
220 value.value = (gint) data;
221 }
222
223 return value;
224 }
225
226 static GUPnPDLNAStringValue
backend_get_stream_format(GUPnPDLNAAudioInformation * self)227 backend_get_stream_format (GUPnPDLNAAudioInformation *self)
228 {
229 GUPnPDLNAGstAudioInformation* gst_info =
230 GUPNP_DLNA_GST_AUDIO_INFORMATION (self);
231
232 return get_string_value (gst_info, "stream-format");
233 }
234
235 static GUPnPDLNAIntValue
backend_get_wma_version(GUPnPDLNAAudioInformation * self)236 backend_get_wma_version (GUPnPDLNAAudioInformation *self)
237 {
238 GUPnPDLNAGstAudioInformation* gst_info =
239 GUPNP_DLNA_GST_AUDIO_INFORMATION (self);
240
241 return get_int_value (gst_info, "wmaversion");
242 }
243
244 static GUPnPDLNAStringValue
backend_get_mime(GUPnPDLNAAudioInformation * self)245 backend_get_mime (GUPnPDLNAAudioInformation *self)
246 {
247 GUPnPDLNAGstAudioInformation* gst_info =
248 GUPNP_DLNA_GST_AUDIO_INFORMATION (self);
249
250 return gupnp_dlna_gst_get_mime (get_caps (gst_info));
251 }
252
253 static void
gupnp_dlna_gst_audio_information_dispose(GObject * object)254 gupnp_dlna_gst_audio_information_dispose (GObject *object)
255 {
256 GUPnPDLNAGstAudioInformation *info =
257 GUPNP_DLNA_GST_AUDIO_INFORMATION (object);
258 GUPnPDLNAGstAudioInformationPrivate *priv = info->priv;
259 GObjectClass *parent_class =
260 G_OBJECT_CLASS (gupnp_dlna_gst_audio_information_parent_class);
261
262 g_clear_pointer (&priv->info, gupnp_dlna_gst_discoverer_info_unref);
263 g_clear_pointer (&priv->stream_list,
264 gst_discoverer_stream_info_list_free);
265 /* priv->audio_info is freed with stream list above */
266 priv->audio_info = NULL;
267 g_clear_pointer (&priv->caps, gst_caps_unref);
268 parent_class->dispose (object);
269 }
270
271 static void
gupnp_dlna_gst_audio_information_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)272 gupnp_dlna_gst_audio_information_set_property (GObject *object,
273 guint property_id,
274 const GValue *value,
275 GParamSpec *pspec)
276 {
277 GUPnPDLNAGstAudioInformation *info =
278 GUPNP_DLNA_GST_AUDIO_INFORMATION (object);
279 GUPnPDLNAGstAudioInformationPrivate *priv = info->priv;
280
281 switch (property_id) {
282 case PROP_INFO:
283 g_clear_pointer (&priv->info,
284 gupnp_dlna_gst_discoverer_info_unref);
285 priv->info =
286 GST_DISCOVERER_INFO (gst_value_dup_mini_object (value));
287 break;
288
289 default:
290 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
291 break;
292 }
293 }
294
295 static void
gupnp_dlna_gst_audio_information_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)296 gupnp_dlna_gst_audio_information_get_property (GObject *object,
297 guint property_id,
298 GValue *value,
299 GParamSpec *pspec)
300 {
301 GUPnPDLNAGstAudioInformation *info =
302 GUPNP_DLNA_GST_AUDIO_INFORMATION (object);
303 GUPnPDLNAGstAudioInformationPrivate *priv = info->priv;
304
305 switch (property_id) {
306 case PROP_INFO:
307 gst_value_set_mini_object (value, GST_MINI_OBJECT (priv->info));
308 break;
309
310 default:
311 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
312 break;
313 }
314 }
315
316 static void
gupnp_dlna_gst_audio_information_class_init(GUPnPDLNAGstAudioInformationClass * gst_info_class)317 gupnp_dlna_gst_audio_information_class_init
318 (GUPnPDLNAGstAudioInformationClass *gst_info_class)
319 {
320 GUPnPDLNAAudioInformationClass *info_class =
321 GUPNP_DLNA_AUDIO_INFORMATION_CLASS (gst_info_class);
322 GObjectClass *object_class = G_OBJECT_CLASS (gst_info_class);
323 GParamSpec *pspec;
324
325 object_class->get_property =
326 gupnp_dlna_gst_audio_information_get_property;
327 object_class->set_property =
328 gupnp_dlna_gst_audio_information_set_property;
329 object_class->dispose = gupnp_dlna_gst_audio_information_dispose;
330
331 info_class->get_bitrate = backend_get_bitrate;
332 info_class->get_channels = backend_get_channels;
333 info_class->get_depth = backend_get_depth;
334 info_class->get_layer = backend_get_layer;
335 info_class->get_level = backend_get_level;
336 info_class->get_mpeg_audio_version = backend_get_mpeg_audio_version;
337 info_class->get_mpeg_version = backend_get_mpeg_version;
338 info_class->get_profile = backend_get_profile;
339 info_class->get_rate = backend_get_rate;
340 info_class->get_stream_format = backend_get_stream_format;
341 info_class->get_wma_version = backend_get_wma_version;
342 info_class->get_mime = backend_get_mime;
343
344 pspec = gst_param_spec_mini_object ("info",
345 "info",
346 "discoverer info",
347 GST_TYPE_DISCOVERER_INFO,
348 G_PARAM_READWRITE |
349 G_PARAM_CONSTRUCT);
350 g_object_class_install_property (object_class,
351 PROP_INFO,
352 pspec);
353
354 g_type_class_add_private (gst_info_class,
355 sizeof (GUPnPDLNAGstAudioInformationPrivate));
356 }
357
358 static void
gupnp_dlna_gst_audio_information_init(GUPnPDLNAGstAudioInformation * self)359 gupnp_dlna_gst_audio_information_init (GUPnPDLNAGstAudioInformation *self)
360 {
361 GUPnPDLNAGstAudioInformationPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE
362 (self,
363 GUPNP_TYPE_DLNA_GST_AUDIO_INFORMATION,
364 GUPnPDLNAGstAudioInformationPrivate);
365
366 priv->info = NULL;
367 priv->stream_list = NULL;
368 priv->audio_info = NULL;
369 priv->caps = NULL;
370 self->priv = priv;
371 }
372
373 GUPnPDLNAGstAudioInformation *
gupnp_dlna_gst_audio_information_new_from_discoverer_info(GstDiscovererInfo * info)374 gupnp_dlna_gst_audio_information_new_from_discoverer_info (GstDiscovererInfo *info)
375 {
376 GList* audio_list;
377 GUPnPDLNAGstAudioInformation *audio_info = NULL;
378
379 g_return_val_if_fail (GST_IS_DISCOVERER_INFO (info), NULL);
380
381 audio_list = gst_discoverer_info_get_audio_streams (info);
382
383 if (audio_list) {
384 audio_info = GUPNP_DLNA_GST_AUDIO_INFORMATION (g_object_new
385 (GUPNP_TYPE_DLNA_GST_AUDIO_INFORMATION,
386 "info", info,
387 NULL));
388 gst_discoverer_stream_info_list_free (audio_list);
389 }
390
391 return audio_info;
392 }
393