tizen 2.3 release
[framework/multimedia/gst-plugins-base0.10.git] / gst-libs / gst / tag / xmpwriter.c
1 /* GStreamer TagXmpWriter
2  * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /**
21  * SECTION:gsttagxmpwriter
22  * @short_description: Interface for elements that provide XMP serialization
23  *
24  * <refsect2>
25  * <para>
26  * This interface is implemented by elements that are able to do XMP serialization. Examples for
27  * such elements are #jifmux and #qtmux.
28  * </para>
29  * <para>
30  * Applications can use this interface to configure which XMP schemas should be used when serializing
31  * tags into XMP. Schemas are represented by their names, a full list of the supported schemas can be
32  * obtained from gst_tag_xmp_list_schemas(). By default, all schemas are used.
33  * </para>
34  * </refsect2>
35  */
36
37 #ifdef HAVE_CONFIG_H
38 #include "config.h"
39 #endif
40
41 #include "xmpwriter.h"
42 #include <string.h>
43 #include <gst/tag/tag.h>
44
45 static GQuark tag_xmp_writer_key;
46
47 typedef struct
48 {
49   GSList *schemas;
50 #if !GLIB_CHECK_VERSION (2, 31, 0)
51   GStaticMutex lock;
52 #else
53   GMutex lock;
54 #endif
55 } GstTagXmpWriterData;
56
57 #if !GLIB_CHECK_VERSION (2, 31, 0)
58 #define GST_TAG_XMP_WRITER_DATA_LOCK(data) g_static_mutex_lock(&data->lock)
59 #define GST_TAG_XMP_WRITER_DATA_UNLOCK(data) g_static_mutex_unlock(&data->lock)
60 #else
61 #define GST_TAG_XMP_WRITER_DATA_LOCK(data) g_mutex_lock(&data->lock)
62 #define GST_TAG_XMP_WRITER_DATA_UNLOCK(data) g_mutex_unlock(&data->lock)
63 #endif
64
65 GType
66 gst_tag_xmp_writer_get_type (void)
67 {
68   static volatile gsize xmp_config_type = 0;
69
70   if (g_once_init_enter (&xmp_config_type)) {
71     GType _type;
72     static const GTypeInfo xmp_config_info = {
73       sizeof (GstTagXmpWriterInterface),        /* class_size */
74       NULL,                     /* base_init */
75       NULL,                     /* base_finalize */
76       NULL,
77       NULL,                     /* class_finalize */
78       NULL,                     /* class_data */
79       0,
80       0,
81       NULL
82     };
83
84     _type = g_type_register_static (G_TYPE_INTERFACE, "GstTagXmpWriter",
85         &xmp_config_info, 0);
86     tag_xmp_writer_key = g_quark_from_static_string ("GST_TAG_XMP_WRITER");
87     g_type_interface_add_prerequisite (_type, GST_TYPE_ELEMENT);
88
89     g_once_init_leave (&xmp_config_type, _type);
90   }
91
92   return xmp_config_type;
93 }
94
95 static void
96 gst_tag_xmp_writer_data_add_schema_unlocked (GstTagXmpWriterData * data,
97     const gchar * schema)
98 {
99   if (!g_slist_find_custom (data->schemas, schema, (GCompareFunc) strcmp)) {
100     data->schemas = g_slist_prepend (data->schemas, g_strdup (schema));
101   }
102 }
103
104 static void
105 gst_tag_xmp_writer_data_add_all_schemas_unlocked (GstTagXmpWriterData * data)
106 {
107   const gchar **schemas;
108   gint i = 0;
109
110   /* initialize it with all schemas */
111   schemas = gst_tag_xmp_list_schemas ();
112   while (schemas[i] != NULL) {
113     gst_tag_xmp_writer_data_add_schema_unlocked (data, schemas[i]);
114     i++;
115   }
116 }
117
118
119 static void
120 gst_tag_xmp_writer_data_free (gpointer p)
121 {
122   GstTagXmpWriterData *data = (GstTagXmpWriterData *) p;
123   GSList *iter;
124
125   if (data->schemas) {
126     for (iter = data->schemas; iter; iter = g_slist_next (iter)) {
127       g_free (iter->data);
128     }
129     g_slist_free (data->schemas);
130   }
131 #if !GLIB_CHECK_VERSION (2, 31, 0)
132   g_static_mutex_free (&data->lock);
133 #else
134   g_mutex_clear (&data->lock);
135 #endif
136
137   g_slice_free (GstTagXmpWriterData, data);
138 }
139
140 static GstTagXmpWriterData *
141 gst_tag_xmp_writer_get_data (GstTagXmpWriter * xmpconfig)
142 {
143   GstTagXmpWriterData *data;
144
145   data = g_object_get_qdata (G_OBJECT (xmpconfig), tag_xmp_writer_key);
146   if (!data) {
147     /* make sure no other thread is creating a GstTagData at the same time */
148 #if !GLIB_CHECK_VERSION (2, 31, 0)
149     static GStaticMutex create_mutex = G_STATIC_MUTEX_INIT;
150
151     g_static_mutex_lock (&create_mutex);
152 #else
153     static GMutex create_mutex; /* no initialisation required */
154
155     g_mutex_lock (&create_mutex);
156 #endif
157
158     data = g_object_get_qdata (G_OBJECT (xmpconfig), tag_xmp_writer_key);
159     if (!data) {
160       data = g_slice_new (GstTagXmpWriterData);
161
162 #if !GLIB_CHECK_VERSION (2, 31, 0)
163       g_static_mutex_init (&data->lock);
164 #else
165       g_mutex_init (&data->lock);
166 #endif
167       data->schemas = NULL;
168       gst_tag_xmp_writer_data_add_all_schemas_unlocked (data);
169
170       g_object_set_qdata_full (G_OBJECT (xmpconfig), tag_xmp_writer_key, data,
171           gst_tag_xmp_writer_data_free);
172     }
173 #if !GLIB_CHECK_VERSION (2, 31, 0)
174     g_static_mutex_unlock (&create_mutex);
175 #else
176     g_mutex_unlock (&create_mutex);
177 #endif
178   }
179
180   return data;
181 }
182
183 /**
184  * gst_tag_xmp_writer_add_all_schemas:
185  * @config: a #GstTagXmpWriter
186  *
187  * Adds all available XMP schemas to the configuration. Meaning that
188  * all will be used.
189  *
190  * Since: 0.10.33
191  */
192 void
193 gst_tag_xmp_writer_add_all_schemas (GstTagXmpWriter * config)
194 {
195   GstTagXmpWriterData *data;
196
197   g_return_if_fail (GST_IS_TAG_XMP_WRITER (config));
198
199   data = gst_tag_xmp_writer_get_data (config);
200
201   GST_TAG_XMP_WRITER_DATA_LOCK (data);
202   gst_tag_xmp_writer_data_add_all_schemas_unlocked (data);
203   GST_TAG_XMP_WRITER_DATA_UNLOCK (data);
204 }
205
206 /**
207  * gst_tag_xmp_writer_add_schema:
208  * @config: a #GstTagXmpWriter
209  * @schema: the schema to be added
210  *
211  * Adds @schema to the list schemas
212  *
213  * Since: 0.10.33
214  */
215 void
216 gst_tag_xmp_writer_add_schema (GstTagXmpWriter * config, const gchar * schema)
217 {
218   GstTagXmpWriterData *data;
219
220   g_return_if_fail (GST_IS_TAG_XMP_WRITER (config));
221
222   data = gst_tag_xmp_writer_get_data (config);
223
224   GST_TAG_XMP_WRITER_DATA_LOCK (data);
225   gst_tag_xmp_writer_data_add_schema_unlocked (data, schema);
226   GST_TAG_XMP_WRITER_DATA_UNLOCK (data);
227 }
228
229 /**
230  * gst_tag_xmp_writer_has_schema:
231  * @config: a #GstTagXmpWriter
232  * @schema: the schema to test
233  *
234  * Checks if @schema is going to be used
235  *
236  * Returns: %TRUE if it is going to be used
237  * Since: 0.10.33
238  */
239 gboolean
240 gst_tag_xmp_writer_has_schema (GstTagXmpWriter * config, const gchar * schema)
241 {
242   GstTagXmpWriterData *data;
243   gboolean ret = FALSE;
244   GSList *iter;
245
246   g_return_val_if_fail (GST_IS_TAG_XMP_WRITER (config), FALSE);
247
248   data = gst_tag_xmp_writer_get_data (config);
249
250   GST_TAG_XMP_WRITER_DATA_LOCK (data);
251   for (iter = data->schemas; iter; iter = g_slist_next (iter)) {
252     if (strcmp ((const gchar *) iter->data, schema) == 0) {
253       ret = TRUE;
254       break;
255     }
256   }
257   GST_TAG_XMP_WRITER_DATA_UNLOCK (data);
258
259   return ret;
260 }
261
262 /**
263  * gst_tag_xmp_writer_remove_schema:
264  * @config: a #GstTagXmpWriter
265  * @schema: the schema to remove
266  *
267  * Removes a schema from the list of schemas to use. Nothing is done if
268  * the schema wasn't in the list
269  *
270  * Since: 0.10.33
271  */
272 void
273 gst_tag_xmp_writer_remove_schema (GstTagXmpWriter * config,
274     const gchar * schema)
275 {
276   GstTagXmpWriterData *data;
277   GSList *iter = NULL;
278
279   g_return_if_fail (GST_IS_TAG_XMP_WRITER (config));
280
281   data = gst_tag_xmp_writer_get_data (config);
282
283   GST_TAG_XMP_WRITER_DATA_LOCK (data);
284   for (iter = data->schemas; iter; iter = g_slist_next (iter)) {
285     if (strcmp ((const gchar *) iter->data, schema) == 0) {
286       g_free (iter->data);
287       data->schemas = g_slist_delete_link (data->schemas, iter);
288       break;
289     }
290   }
291   GST_TAG_XMP_WRITER_DATA_UNLOCK (data);
292 }
293
294 /**
295  * gst_tag_xmp_writer_remove_all_schemas:
296  * @config: a #GstTagXmpWriter
297  *
298  * Removes all schemas from the list of schemas to use. Meaning that no
299  * XMP will be generated.
300  *
301  * Since: 0.10.33
302  */
303 void
304 gst_tag_xmp_writer_remove_all_schemas (GstTagXmpWriter * config)
305 {
306   GstTagXmpWriterData *data;
307   GSList *iter;
308
309   g_return_if_fail (GST_IS_TAG_XMP_WRITER (config));
310
311   data = gst_tag_xmp_writer_get_data (config);
312
313   GST_TAG_XMP_WRITER_DATA_LOCK (data);
314   if (data->schemas) {
315     for (iter = data->schemas; iter; iter = g_slist_next (iter)) {
316       g_free (iter->data);
317     }
318     g_slist_free (data->schemas);
319   }
320   data->schemas = NULL;
321   GST_TAG_XMP_WRITER_DATA_UNLOCK (data);
322 }
323
324 GstBuffer *
325 gst_tag_xmp_writer_tag_list_to_xmp_buffer (GstTagXmpWriter * config,
326     const GstTagList * taglist, gboolean read_only)
327 {
328   GstTagXmpWriterData *data;
329   GstBuffer *buf = NULL;
330   gint i = 0;
331   GSList *iter;
332
333   g_return_val_if_fail (GST_IS_TAG_XMP_WRITER (config), NULL);
334
335   data = gst_tag_xmp_writer_get_data (config);
336
337   GST_TAG_XMP_WRITER_DATA_LOCK (data);
338   if (data->schemas) {
339     gchar **array = g_new0 (gchar *, g_slist_length (data->schemas) + 1);
340     if (array) {
341       for (iter = data->schemas; iter; iter = g_slist_next (iter)) {
342         array[i++] = (gchar *) iter->data;
343       }
344       buf = gst_tag_list_to_xmp_buffer_full (taglist, read_only,
345           (const gchar **) array);
346       g_free (array);
347     }
348   }
349   GST_TAG_XMP_WRITER_DATA_UNLOCK (data);
350
351   return buf;
352 }