Free caps in GUPnPDLNAProfilePriv
[gupnp:gupnp-dlna.git] / libgupnp-dlna / gupnp-dlna-profile.c
1 /*
2  * Copyright (C) 2010 Nokia Corporation.
3  *
4  * Authors: Arun Raghavan <arun.raghavan@collabora.co.uk>
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., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #include "gupnp-dlna-profile.h"
23 #include <gst/gstminiobject.h>
24
25 /**
26  * SECTION:gupnp-dlna-profile
27  * @short_description: Object representing a DLNA profile
28  *
29  * The #GUPnPDLNADiscoverer object provides a few APIs that return
30  * #GUPnPDLNAProfile objects. These represent a single DLNA profile. Each
31  * #GUPnPDLNAProfile has a name (the name of the DLNA profile), the
32  * corresponding MIME type, and a #GstEncodingProfile which represents the
33  * various audio/video/container restrictions specified for that DLNA profile.
34  */
35 G_DEFINE_TYPE (GUPnPDLNAProfile, gupnp_dlna_profile, G_TYPE_OBJECT)
36
37 #define GET_PRIVATE(o)                                          \
38         (G_TYPE_INSTANCE_GET_PRIVATE ((o),                      \
39                                       GUPNP_TYPE_DLNA_PROFILE,  \
40                                       GUPnPDLNAProfilePrivate))
41
42 typedef struct _GUPnPDLNAProfilePrivate GUPnPDLNAProfilePrivate;
43
44 struct _GUPnPDLNAProfilePrivate {
45         gchar              *name;
46         gchar              *mime;
47         GstCaps            *container_caps;
48         GstCaps            *video_caps;
49         GstCaps            *audio_caps;
50         gboolean           extended;
51         GstEncodingProfile *enc_profile;
52 };
53
54 enum {
55         PROP_0,
56         PROP_DLNA_NAME,
57         PROP_DLNA_MIME,
58         PROP_ENCODING_PROFILE,
59         PROP_DLNA_EXTENDED,
60 };
61
62 static void
63 gupnp_dlna_profile_get_property (GObject    *object,
64                                  guint       property_id,
65                                  GValue     *value,
66                                  GParamSpec *pspec)
67 {
68         GUPnPDLNAProfile *self = GUPNP_DLNA_PROFILE (object);
69         GUPnPDLNAProfilePrivate *priv = GET_PRIVATE (self);
70
71         switch (property_id) {
72                 case PROP_DLNA_NAME:
73                         g_value_set_string (value, priv->name);
74                         break;
75
76                 case PROP_DLNA_MIME:
77                         g_value_set_string (value, priv->mime);
78                         break;
79
80                 case PROP_ENCODING_PROFILE:
81                         gst_value_set_mini_object (value,
82                                         GST_MINI_OBJECT (priv->enc_profile));
83                         break;
84
85                 case PROP_DLNA_EXTENDED:
86                         g_value_set_boolean (value, priv->extended);
87                         break;
88
89                 default:
90                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
91                                                            property_id,
92                                                            pspec);
93                         break;
94         }
95 }
96
97 static void
98 gupnp_dlna_profile_set_property (GObject      *object,
99                                  guint         property_id,
100                                  const GValue *value,
101                                  GParamSpec   *pspec)
102 {
103         GUPnPDLNAProfile *self = GUPNP_DLNA_PROFILE (object);
104         GUPnPDLNAProfilePrivate *priv = GET_PRIVATE (self);
105
106         switch (property_id) {
107                 case PROP_DLNA_NAME:
108                         g_free (priv->name);
109                         priv->name = g_value_dup_string (value);
110                         break;
111
112                 case PROP_DLNA_MIME:
113                         g_free (priv->mime);
114                         priv->mime = g_value_dup_string (value);
115                         break;
116
117                 case PROP_DLNA_EXTENDED:
118                         priv->extended = g_value_get_boolean (value);
119                         break;
120
121                 default:
122                         G_OBJECT_WARN_INVALID_PROPERTY_ID
123                                 (object, property_id, pspec);
124                         break;
125         }
126 }
127
128 static void
129 gupnp_dlna_profile_finalize (GObject *object)
130 {
131         GUPnPDLNAProfile *self = GUPNP_DLNA_PROFILE (object);
132         GUPnPDLNAProfilePrivate *priv = GET_PRIVATE (self);
133
134         g_free (priv->name);
135         g_free (priv->mime);
136
137         if (priv->container_caps)
138                 gst_caps_unref (priv->container_caps);
139         if (priv->audio_caps)
140                 gst_caps_unref (priv->audio_caps);
141         if (priv->video_caps)
142                 gst_caps_unref (priv->video_caps);
143
144         if (priv->enc_profile)
145                 gst_encoding_profile_unref (priv->enc_profile);
146
147         G_OBJECT_CLASS (gupnp_dlna_profile_parent_class)->finalize (object);
148 }
149
150 static void
151 gupnp_dlna_profile_class_init (GUPnPDLNAProfileClass *klass)
152 {
153         GObjectClass *object_class = G_OBJECT_CLASS (klass);
154         GParamSpec *pspec;
155
156         g_type_class_add_private (klass, sizeof (GUPnPDLNAProfilePrivate));
157
158         object_class->get_property = gupnp_dlna_profile_get_property;
159         object_class->set_property = gupnp_dlna_profile_set_property;
160         object_class->finalize = gupnp_dlna_profile_finalize;
161
162         pspec = g_param_spec_string ("name",
163                                      "DLNA profile name",
164                                      "The name of the DLNA profile ",
165                                      NULL,
166                                      G_PARAM_READWRITE |
167                                      G_PARAM_CONSTRUCT_ONLY);
168         g_object_class_install_property (object_class, PROP_DLNA_NAME, pspec);
169
170         pspec = g_param_spec_string ("mime",
171                                      "DLNA profile MIME type",
172                                      "The MIME type of the DLNA profile",
173                                      NULL,
174                                      G_PARAM_READWRITE |
175                                      G_PARAM_CONSTRUCT_ONLY);
176         g_object_class_install_property (object_class, PROP_DLNA_MIME, pspec);
177
178         pspec = gst_param_spec_mini_object ("encoding-profile",
179                                             "Encoding Profile for the "
180                                             "DLNA Profile",
181                                             "GstEncodingProfile object"
182                                             "corresponding to the DLNA profile",
183                                             GST_TYPE_ENCODING_PROFILE,
184                                             G_PARAM_READABLE);
185         g_object_class_install_property (object_class,
186                                          PROP_ENCODING_PROFILE,
187                                          pspec);
188
189         pspec = g_param_spec_boolean ("extended",
190                                       "Extended mode property",
191                                       "Indicates that this profile is not "
192                                       "part of the DLNA specification",
193                                       FALSE,
194                                       G_PARAM_READWRITE |
195                                       G_PARAM_CONSTRUCT_ONLY);
196         g_object_class_install_property (object_class,
197                                          PROP_DLNA_EXTENDED,
198                                          pspec);
199
200 }
201
202 static void
203 gupnp_dlna_profile_init (GUPnPDLNAProfile *self)
204 {
205         GUPnPDLNAProfilePrivate *priv = GET_PRIVATE (self);
206
207         priv->name = NULL;
208         priv->mime = NULL;
209         priv->enc_profile = NULL;
210         priv->extended = FALSE;
211 }
212
213 GstCaps *
214 gupnp_dlna_profile_get_container_caps (GUPnPDLNAProfile *self)
215 {
216         GUPnPDLNAProfilePrivate *priv = GET_PRIVATE (self);
217         return priv->container_caps;
218 }
219
220 GstCaps *
221 gupnp_dlna_profile_get_video_caps (GUPnPDLNAProfile *self)
222 {
223         GUPnPDLNAProfilePrivate *priv = GET_PRIVATE (self);
224         return priv->video_caps;
225 }
226
227 GstCaps *
228 gupnp_dlna_profile_get_audio_caps (GUPnPDLNAProfile *self)
229 {
230         GUPnPDLNAProfilePrivate *priv = GET_PRIVATE (self);
231         return priv->audio_caps;
232 }
233
234 void
235 gupnp_dlna_profile_set_container_caps (GUPnPDLNAProfile *self, GstCaps *caps)
236 {
237         GUPnPDLNAProfilePrivate *priv = GET_PRIVATE (self);
238
239         if (priv->container_caps)
240                 gst_caps_unref (priv->container_caps);
241         priv->container_caps = gst_caps_copy (caps);
242 }
243
244 void
245 gupnp_dlna_profile_set_video_caps (GUPnPDLNAProfile *self, GstCaps *caps)
246 {
247         GUPnPDLNAProfilePrivate *priv = GET_PRIVATE (self);
248
249         if (priv->video_caps)
250                 gst_caps_unref (priv->video_caps);
251         priv->video_caps = gst_caps_copy (caps);
252 }
253
254 void
255 gupnp_dlna_profile_set_audio_caps (GUPnPDLNAProfile *self, GstCaps *caps)
256 {
257         GUPnPDLNAProfilePrivate *priv = GET_PRIVATE (self);
258
259         if (priv->audio_caps)
260                 gst_caps_unref (priv->audio_caps);
261         priv->audio_caps = gst_caps_copy (caps);
262 }
263
264 /**
265  * gupnp_dlna_profile_new:
266  *
267  * Creates a new #GUPnPDLNAProfile object.
268  *
269  * Returns: A new #GUPnPDLNAProfile object.
270  */
271 GUPnPDLNAProfile *
272 gupnp_dlna_profile_new (gchar              *name,
273                         gchar              *mime,
274                         GstCaps            *container_caps,
275                         GstCaps            *video_caps,
276                         GstCaps            *audio_caps,
277                         gboolean           extended)
278 {
279         GUPnPDLNAProfile *prof;
280
281         prof =  g_object_new (GUPNP_TYPE_DLNA_PROFILE,
282                               "name", name,
283                               "mime", mime,
284                               "extended", extended,
285                               NULL);
286
287         gupnp_dlna_profile_set_container_caps (prof, container_caps);
288         gupnp_dlna_profile_set_video_caps (prof, video_caps);
289         gupnp_dlna_profile_set_audio_caps (prof, audio_caps);
290
291         return prof;
292 }
293
294 /**
295  * gupnp_dlna_profile_get_name:
296  * @self: The #GUPnPDLNAProfile object
297  *
298  * Returns: the name of the DLNA profile represented by @self
299  */
300 const gchar *
301 gupnp_dlna_profile_get_name (GUPnPDLNAProfile *self)
302 {
303         GUPnPDLNAProfilePrivate *priv = GET_PRIVATE (self);
304         return priv->name;
305 }
306
307 /**
308  * gupnp_dlna_profile_get_mime:
309  * @self: The #GUPnPDLNAProfile object
310  *
311  * Returns: the DLNA MIME type of the DLNA profile represented by @self
312  */
313 const gchar *
314 gupnp_dlna_profile_get_mime (GUPnPDLNAProfile *self)
315 {
316         GUPnPDLNAProfilePrivate *priv = GET_PRIVATE (self);
317         return priv->mime;
318 }
319
320 /**
321  * gupnp_dlna_profile_get_encoding_profile:
322  * @self: The #GUPnPDLNAProfile object
323  *
324  * Returns: a #GstEncodingProfile object that, in a future version, can be used
325  *          to transcode a given stream to match the DLNA profile represented
326  *          by @self.
327  */
328 GstEncodingProfile *
329 gupnp_dlna_profile_get_encoding_profile (GUPnPDLNAProfile *self)
330 {
331         GUPnPDLNAProfilePrivate *priv = GET_PRIVATE (self);
332
333         /* check if we have it cached already */
334         if (priv->enc_profile) {
335                 gst_encoding_profile_ref (priv->enc_profile);
336         } else {
337                 /* create an encoding-profile */
338                 if (GST_IS_CAPS (priv->container_caps)) {
339                         priv->enc_profile = (GstEncodingProfile *)
340                                 gst_encoding_container_profile_new
341                                         (priv->name,
342                                          priv->mime,
343                                          priv->container_caps,
344                                          NULL);
345
346                         if (GST_IS_CAPS (priv->video_caps) &&
347                             !gst_caps_is_empty (priv->video_caps))
348                                 gst_encoding_container_profile_add_profile
349                                         ((GstEncodingContainerProfile *)priv->enc_profile,
350                                          (GstEncodingProfile *)gst_encoding_video_profile_new
351                                          (priv->video_caps, NULL, NULL, 0));
352
353
354                         if (GST_IS_CAPS (priv->audio_caps) &&
355                             !gst_caps_is_empty (priv->audio_caps))
356                                 gst_encoding_container_profile_add_profile
357                                         ((GstEncodingContainerProfile *)priv->enc_profile,
358                                          (GstEncodingProfile *)gst_encoding_audio_profile_new
359                                          (priv->audio_caps, NULL, NULL, 0));
360
361                 }
362         }
363
364         return (GstEncodingProfile *)priv->enc_profile;
365 }
366
367 /**
368  * gupnp_dlna_profile_get_extended:
369  * @self: The #GUPnPDLNAProfile object
370  *
371  * Returns: true if application is using extended mode and false otherwise
372  */
373 gboolean
374 gupnp_dlna_profile_get_extended (GUPnPDLNAProfile *self)
375 {
376         GUPnPDLNAProfilePrivate *priv = GET_PRIVATE (self);
377         return priv->extended;
378 }