| /* GStreamer TagXmpWriter |
| * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk> |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Library General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public |
| * License along with this library; if not, write to the |
| * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, |
| * Boston, MA 02110-1301, USA. |
| */ |
| |
| /** |
| * SECTION:gsttagxmpwriter |
| * @title: GstTagXmpWriter |
| * @short_description: Interface for elements that provide XMP serialization |
| * |
| * This interface is implemented by elements that are able to do XMP serialization. Examples for |
| * such elements are #jifmux and #qtmux. |
| * |
| * Applications can use this interface to configure which XMP schemas should be used when serializing |
| * tags into XMP. Schemas are represented by their names, a full list of the supported schemas can be |
| * obtained from gst_tag_xmp_list_schemas(). By default, all schemas are used. |
| * |
| */ |
| |
| #ifdef HAVE_CONFIG_H |
| #include "config.h" |
| #endif |
| |
| #include "xmpwriter.h" |
| #include <string.h> |
| #include <gst/tag/tag.h> |
| |
| static GQuark tag_xmp_writer_key; |
| |
| typedef struct |
| { |
| GSList *schemas; |
| GMutex lock; |
| } GstTagXmpWriterData; |
| |
| #define GST_TAG_XMP_WRITER_DATA_LOCK(data) g_mutex_lock(&data->lock) |
| #define GST_TAG_XMP_WRITER_DATA_UNLOCK(data) g_mutex_unlock(&data->lock) |
| |
| GType |
| gst_tag_xmp_writer_get_type (void) |
| { |
| static volatile gsize xmp_config_type = 0; |
| |
| if (g_once_init_enter (&xmp_config_type)) { |
| GType _type; |
| static const GTypeInfo xmp_config_info = { |
| sizeof (GstTagXmpWriterInterface), /* class_size */ |
| NULL, /* base_init */ |
| NULL, /* base_finalize */ |
| NULL, |
| NULL, /* class_finalize */ |
| NULL, /* class_data */ |
| 0, |
| 0, |
| NULL |
| }; |
| |
| _type = g_type_register_static (G_TYPE_INTERFACE, "GstTagXmpWriter", |
| &xmp_config_info, 0); |
| tag_xmp_writer_key = g_quark_from_static_string ("GST_TAG_XMP_WRITER"); |
| g_type_interface_add_prerequisite (_type, GST_TYPE_ELEMENT); |
| |
| g_once_init_leave (&xmp_config_type, _type); |
| } |
| |
| return xmp_config_type; |
| } |
| |
| static void |
| gst_tag_xmp_writer_data_add_schema_unlocked (GstTagXmpWriterData * data, |
| const gchar * schema) |
| { |
| if (!g_slist_find_custom (data->schemas, schema, (GCompareFunc) strcmp)) { |
| data->schemas = g_slist_prepend (data->schemas, g_strdup (schema)); |
| } |
| } |
| |
| static void |
| gst_tag_xmp_writer_data_add_all_schemas_unlocked (GstTagXmpWriterData * data) |
| { |
| const gchar **schemas; |
| gint i = 0; |
| |
| /* initialize it with all schemas */ |
| schemas = gst_tag_xmp_list_schemas (); |
| while (schemas[i] != NULL) { |
| gst_tag_xmp_writer_data_add_schema_unlocked (data, schemas[i]); |
| i++; |
| } |
| } |
| |
| |
| static void |
| gst_tag_xmp_writer_data_free (gpointer p) |
| { |
| GstTagXmpWriterData *data = (GstTagXmpWriterData *) p; |
| GSList *iter; |
| |
| if (data->schemas) { |
| for (iter = data->schemas; iter; iter = g_slist_next (iter)) { |
| g_free (iter->data); |
| } |
| g_slist_free (data->schemas); |
| } |
| g_mutex_clear (&data->lock); |
| |
| g_slice_free (GstTagXmpWriterData, data); |
| } |
| |
| static GstTagXmpWriterData * |
| gst_tag_xmp_writer_get_data (GstTagXmpWriter * xmpconfig) |
| { |
| GstTagXmpWriterData *data; |
| |
| data = g_object_get_qdata (G_OBJECT (xmpconfig), tag_xmp_writer_key); |
| if (!data) { |
| /* make sure no other thread is creating a GstTagData at the same time */ |
| static GMutex create_mutex; /* no initialisation required */ |
| |
| g_mutex_lock (&create_mutex); |
| |
| data = g_object_get_qdata (G_OBJECT (xmpconfig), tag_xmp_writer_key); |
| if (!data) { |
| data = g_slice_new (GstTagXmpWriterData); |
| |
| g_mutex_init (&data->lock); |
| data->schemas = NULL; |
| gst_tag_xmp_writer_data_add_all_schemas_unlocked (data); |
| |
| g_object_set_qdata_full (G_OBJECT (xmpconfig), tag_xmp_writer_key, data, |
| gst_tag_xmp_writer_data_free); |
| } |
| g_mutex_unlock (&create_mutex); |
| } |
| |
| return data; |
| } |
| |
| /** |
| * gst_tag_xmp_writer_add_all_schemas: |
| * @config: a #GstTagXmpWriter |
| * |
| * Adds all available XMP schemas to the configuration. Meaning that |
| * all will be used. |
| */ |
| void |
| gst_tag_xmp_writer_add_all_schemas (GstTagXmpWriter * config) |
| { |
| GstTagXmpWriterData *data; |
| |
| g_return_if_fail (GST_IS_TAG_XMP_WRITER (config)); |
| |
| data = gst_tag_xmp_writer_get_data (config); |
| |
| GST_TAG_XMP_WRITER_DATA_LOCK (data); |
| gst_tag_xmp_writer_data_add_all_schemas_unlocked (data); |
| GST_TAG_XMP_WRITER_DATA_UNLOCK (data); |
| } |
| |
| /** |
| * gst_tag_xmp_writer_add_schema: |
| * @config: a #GstTagXmpWriter |
| * @schema: the schema to be added |
| * |
| * Adds @schema to the list schemas |
| */ |
| void |
| gst_tag_xmp_writer_add_schema (GstTagXmpWriter * config, const gchar * schema) |
| { |
| GstTagXmpWriterData *data; |
| |
| g_return_if_fail (GST_IS_TAG_XMP_WRITER (config)); |
| |
| data = gst_tag_xmp_writer_get_data (config); |
| |
| GST_TAG_XMP_WRITER_DATA_LOCK (data); |
| gst_tag_xmp_writer_data_add_schema_unlocked (data, schema); |
| GST_TAG_XMP_WRITER_DATA_UNLOCK (data); |
| } |
| |
| /** |
| * gst_tag_xmp_writer_has_schema: |
| * @config: a #GstTagXmpWriter |
| * @schema: the schema to test |
| * |
| * Checks if @schema is going to be used |
| * |
| * Returns: %TRUE if it is going to be used |
| */ |
| gboolean |
| gst_tag_xmp_writer_has_schema (GstTagXmpWriter * config, const gchar * schema) |
| { |
| GstTagXmpWriterData *data; |
| gboolean ret = FALSE; |
| GSList *iter; |
| |
| g_return_val_if_fail (GST_IS_TAG_XMP_WRITER (config), FALSE); |
| |
| data = gst_tag_xmp_writer_get_data (config); |
| |
| GST_TAG_XMP_WRITER_DATA_LOCK (data); |
| for (iter = data->schemas; iter; iter = g_slist_next (iter)) { |
| if (strcmp ((const gchar *) iter->data, schema) == 0) { |
| ret = TRUE; |
| break; |
| } |
| } |
| GST_TAG_XMP_WRITER_DATA_UNLOCK (data); |
| |
| return ret; |
| } |
| |
| /** |
| * gst_tag_xmp_writer_remove_schema: |
| * @config: a #GstTagXmpWriter |
| * @schema: the schema to remove |
| * |
| * Removes a schema from the list of schemas to use. Nothing is done if |
| * the schema wasn't in the list |
| */ |
| void |
| gst_tag_xmp_writer_remove_schema (GstTagXmpWriter * config, |
| const gchar * schema) |
| { |
| GstTagXmpWriterData *data; |
| GSList *iter = NULL; |
| |
| g_return_if_fail (GST_IS_TAG_XMP_WRITER (config)); |
| |
| data = gst_tag_xmp_writer_get_data (config); |
| |
| GST_TAG_XMP_WRITER_DATA_LOCK (data); |
| for (iter = data->schemas; iter; iter = g_slist_next (iter)) { |
| if (strcmp ((const gchar *) iter->data, schema) == 0) { |
| g_free (iter->data); |
| data->schemas = g_slist_delete_link (data->schemas, iter); |
| break; |
| } |
| } |
| GST_TAG_XMP_WRITER_DATA_UNLOCK (data); |
| } |
| |
| /** |
| * gst_tag_xmp_writer_remove_all_schemas: |
| * @config: a #GstTagXmpWriter |
| * |
| * Removes all schemas from the list of schemas to use. Meaning that no |
| * XMP will be generated. |
| */ |
| void |
| gst_tag_xmp_writer_remove_all_schemas (GstTagXmpWriter * config) |
| { |
| GstTagXmpWriterData *data; |
| GSList *iter; |
| |
| g_return_if_fail (GST_IS_TAG_XMP_WRITER (config)); |
| |
| data = gst_tag_xmp_writer_get_data (config); |
| |
| GST_TAG_XMP_WRITER_DATA_LOCK (data); |
| if (data->schemas) { |
| for (iter = data->schemas; iter; iter = g_slist_next (iter)) { |
| g_free (iter->data); |
| } |
| g_slist_free (data->schemas); |
| } |
| data->schemas = NULL; |
| GST_TAG_XMP_WRITER_DATA_UNLOCK (data); |
| } |
| |
| GstBuffer * |
| gst_tag_xmp_writer_tag_list_to_xmp_buffer (GstTagXmpWriter * config, |
| const GstTagList * taglist, gboolean read_only) |
| { |
| GstTagXmpWriterData *data; |
| GstBuffer *buf = NULL; |
| gint i = 0; |
| GSList *iter; |
| |
| g_return_val_if_fail (GST_IS_TAG_XMP_WRITER (config), NULL); |
| |
| data = gst_tag_xmp_writer_get_data (config); |
| |
| GST_TAG_XMP_WRITER_DATA_LOCK (data); |
| if (data->schemas) { |
| gchar **array = g_new0 (gchar *, g_slist_length (data->schemas) + 1); |
| if (array) { |
| for (iter = data->schemas; iter; iter = g_slist_next (iter)) { |
| array[i++] = (gchar *) iter->data; |
| } |
| buf = gst_tag_list_to_xmp_buffer (taglist, read_only, |
| (const gchar **) array); |
| g_free (array); |
| } |
| } |
| GST_TAG_XMP_WRITER_DATA_UNLOCK (data); |
| |
| return buf; |
| } |