blob: d714e0a03434fac5bc4d9d3495076268a3d94865 [file] [log] [blame]
/* 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;
}