Blame gst-libs/gst/tag/xmpwriter.c

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