tagxmpwriter: Adds a new GstTagXmpWriter interface

The GstTagXmpWriter interface is to be implemented on elements that
provide xmp serialization. It allows users to select which
xmp schemas should be used on serialization.

API: GstTagXmpWriter

https://bugzilla.gnome.org/show_bug.cgi?id=645167
This commit is contained in:
Thiago Santos 2011-03-17 15:42:28 -03:00
parent 6cc96a67ec
commit 34ba387d0b
6 changed files with 407 additions and 11 deletions

View file

@ -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)

View file

@ -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;

View file

@ -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 */

View file

@ -0,0 +1,322 @@
/* GStreamer XmpConfig
* 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:gstxmpconfig
* @short_description: Interface for elements that provide XMP serialization
*
* <refsect2>
* <para>
* This interface is implemented by elements that are able to do XMP serialization. Examples for
* such elements are #jifmux and #qtmux.
* </para>
* <para>
* 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.
* </para>
* </refsect2>
*/
#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;
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;
}

View file

@ -0,0 +1,68 @@
/* GStreamer XmpConfig
* Copyright (C) 2011 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __TAG_XMP_WRITER_H__
#define __TAG_XMP_WRITER_H__
#include <gst/gst.h>
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__ */

View file

@ -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