diff --git a/gst-libs/gst/tag/Makefile.am b/gst-libs/gst/tag/Makefile.am index 15263dd49e..f953e60a7d 100644 --- a/gst-libs/gst/tag/Makefile.am +++ b/gst-libs/gst/tag/Makefile.am @@ -2,13 +2,13 @@ libgsttagincludedir = \ $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/tag libgsttaginclude_HEADERS = \ - tag.h gsttagdemux.h + tag.h gsttagdemux.h xmpwriter.h lib_LTLIBRARIES = libgsttag-@GST_MAJORMINOR@.la libgsttag_@GST_MAJORMINOR@_la_SOURCES = \ gstvorbistag.c gstid3tag.c gstxmptag.c gstexiftag.c \ - lang.c tags.c gsttagdemux.c gsttageditingprivate.c + lang.c tags.c gsttagdemux.c gsttageditingprivate.c xmpwriter.c libgsttag_@GST_MAJORMINOR@_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) libgsttag_@GST_MAJORMINOR@_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS) $(LIBM) libgsttag_@GST_MAJORMINOR@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS) diff --git a/gst-libs/gst/tag/gstxmptag.c b/gst-libs/gst/tag/gstxmptag.c index aa3b9a7f6a..dce3e416d3 100644 --- a/gst-libs/gst/tag/gstxmptag.c +++ b/gst-libs/gst/tag/gstxmptag.c @@ -93,22 +93,21 @@ typedef void (*XmpDeserializationFunc) (XmpTag * xmptag, GstTagList * taglist, struct _XmpSerializationData { GString *data; - GList *schemas; + const gchar **schemas; }; static gboolean xmp_serialization_data_use_schema (XmpSerializationData * serdata, const gchar * schemaname) { - GList *iter; + gint i = 0; if (serdata->schemas == NULL) return TRUE; - for (iter = serdata->schemas; iter; iter = g_list_next (iter)) { - const gchar *name = (const gchar *) iter->data; - - if (strcmp (name, schemaname) == 0) + while (serdata->schemas[i] != NULL) { + if (strcmp (serdata->schemas[i], schemaname) == 0) return TRUE; + i++; } return FALSE; } @@ -1574,7 +1573,7 @@ write_one_tag (const GstTagList * list, const gchar * tag, gpointer user_data) * gst_tag_list_to_xmp_buffer_full: * @list: tags * @read_only: does the container forbid inplace editing - * @schemas: list of schemas to be used on serialization + * @schemas: %NULL terminated array of schemas to be used on serialization * * Formats a taglist as a xmp packet using only the selected * schemas. An empty list (%NULL) means that all schemas should @@ -1586,7 +1585,7 @@ write_one_tag (const GstTagList * list, const gchar * tag, gpointer user_data) */ GstBuffer * gst_tag_list_to_xmp_buffer_full (const GstTagList * list, gboolean read_only, - GList * schemas) + const gchar ** schemas) { GstBuffer *buffer = NULL; XmpSerializationData serialization_data; diff --git a/gst-libs/gst/tag/tag.h b/gst-libs/gst/tag/tag.h index ed91e133f2..472110b2ab 100644 --- a/gst-libs/gst/tag/tag.h +++ b/gst-libs/gst/tag/tag.h @@ -475,7 +475,7 @@ GstTagList * gst_tag_list_from_xmp_buffer (const GstBuffer * buffer GstBuffer * gst_tag_list_to_xmp_buffer (const GstTagList * list, gboolean read_only); GstBuffer * gst_tag_list_to_xmp_buffer_full (const GstTagList * list, - gboolean read_only, GList * schemas); + gboolean read_only, const gchar ** schemas); const gchar** gst_tag_xmp_list_schemas (void); /* functions related to exif */ diff --git a/gst-libs/gst/tag/xmpwriter.c b/gst-libs/gst/tag/xmpwriter.c new file mode 100644 index 0000000000..573224cb1d --- /dev/null +++ b/gst-libs/gst/tag/xmpwriter.c @@ -0,0 +1,322 @@ +/* GStreamer XmpConfig + * Copyright (C) 2010 Thiago Santos + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:gstxmpconfig + * @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 +#include + +static GQuark tag_xmp_writer_key; + +typedef struct +{ + GSList *schemas; + GStaticMutex lock; +} GstTagXmpWriterData; + +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_static_mutex_free (&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) { + static GStaticMutex create_mutex = G_STATIC_MUTEX_INIT; + + /* make sure no other thread is creating a GstTagXmpWriterData at the same time */ + g_static_mutex_lock (&create_mutex); + data = g_object_get_qdata (G_OBJECT (xmpconfig), tag_xmp_writer_key); + if (!data) { + data = g_slice_new (GstTagXmpWriterData); + g_static_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_static_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. + * + * Since: 0.10.33 + */ +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); + + g_static_mutex_lock (&data->lock); + gst_tag_xmp_writer_data_add_all_schemas_unlocked (data); + g_static_mutex_unlock (&data->lock); +} + +/** + * gst_tag_xmp_writer_add_schema: + * @config: a #GstTagXmpWriter + * @schema: the schema to be added + * + * Adds @schema to the list schemas + * + * Since: 0.10.33 + */ +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); + + g_static_mutex_lock (&data->lock); + gst_tag_xmp_writer_data_add_schema_unlocked (data, schema); + g_static_mutex_unlock (&data->lock); +} + +/** + * 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 + * Since: 0.10.33 + */ +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); + + g_static_mutex_lock (&data->lock); + for (iter = data->schemas; iter; iter = g_slist_next (iter)) { + if (strcmp ((const gchar *) iter->data, schema) == 0) { + ret = TRUE; + break; + } + } + g_static_mutex_unlock (&data->lock); + + 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 + * + * Since: 0.10.33 + */ +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); + + g_static_mutex_lock (&data->lock); + 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; + } + } + g_static_mutex_unlock (&data->lock); +} + +/** + * 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. + * + * Since: 0.10.33 + */ +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); + + g_static_mutex_lock (&data->lock); + 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; + g_static_mutex_unlock (&data->lock); +} + +GstBuffer * +gst_tag_xmp_writer_tag_list_to_xmp_buffer (GstTagXmpWriter * config, + const GstTagList * taglist, gboolean read_only) +{ + GstTagXmpWriterData *data; + GstBuffer *buf = NULL; + const gchar **array; + 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); + + g_static_mutex_lock (&data->lock); + if (data->schemas) { + array = g_new0 (const gchar *, g_slist_length (data->schemas) + 1); + if (array) { + for (iter = data->schemas; iter; iter = g_slist_next (iter)) { + array[i++] = (const gchar *) iter->data; + } + buf = gst_tag_list_to_xmp_buffer_full (taglist, read_only, array); + g_free (array); + } + } + g_static_mutex_unlock (&data->lock); + + return buf; +} diff --git a/gst-libs/gst/tag/xmpwriter.h b/gst-libs/gst/tag/xmpwriter.h new file mode 100644 index 0000000000..6c89072c23 --- /dev/null +++ b/gst-libs/gst/tag/xmpwriter.h @@ -0,0 +1,68 @@ +/* GStreamer XmpConfig + * Copyright (C) 2011 Thiago Santos + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __TAG_XMP_WRITER_H__ +#define __TAG_XMP_WRITER_H__ + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_TAG_XMP_WRITER \ + (gst_tag_xmp_writer_get_type ()) +#define GST_TAG_XMP_WRITER(obj) \ + (GST_IMPLEMENTS_INTERFACE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TAG_XMP_WRITER, GstTagXmpWriter)) +#define GST_TAG_XMP_WRITER_INTERFACE(iface) \ + (G_TYPE_CHECK_INTERFACE_CAST ((iface), GST_TYPE_TAG_XMP_WRITER, GstTagXmpWriterInterface)) +#define GST_IS_TAG_XMP_WRITER(obj) \ + (GST_IMPLEMENTS_INTERFACE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TAG_XMP_WRITER)) +#define GST_IS_TAG_XMP_WRITER_INTERFACE(iface) \ + (G_TYPE_CHECK_INTERFACE_TYPE ((iface), GST_TYPE_TAG_XMP_WRITER)) +#define GST_TAG_XMP_WRITER_GET_INTERFACE(inst) \ + (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_TAG_XMP_WRITER, GstTagXmpWriterInterface)) + +typedef struct _GstTagXmpWriter GstTagXmpWriter; +typedef struct _GstTagXmpWriterInterface GstTagXmpWriterInterface; + +struct _GstTagXmpWriterInterface { + GTypeInterface parent; +}; + +GType gst_tag_xmp_writer_get_type (void); + +void gst_tag_xmp_writer_add_all_schemas (GstTagXmpWriter * config); + +void gst_tag_xmp_writer_add_schema (GstTagXmpWriter * config, + const gchar * schema); + +gboolean gst_tag_xmp_writer_has_schema (GstTagXmpWriter * config, + const gchar * schema); + +void gst_tag_xmp_writer_remove_schema (GstTagXmpWriter * config, + const gchar * schema); + +void gst_tag_xmp_writer_remove_all_schemas (GstTagXmpWriter * config); + +GstBuffer* gst_tag_xmp_writer_tag_list_to_xmp_buffer (GstTagXmpWriter * config, + const GstTagList * taglist, + gboolean read_only); + +G_END_DECLS + +#endif /* __TAG_XMP_WRITER_H__ */ diff --git a/win32/common/libgsttag.def b/win32/common/libgsttag.def index 349cfc05ab..bab6bbda21 100644 --- a/win32/common/libgsttag.def +++ b/win32/common/libgsttag.def @@ -31,4 +31,11 @@ EXPORTS gst_tag_to_vorbis_comments gst_tag_to_vorbis_tag gst_tag_xmp_list_schemas + gst_tag_xmp_writer_add_all_schemas + gst_tag_xmp_writer_add_schema + gst_tag_xmp_writer_get_type + gst_tag_xmp_writer_has_schema + gst_tag_xmp_writer_remove_all_schemas + gst_tag_xmp_writer_remove_schema + gst_tag_xmp_writer_tag_list_to_xmp_buffer gst_vorbis_tag_add