/* GStreamer
 * Copyright (C) 2008-2009 Sebastian Dröge <sebastian.droege@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.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gst/gst.h>
#include <string.h>

#include "mxftypes.h"
#include "mxfmetadata.h"
#include "mxfquark.h"

GST_DEBUG_CATEGORY_EXTERN (mxf_debug);
#define GST_CAT_DEFAULT mxf_debug

G_DEFINE_ABSTRACT_TYPE (MXFMetadataBase, mxf_metadata_base, G_TYPE_OBJECT);

static void
mxf_metadata_base_finalize (GObject * object)
{
  MXFMetadataBase *self = MXF_METADATA_BASE (object);

  if (self->other_tags) {
    g_hash_table_destroy (self->other_tags);
    self->other_tags = NULL;
  }

  G_OBJECT_CLASS (mxf_metadata_base_parent_class)->finalize (object);
}

static gboolean
mxf_metadata_base_handle_tag (MXFMetadataBase * self, MXFPrimerPack * primer,
    guint16 tag, const guint8 * tag_data, guint tag_size)
{
  return (mxf_local_tag_add_to_hash_table (primer, tag, tag_data, tag_size,
          &self->other_tags));
}

static gboolean
mxf_metadata_base_resolve_default (MXFMetadataBase * self,
    GHashTable * metadata)
{
  return TRUE;
}

static GstStructure *
mxf_metadata_base_to_structure_default (MXFMetadataBase * self)
{
  MXFMetadataBaseClass *klass = MXF_METADATA_BASE_GET_CLASS (self);
  GstStructure *ret;
  gchar str[48];

  g_return_val_if_fail (klass->name_quark != 0, NULL);

  ret = gst_structure_new_id_empty (klass->name_quark);

  if (!mxf_uuid_is_zero (&self->instance_uid)) {
    mxf_uuid_to_string (&self->instance_uid, str);
    gst_structure_id_set (ret, MXF_QUARK (INSTANCE_UID), G_TYPE_STRING, str,
        NULL);
  }

  if (!mxf_uuid_is_zero (&self->generation_uid)) {
    mxf_uuid_to_string (&self->generation_uid, str);
    gst_structure_id_set (ret, MXF_QUARK (GENERATION_UID), G_TYPE_STRING, str,
        NULL);
  }

  if (self->other_tags) {
    MXFLocalTag *tag;
    GValue va = { 0, };
    GValue v = { 0, };
    GstStructure *s;
    GstBuffer *buf;
    GstMapInfo map;
    GHashTableIter iter;

    g_hash_table_iter_init (&iter, self->other_tags);
    g_value_init (&va, GST_TYPE_ARRAY);

    while (g_hash_table_iter_next (&iter, NULL, (gpointer) & tag)) {
      g_value_init (&v, GST_TYPE_STRUCTURE);
      s = gst_structure_new_id_empty (MXF_QUARK (TAG));

      mxf_ul_to_string (&tag->ul, str);

      buf = gst_buffer_new_and_alloc (tag->size);
      gst_buffer_map (buf, &map, GST_MAP_WRITE);
      memcpy (map.data, tag->data, tag->size);
      gst_buffer_unmap (buf, &map);

      gst_structure_id_set (s, MXF_QUARK (NAME), G_TYPE_STRING, str,
          MXF_QUARK (DATA), GST_TYPE_BUFFER, buf, NULL);

      gst_value_set_structure (&v, s);
      gst_structure_free (s);
      gst_buffer_unref (buf);
      gst_value_array_append_value (&va, &v);
      g_value_unset (&v);
    }

    gst_structure_id_set_value (ret, MXF_QUARK (OTHER_TAGS), &va);
    g_value_unset (&va);
  }

  return ret;
}

static void
mxf_metadata_base_init (MXFMetadataBase * self)
{

}

static void
mxf_metadata_base_class_init (MXFMetadataBaseClass * klass)
{
  GObjectClass *object_class = (GObjectClass *) klass;

  object_class->finalize = mxf_metadata_base_finalize;
  klass->handle_tag = mxf_metadata_base_handle_tag;
  klass->resolve = mxf_metadata_base_resolve_default;
  klass->to_structure = mxf_metadata_base_to_structure_default;
}

gboolean
mxf_metadata_base_parse (MXFMetadataBase * self, MXFPrimerPack * primer,
    const guint8 * data, guint size)
{
  guint16 tag, tag_size;
  const guint8 *tag_data;

  g_return_val_if_fail (MXF_IS_METADATA_BASE (self), FALSE);
  g_return_val_if_fail (data != NULL, FALSE);
  g_return_val_if_fail (primer != NULL, FALSE);

  while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
    if (tag_size == 0 || tag == 0x0000)
      goto next;

    if (!MXF_METADATA_BASE_GET_CLASS (self)->handle_tag (self, primer, tag,
            tag_data, tag_size))
      return FALSE;
  next:
    data += 4 + tag_size;
    size -= 4 + tag_size;
  }

  return TRUE;
}

gboolean
mxf_metadata_base_resolve (MXFMetadataBase * self, GHashTable * metadata)
{
  MXFMetadataBaseClass *klass;
  gboolean ret = TRUE;

  g_return_val_if_fail (MXF_IS_METADATA_BASE (self), FALSE);
  g_return_val_if_fail (metadata != NULL, FALSE);

  if (self->resolved == MXF_METADATA_BASE_RESOLVE_STATE_SUCCESS)
    return TRUE;
  else if (self->resolved != MXF_METADATA_BASE_RESOLVE_STATE_NONE)
    return FALSE;

  self->resolved = MXF_METADATA_BASE_RESOLVE_STATE_RUNNING;

  klass = MXF_METADATA_BASE_GET_CLASS (self);

  if (klass->resolve)
    ret = klass->resolve (self, metadata);

  self->resolved =
      (ret) ? MXF_METADATA_BASE_RESOLVE_STATE_SUCCESS :
      MXF_METADATA_BASE_RESOLVE_STATE_FAILURE;

  return ret;
}

GstStructure *
mxf_metadata_base_to_structure (MXFMetadataBase * self)
{
  MXFMetadataBaseClass *klass;

  g_return_val_if_fail (MXF_IS_METADATA_BASE (self), NULL);

  g_return_val_if_fail (self->resolved ==
      MXF_METADATA_BASE_RESOLVE_STATE_SUCCESS, NULL);

  klass = MXF_METADATA_BASE_GET_CLASS (self);

  if (klass->to_structure)
    return klass->to_structure (self);

  return NULL;
}

GstBuffer *
mxf_metadata_base_to_buffer (MXFMetadataBase * self, MXFPrimerPack * primer)
{
  MXFMetadataBaseClass *klass;
  GstBuffer *ret;
  GstMapInfo map;
  GList *tags, *l;
  guint size = 0, slen;
  guint8 ber[9];
  MXFLocalTag *t, *last;
  guint8 *data;

  g_return_val_if_fail (MXF_IS_METADATA_BASE (self), NULL);
  g_return_val_if_fail (primer != NULL, NULL);

  klass = MXF_METADATA_BASE_GET_CLASS (self);
  g_return_val_if_fail (klass->write_tags, NULL);

  tags = klass->write_tags (self, primer);
  g_return_val_if_fail (tags != NULL, NULL);

  /* Add unknown tags */
  if (self->other_tags) {
    MXFLocalTag *tmp;
    GHashTableIter iter;

    g_hash_table_iter_init (&iter, self->other_tags);

    while (g_hash_table_iter_next (&iter, NULL, (gpointer) & t)) {
      tmp = g_slice_dup (MXFLocalTag, t);
      if (t->g_slice) {
        tmp->data = g_slice_alloc (t->size);
        mxf_primer_pack_add_mapping (primer, 0x0000, &t->ul);
        memcpy (tmp->data, t->data, t->size);
      } else {
        tmp->data = g_memdup (t->data, t->size);
      }
      tags = g_list_prepend (tags, tmp);
    }
  }

  l = g_list_last (tags);
  last = l->data;
  tags = g_list_delete_link (tags, l);
  /* Last element contains the metadata UL */
  g_return_val_if_fail (last->size == 0, NULL);

  for (l = tags; l; l = l->next) {
    t = l->data;
    g_assert (G_MAXUINT - t->size >= size);
    size += 4 + t->size;
  }

  slen = mxf_ber_encode_size (size, ber);
  size += 16 + slen;

  ret = gst_buffer_new_and_alloc (size);
  gst_buffer_map (ret, &map, GST_MAP_WRITE);

  memcpy (map.data, &last->ul, 16);
  mxf_local_tag_free (last);
  last = NULL;
  memcpy (map.data + 16, ber, slen);

  data = map.data + 16 + slen;
  size -= 16 + slen;

  for (l = tags; l; l = l->next) {
    guint16 local_tag;

    g_assert (size >= 4);
    t = l->data;

    local_tag =
        GPOINTER_TO_UINT (g_hash_table_lookup (primer->reverse_mappings,
            &t->ul));
    g_assert (local_tag != 0);

    GST_WRITE_UINT16_BE (data, local_tag);
    GST_WRITE_UINT16_BE (data + 2, t->size);
    data += 4;
    size -= 4;
    g_assert (size >= t->size);

    memcpy (data, t->data, t->size);
    data += t->size;
    size -= t->size;

    mxf_local_tag_free (t);
  }

  g_list_free (tags);

  gst_buffer_unmap (ret, &map);

  return ret;
}

G_DEFINE_ABSTRACT_TYPE (MXFMetadata, mxf_metadata, MXF_TYPE_METADATA_BASE);

static gboolean
mxf_metadata_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer,
    guint16 tag, const guint8 * tag_data, guint tag_size)
{
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif
  MXFMetadata *self = MXF_METADATA (metadata);
  gboolean ret = TRUE;

  switch (tag) {
    case 0x3c0a:
      if (tag_size != 16)
        goto error;
      memcpy (&self->parent.instance_uid, tag_data, 16);
      GST_DEBUG ("  instance uid = %s",
          mxf_uuid_to_string (&self->parent.instance_uid, str));
      break;
    case 0x0102:
      if (tag_size != 16)
        goto error;
      memcpy (&self->parent.generation_uid, tag_data, 16);
      GST_DEBUG ("  generation uid = %s",
          mxf_uuid_to_string (&self->parent.generation_uid, str));
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS (mxf_metadata_parent_class)->handle_tag
          (metadata, primer, tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR ("Invalid metadata local tag 0x%04x of size %u", tag, tag_size);

  return FALSE;
}

static GList *
mxf_metadata_write_tags (MXFMetadataBase * m, MXFPrimerPack * primer)
{
  MXFMetadata *self = MXF_METADATA (m);
  GList *ret = NULL;
  MXFLocalTag *t;
  MXFMetadataClass *klass;

  g_return_val_if_fail (MXF_IS_METADATA (self), NULL);
  klass = MXF_METADATA_GET_CLASS (self);

  /* Last element contains the metadata key */
  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (METADATA), 16);
  GST_WRITE_UINT16_BE (&t->ul.u[13], klass->type);
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (INSTANCE_UID), 16);
  t->size = 16;
  t->data = g_slice_alloc (16);
  t->g_slice = TRUE;
  memcpy (t->data, &self->parent.instance_uid, 16);
  mxf_primer_pack_add_mapping (primer, 0x3c0a, &t->ul);
  ret = g_list_prepend (ret, t);

  if (!mxf_uuid_is_zero (&self->parent.generation_uid)) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (GENERATION_UID), 16);
    t->size = 16;
    t->data = g_slice_alloc (16);
    t->g_slice = TRUE;
    memcpy (t->data, &self->parent.generation_uid, 16);
    mxf_primer_pack_add_mapping (primer, 0x0102, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  return ret;
}

static void
mxf_metadata_class_init (MXFMetadataClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;

  metadata_base_class->handle_tag = mxf_metadata_handle_tag;
  metadata_base_class->write_tags = mxf_metadata_write_tags;
}

static void
mxf_metadata_init (MXFMetadata * self)
{
}

static GArray *_mxf_metadata_registry = NULL;

#define _add_metadata_type(type) G_STMT_START { \
  GType t = type; \
  \
  g_array_append_val (_mxf_metadata_registry, t); \
} G_STMT_END

void
mxf_metadata_init_types (void)
{
  g_return_if_fail (_mxf_metadata_registry == NULL);

  _mxf_metadata_registry = g_array_new (FALSE, TRUE, sizeof (GType));

  _add_metadata_type (MXF_TYPE_METADATA_PREFACE);
  _add_metadata_type (MXF_TYPE_METADATA_IDENTIFICATION);
  _add_metadata_type (MXF_TYPE_METADATA_CONTENT_STORAGE);
  _add_metadata_type (MXF_TYPE_METADATA_ESSENCE_CONTAINER_DATA);
  _add_metadata_type (MXF_TYPE_METADATA_MATERIAL_PACKAGE);
  _add_metadata_type (MXF_TYPE_METADATA_SOURCE_PACKAGE);
  _add_metadata_type (MXF_TYPE_METADATA_TIMELINE_TRACK);
  _add_metadata_type (MXF_TYPE_METADATA_EVENT_TRACK);
  _add_metadata_type (MXF_TYPE_METADATA_STATIC_TRACK);
  _add_metadata_type (MXF_TYPE_METADATA_SEQUENCE);
  _add_metadata_type (MXF_TYPE_METADATA_SOURCE_CLIP);
  _add_metadata_type (MXF_TYPE_METADATA_FILLER);
  _add_metadata_type (MXF_TYPE_METADATA_TIMECODE_COMPONENT);
  _add_metadata_type (MXF_TYPE_METADATA_DM_SEGMENT);
  _add_metadata_type (MXF_TYPE_METADATA_DM_SOURCE_CLIP);
  _add_metadata_type (MXF_TYPE_METADATA_FILE_DESCRIPTOR);
  _add_metadata_type (MXF_TYPE_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR);
  _add_metadata_type (MXF_TYPE_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR);
  _add_metadata_type (MXF_TYPE_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR);
  _add_metadata_type (MXF_TYPE_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR);
  _add_metadata_type (MXF_TYPE_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR);
  _add_metadata_type (MXF_TYPE_METADATA_MULTIPLE_DESCRIPTOR);
  _add_metadata_type (MXF_TYPE_METADATA_NETWORK_LOCATOR);
  _add_metadata_type (MXF_TYPE_METADATA_TEXT_LOCATOR);
}

#undef _add_metadata_type

void
mxf_metadata_register (GType type)
{
  g_return_if_fail (g_type_is_a (type, MXF_TYPE_METADATA));

  g_array_append_val (_mxf_metadata_registry, type);
}

MXFMetadata *
mxf_metadata_new (guint16 type, MXFPrimerPack * primer, guint64 offset,
    const guint8 * data, guint size)
{
  guint i;
  GType t = G_TYPE_INVALID;
  MXFMetadata *ret = NULL;

  g_return_val_if_fail (type != 0, NULL);
  g_return_val_if_fail (primer != NULL, NULL);
  g_return_val_if_fail (_mxf_metadata_registry != NULL, NULL);

  for (i = 0; i < _mxf_metadata_registry->len; i++) {
    GType tmp = g_array_index (_mxf_metadata_registry, GType, i);
    MXFMetadataClass *klass = MXF_METADATA_CLASS (g_type_class_ref (tmp));

    if (klass->type == type) {
      g_type_class_unref (klass);
      t = tmp;
      break;
    }
    g_type_class_unref (klass);
  }

  if (t == G_TYPE_INVALID) {
    GST_WARNING
        ("No handler for type 0x%04x found -- using generic metadata parser",
        type);
    return NULL;
  }


  GST_DEBUG ("Metadata type 0x%04x is handled by type %s", type,
      g_type_name (t));

  ret = (MXFMetadata *) g_type_create_instance (t);
  if (!mxf_metadata_base_parse (MXF_METADATA_BASE (ret), primer, data, size)) {
    GST_ERROR ("Parsing metadata failed");
    g_object_unref (ret);
    return NULL;
  }

  ret->parent.offset = offset;
  return ret;
}

G_DEFINE_TYPE (MXFMetadataPreface, mxf_metadata_preface, MXF_TYPE_METADATA);

static void
mxf_metadata_preface_finalize (GObject * object)
{
  MXFMetadataPreface *self = MXF_METADATA_PREFACE (object);

  g_free (self->identifications_uids);
  self->identifications_uids = NULL;

  g_free (self->identifications);
  self->identifications = NULL;

  g_free (self->essence_containers);
  self->essence_containers = NULL;

  g_free (self->dm_schemes);
  self->dm_schemes = NULL;

  G_OBJECT_CLASS (mxf_metadata_preface_parent_class)->finalize (object);
}

static gboolean
mxf_metadata_preface_handle_tag (MXFMetadataBase * metadata,
    MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataPreface *self = MXF_METADATA_PREFACE (metadata);
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif
  gboolean ret = TRUE;

  switch (tag) {
    case 0x3b02:
      if (!mxf_timestamp_parse (&self->last_modified_date, tag_data, tag_size))
        goto error;
      GST_DEBUG ("  last modified date = %s",
          mxf_timestamp_to_string (&self->last_modified_date, str));
      break;
    case 0x3b05:
      if (tag_size != 2)
        goto error;
      self->version = GST_READ_UINT16_BE (tag_data);
      GST_DEBUG ("  version = %u.%u", (self->version >> 8),
          (self->version & 0x0f));
      break;
    case 0x3b07:
      if (tag_size != 4)
        goto error;
      self->object_model_version = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  object model version = %u", self->object_model_version);
      break;
    case 0x3b08:
      if (tag_size != 16)
        goto error;
      memcpy (&self->primary_package_uid, tag_data, 16);
      GST_DEBUG ("  primary package = %s",
          mxf_uuid_to_string (&self->primary_package_uid, str));
      break;
    case 0x3b06:
      if (!mxf_uuid_array_parse (&self->identifications_uids,
              &self->n_identifications, tag_data, tag_size))
        goto error;

      GST_DEBUG ("  number of identifications = %u", self->n_identifications);
#ifndef GST_DISABLE_GST_DEBUG
      {
        guint i;
        for (i = 0; i < self->n_identifications; i++) {
          GST_DEBUG ("  identification %u = %s", i,
              mxf_uuid_to_string (&self->identifications_uids[i], str));
        }
      }
#endif
      break;
    case 0x3b03:
      if (tag_size != 16)
        goto error;
      memcpy (&self->content_storage_uid, tag_data, 16);
      GST_DEBUG ("  content storage = %s",
          mxf_uuid_to_string (&self->content_storage_uid, str));
      break;
    case 0x3b09:
      if (tag_size != 16)
        goto error;
      memcpy (&self->operational_pattern, tag_data, 16);
      GST_DEBUG ("  operational pattern = %s",
          mxf_ul_to_string (&self->operational_pattern, str));
      break;
    case 0x3b0a:
      if (!mxf_ul_array_parse (&self->essence_containers,
              &self->n_essence_containers, tag_data, tag_size))
        goto error;

      GST_DEBUG ("  number of essence containers = %u",
          self->n_essence_containers);
#ifndef GST_DISABLE_GST_DEBUG
      {
        guint i;
        for (i = 0; i < self->n_essence_containers; i++) {
          GST_DEBUG ("  essence container %u = %s", i,
              mxf_ul_to_string (&self->essence_containers[i], str));
        }
      }
#endif
      break;
    case 0x3b0b:
      if (!mxf_ul_array_parse (&self->dm_schemes, &self->n_dm_schemes, tag_data,
              tag_size))
        goto error;
      GST_DEBUG ("  number of DM schemes = %u", self->n_dm_schemes);

#ifndef GST_DISABLE_GST_DEBUG
      {
        guint i;
        for (i = 0; i < self->n_dm_schemes; i++) {
          GST_DEBUG ("  DM schemes %u = %s", i,
              mxf_ul_to_string (&self->dm_schemes[i], str));
        }
      }
#endif
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_preface_parent_class)->handle_tag (metadata, primer,
          tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR ("Invalid preface local tag 0x%04x of size %u", tag, tag_size);

  return FALSE;
}

static gboolean
mxf_metadata_preface_resolve (MXFMetadataBase * m, GHashTable * metadata)
{
  MXFMetadataPreface *self = MXF_METADATA_PREFACE (m);
  MXFMetadataBase *current = NULL;
  guint i;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  if (!mxf_uuid_is_zero (&self->primary_package_uid)) {
    current = g_hash_table_lookup (metadata, &self->primary_package_uid);
    if (!current || !MXF_IS_METADATA_GENERIC_PACKAGE (current)) {
      GST_ERROR ("Primary package %s not found",
          mxf_uuid_to_string (&self->primary_package_uid, str));
    } else {
      if (mxf_metadata_base_resolve (current, metadata)) {
        self->primary_package = MXF_METADATA_GENERIC_PACKAGE (current);
      }
    }
  }
  current = NULL;

  current = g_hash_table_lookup (metadata, &self->content_storage_uid);
  if (!current || !MXF_IS_METADATA_CONTENT_STORAGE (current)) {
    GST_ERROR ("Content storage %s not found",
        mxf_uuid_to_string (&self->content_storage_uid, str));
    return FALSE;
  } else {
    if (mxf_metadata_base_resolve (current, metadata)) {
      self->content_storage = MXF_METADATA_CONTENT_STORAGE (current);
    } else {
      GST_ERROR ("Couldn't resolve content storage %s",
          mxf_uuid_to_string (&self->content_storage_uid, str));
      return FALSE;
    }
  }
  current = NULL;

  if (self->identifications)
    memset (self->identifications, 0,
        sizeof (gpointer) * self->n_identifications);
  else
    self->identifications =
        g_new0 (MXFMetadataIdentification *, self->n_identifications);
  for (i = 0; i < self->n_identifications; i++) {
    current = g_hash_table_lookup (metadata, &self->identifications_uids[i]);
    if (current && MXF_IS_METADATA_IDENTIFICATION (current)) {
      if (mxf_metadata_base_resolve (current, metadata))
        self->identifications[i] = MXF_METADATA_IDENTIFICATION (current);
    }
    current = NULL;
  }

  return
      MXF_METADATA_BASE_CLASS (mxf_metadata_preface_parent_class)->resolve (m,
      metadata);
}

static GstStructure *
mxf_metadata_preface_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS (mxf_metadata_preface_parent_class)->to_structure
      (m);
  MXFMetadataPreface *self = MXF_METADATA_PREFACE (m);
  gchar str[48];
  guint i;

  if (!mxf_timestamp_is_unknown (&self->last_modified_date)) {
    mxf_timestamp_to_string (&self->last_modified_date, str);
    gst_structure_id_set (ret, MXF_QUARK (LAST_MODIFIED_DATE), G_TYPE_STRING,
        str, NULL);
  }

  if (self->version != 0)
    gst_structure_id_set (ret, MXF_QUARK (VERSION), G_TYPE_UINT, self->version,
        NULL);

  if (self->object_model_version != 0)
    gst_structure_id_set (ret, MXF_QUARK (OBJECT_MODEL_VERSION), G_TYPE_UINT,
        self->object_model_version, NULL);

  if (!mxf_uuid_is_zero (&self->primary_package_uid)) {
    mxf_uuid_to_string (&self->primary_package_uid, str);
    gst_structure_id_set (ret, MXF_QUARK (PRIMARY_PACKAGE), G_TYPE_STRING, str,
        NULL);
  }

  if (self->n_identifications > 0) {
    GValue arr = { 0, }
    , val = {
    0,};

    g_value_init (&arr, GST_TYPE_ARRAY);

    for (i = 0; i < self->n_identifications; i++) {
      GstStructure *s;

      if (self->identifications[i] == NULL)
        continue;

      g_value_init (&val, GST_TYPE_STRUCTURE);

      s = mxf_metadata_base_to_structure (MXF_METADATA_BASE
          (self->identifications[i]));
      gst_value_set_structure (&val, s);
      gst_structure_free (s);
      gst_value_array_append_value (&arr, &val);
      g_value_unset (&val);
    }

    if (gst_value_array_get_size (&arr) > 0)
      gst_structure_id_set_value (ret, MXF_QUARK (IDENTIFICATIONS), &arr);

    g_value_unset (&arr);
  }

  if (self->content_storage) {
    GstStructure *s =
        mxf_metadata_base_to_structure (MXF_METADATA_BASE
        (self->content_storage));
    gst_structure_id_set (ret, MXF_QUARK (CONTENT_STORAGE), GST_TYPE_STRUCTURE,
        s, NULL);
    gst_structure_free (s);
  }

  if (!mxf_ul_is_zero (&self->operational_pattern)) {
    mxf_ul_to_string (&self->operational_pattern, str);
    gst_structure_id_set (ret, MXF_QUARK (OPERATIONAL_PATTERN), G_TYPE_STRING,
        str, NULL);
  }

  if (self->n_essence_containers > 0) {
    GValue arr = { 0, }
    , val = {
    0,};

    g_value_init (&arr, GST_TYPE_ARRAY);

    for (i = 0; i < self->n_essence_containers; i++) {
      if (mxf_ul_is_zero (&self->essence_containers[i]))
        continue;

      g_value_init (&val, G_TYPE_STRING);

      mxf_ul_to_string (&self->essence_containers[i], str);
      g_value_set_string (&val, str);

      gst_value_array_append_value (&arr, &val);
      g_value_unset (&val);
    }

    if (gst_value_array_get_size (&arr) > 0)
      gst_structure_id_set_value (ret, MXF_QUARK (ESSENCE_CONTAINERS), &arr);

    g_value_unset (&arr);
  }

  if (self->n_dm_schemes > 0) {
    GValue arr = { 0, }
    , val = {
    0,};

    g_value_init (&arr, GST_TYPE_ARRAY);

    for (i = 0; i < self->n_dm_schemes; i++) {
      if (mxf_ul_is_zero (&self->dm_schemes[i]))
        continue;

      g_value_init (&val, G_TYPE_STRING);

      mxf_ul_to_string (&self->dm_schemes[i], str);
      g_value_set_string (&val, str);

      gst_value_array_append_value (&arr, &val);
      g_value_unset (&val);
    }

    if (gst_value_array_get_size (&arr) > 0)
      gst_structure_id_set_value (ret, MXF_QUARK (DM_SCHEMES), &arr);

    g_value_unset (&arr);
  }

  return ret;
}

static GList *
mxf_metadata_preface_write_tags (MXFMetadataBase * m, MXFPrimerPack * primer)
{
  MXFMetadataPreface *self = MXF_METADATA_PREFACE (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS (mxf_metadata_preface_parent_class)->write_tags
      (m, primer);
  MXFLocalTag *t;
  guint i;

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (LAST_MODIFIED_DATE), 16);
  t->size = 8;
  t->data = g_slice_alloc (8);
  t->g_slice = TRUE;
  mxf_timestamp_write (&self->last_modified_date, t->data);
  mxf_primer_pack_add_mapping (primer, 0x3b02, &t->ul);
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (VERSION), 16);
  t->size = 2;
  t->data = g_slice_alloc (2);
  t->g_slice = TRUE;
  GST_WRITE_UINT16_BE (t->data, self->version);
  mxf_primer_pack_add_mapping (primer, 0x3b05, &t->ul);
  ret = g_list_prepend (ret, t);

  if (self->object_model_version) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (OBJECT_MODEL_VERSION), 16);
    t->size = 4;
    t->data = g_slice_alloc (4);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->object_model_version);
    mxf_primer_pack_add_mapping (primer, 0x3b07, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (!mxf_uuid_is_zero (&self->primary_package_uid)) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (PRIMARY_PACKAGE), 16);
    t->size = 16;
    t->data = g_slice_alloc (16);
    t->g_slice = TRUE;
    memcpy (t->data, &self->primary_package_uid, 16);
    mxf_primer_pack_add_mapping (primer, 0x3b08, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (IDENTIFICATIONS), 16);
  t->size = 8 + 16 * self->n_identifications;
  t->data = g_slice_alloc0 (t->size);
  t->g_slice = TRUE;
  mxf_primer_pack_add_mapping (primer, 0x3b06, &t->ul);
  GST_WRITE_UINT32_BE (t->data, self->n_identifications);
  GST_WRITE_UINT32_BE (t->data + 4, 16);
  for (i = 0; i < self->n_identifications; i++) {
    if (!self->identifications[i])
      continue;

    memcpy (t->data + 8 + 16 * i,
        &MXF_METADATA_BASE (self->identifications[i])->instance_uid, 16);
  }
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (CONTENT_STORAGE), 16);
  t->size = 16;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  mxf_primer_pack_add_mapping (primer, 0x3b03, &t->ul);
  memcpy (t->data, &MXF_METADATA_BASE (self->content_storage)->instance_uid,
      16);
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (OPERATIONAL_PATTERN), 16);
  t->size = 16;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  mxf_primer_pack_add_mapping (primer, 0x3b09, &t->ul);
  memcpy (t->data, &self->operational_pattern, 16);
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (ESSENCE_CONTAINERS), 16);
  t->size = 8 + 16 * self->n_essence_containers;
  t->data = g_slice_alloc0 (t->size);
  t->g_slice = TRUE;
  mxf_primer_pack_add_mapping (primer, 0x3b0a, &t->ul);
  GST_WRITE_UINT32_BE (t->data, self->n_essence_containers);
  GST_WRITE_UINT32_BE (t->data + 4, 16);
  for (i = 0; i < self->n_essence_containers; i++) {
    memcpy (t->data + 8 + 16 * i, &self->essence_containers[i], 16);
  }
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (DM_SCHEMES), 16);
  t->size = 8 + 16 * self->n_dm_schemes;
  t->data = g_slice_alloc0 (t->size);
  t->g_slice = TRUE;
  mxf_primer_pack_add_mapping (primer, 0x3b0b, &t->ul);
  GST_WRITE_UINT32_BE (t->data, self->n_dm_schemes);
  GST_WRITE_UINT32_BE (t->data + 4, 16);
  for (i = 0; i < self->n_dm_schemes; i++) {
    memcpy (t->data + 8 + 16 * i, &self->dm_schemes[i], 16);
  }
  ret = g_list_prepend (ret, t);

  return ret;
}

static void
mxf_metadata_preface_init (MXFMetadataPreface * self)
{

}

static void
mxf_metadata_preface_class_init (MXFMetadataPrefaceClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  GObjectClass *object_class = (GObjectClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  object_class->finalize = mxf_metadata_preface_finalize;
  metadata_base_class->handle_tag = mxf_metadata_preface_handle_tag;
  metadata_base_class->resolve = mxf_metadata_preface_resolve;
  metadata_base_class->to_structure = mxf_metadata_preface_to_structure;
  metadata_base_class->write_tags = mxf_metadata_preface_write_tags;
  metadata_base_class->name_quark = MXF_QUARK (PREFACE);
  metadata_class->type = 0x012f;
}

G_DEFINE_TYPE (MXFMetadataIdentification, mxf_metadata_identification,
    MXF_TYPE_METADATA);

static void
mxf_metadata_identification_finalize (GObject * object)
{
  MXFMetadataIdentification *self = MXF_METADATA_IDENTIFICATION (object);

  g_free (self->company_name);
  self->company_name = NULL;

  g_free (self->product_name);
  self->product_name = NULL;

  g_free (self->version_string);
  self->version_string = NULL;

  g_free (self->platform);
  self->platform = NULL;

  G_OBJECT_CLASS (mxf_metadata_identification_parent_class)->finalize (object);
}

static gboolean
mxf_metadata_identification_handle_tag (MXFMetadataBase * metadata,
    MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataIdentification *self = MXF_METADATA_IDENTIFICATION (metadata);
  gboolean ret = TRUE;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  switch (tag) {
    case 0x3c09:
      if (tag_size != 16)
        goto error;
      memcpy (&self->this_generation_uid, tag_data, 16);
      GST_DEBUG ("  this generation uid = %s",
          mxf_uuid_to_string (&self->this_generation_uid, str));
      break;
    case 0x3c01:
      self->company_name = mxf_utf16_to_utf8 (tag_data, tag_size);
      GST_DEBUG ("  company name = %s", GST_STR_NULL (self->company_name));
      break;
    case 0x3c02:
      self->product_name = mxf_utf16_to_utf8 (tag_data, tag_size);
      GST_DEBUG ("  product name = %s", GST_STR_NULL (self->product_name));
      break;
    case 0x3c03:
      if (!mxf_product_version_parse (&self->product_version,
              tag_data, tag_size))
        goto error;
      GST_DEBUG ("  product version = %u.%u.%u.%u.%u",
          self->product_version.major,
          self->product_version.minor,
          self->product_version.patch,
          self->product_version.build, self->product_version.release);
      break;
    case 0x3c04:
      self->version_string = mxf_utf16_to_utf8 (tag_data, tag_size);
      GST_DEBUG ("  version string = %s", GST_STR_NULL (self->version_string));
      break;
    case 0x3c05:
      if (tag_size != 16)
        goto error;
      memcpy (&self->product_uid, tag_data, 16);
      GST_DEBUG ("  product uid = %s",
          mxf_uuid_to_string (&self->product_uid, str));
      break;
    case 0x3c06:
      if (!mxf_timestamp_parse (&self->modification_date, tag_data, tag_size))
        goto error;
      GST_DEBUG ("  modification date = %s",
          mxf_timestamp_to_string (&self->modification_date, str));
      break;
    case 0x3c07:
      if (!mxf_product_version_parse (&self->toolkit_version,
              tag_data, tag_size))
        goto error;
      GST_DEBUG ("  toolkit version = %u.%u.%u.%u.%u",
          self->toolkit_version.major,
          self->toolkit_version.minor,
          self->toolkit_version.patch,
          self->toolkit_version.build, self->toolkit_version.release);
      break;
    case 0x3c08:
      self->platform = mxf_utf16_to_utf8 (tag_data, tag_size);
      GST_DEBUG ("  platform = %s", GST_STR_NULL (self->platform));
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_identification_parent_class)->handle_tag (metadata,
          primer, tag, tag_data, tag_size);
      break;
  }

  return ret;

error:
  GST_ERROR ("Invalid identification local tag 0x%04x of size %u", tag,
      tag_size);

  return FALSE;
}

static GstStructure *
mxf_metadata_identification_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_identification_parent_class)->to_structure (m);
  MXFMetadataIdentification *self = MXF_METADATA_IDENTIFICATION (m);
  gchar str[48];

  if (!mxf_uuid_is_zero (&self->this_generation_uid)) {
    mxf_uuid_to_string (&self->this_generation_uid, str);
    gst_structure_id_set (ret, MXF_QUARK (THIS_GENERATION_UID), G_TYPE_STRING,
        str, NULL);
  }

  if (self->company_name)
    gst_structure_id_set (ret, MXF_QUARK (COMPANY_NAME), G_TYPE_STRING,
        self->company_name, NULL);

  if (self->product_name)
    gst_structure_id_set (ret, MXF_QUARK (PRODUCT_NAME), G_TYPE_STRING,
        self->product_name, NULL);

  if (self->product_version.major ||
      self->product_version.minor ||
      self->product_version.patch ||
      self->product_version.build || self->product_version.release) {
    g_snprintf (str, 48, "%u.%u.%u.%u.%u", self->product_version.major,
        self->product_version.minor,
        self->product_version.patch,
        self->product_version.build, self->product_version.release);
    gst_structure_id_set (ret, MXF_QUARK (PRODUCT_VERSION), G_TYPE_STRING, str,
        NULL);
  }

  if (self->version_string)
    gst_structure_id_set (ret, MXF_QUARK (VERSION_STRING), G_TYPE_STRING,
        self->version_string, NULL);

  if (!mxf_uuid_is_zero (&self->product_uid)) {
    mxf_uuid_to_string (&self->product_uid, str);
    gst_structure_id_set (ret, MXF_QUARK (PRODUCT_UID), G_TYPE_STRING, str,
        NULL);
  }

  if (!mxf_timestamp_is_unknown (&self->modification_date)) {
    mxf_timestamp_to_string (&self->modification_date, str);
    gst_structure_id_set (ret, MXF_QUARK (MODIFICATION_DATE), G_TYPE_STRING,
        str, NULL);
  }

  if (self->toolkit_version.major ||
      self->toolkit_version.minor ||
      self->toolkit_version.patch ||
      self->toolkit_version.build || self->toolkit_version.release) {
    g_snprintf (str, 48, "%u.%u.%u.%u.%u", self->toolkit_version.major,
        self->toolkit_version.minor,
        self->toolkit_version.patch,
        self->toolkit_version.build, self->toolkit_version.release);
    gst_structure_id_set (ret, MXF_QUARK (TOOLKIT_VERSION), G_TYPE_STRING, str,
        NULL);
  }

  if (self->platform)
    gst_structure_id_set (ret, MXF_QUARK (PLATFORM), G_TYPE_STRING,
        self->platform, NULL);

  return ret;
}

static GList *
mxf_metadata_identification_write_tags (MXFMetadataBase * m,
    MXFPrimerPack * primer)
{
  MXFMetadataIdentification *self = MXF_METADATA_IDENTIFICATION (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_identification_parent_class)->write_tags (m, primer);
  MXFLocalTag *t;

  if (self->company_name) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (COMPANY_NAME), 16);
    t->data = mxf_utf8_to_utf16 (self->company_name, &t->size);
    mxf_primer_pack_add_mapping (primer, 0x3c01, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->product_name) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (PRODUCT_NAME), 16);
    t->data = mxf_utf8_to_utf16 (self->product_name, &t->size);
    mxf_primer_pack_add_mapping (primer, 0x3c02, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (!mxf_product_version_is_valid (&self->product_version)) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (PRODUCT_VERSION), 16);
    t->size = 10;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    mxf_product_version_write (&self->product_version, t->data);
    mxf_primer_pack_add_mapping (primer, 0x3c03, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->version_string) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (VERSION_STRING), 16);
    t->data = mxf_utf8_to_utf16 (self->version_string, &t->size);
    mxf_primer_pack_add_mapping (primer, 0x3c04, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (!mxf_uuid_is_zero (&self->product_uid)) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (PRODUCT_UID), 16);
    t->size = 16;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    memcpy (t->data, &self->product_uid, 16);
    mxf_primer_pack_add_mapping (primer, 0x3c05, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (!mxf_timestamp_is_unknown (&self->modification_date)) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (MODIFICATION_DATE), 16);
    t->size = 8;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    mxf_timestamp_write (&self->modification_date, t->data);
    mxf_primer_pack_add_mapping (primer, 0x3c06, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (!mxf_product_version_is_valid (&self->toolkit_version)) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (TOOLKIT_VERSION), 16);
    t->size = 10;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    mxf_product_version_write (&self->toolkit_version, t->data);
    mxf_primer_pack_add_mapping (primer, 0x3c07, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->platform) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (PLATFORM), 16);
    t->data = mxf_utf8_to_utf16 (self->platform, &t->size);
    mxf_primer_pack_add_mapping (primer, 0x3c08, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (!mxf_uuid_is_zero (&self->this_generation_uid)) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (THIS_GENERATION_UID), 16);
    t->size = 16;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    memcpy (t->data, &self->this_generation_uid, 16);
    mxf_primer_pack_add_mapping (primer, 0x3c09, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  return ret;
}

static void
mxf_metadata_identification_init (MXFMetadataIdentification * self)
{

}

static void
mxf_metadata_identification_class_init (MXFMetadataIdentificationClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  GObjectClass *object_class = (GObjectClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  object_class->finalize = mxf_metadata_identification_finalize;
  metadata_base_class->handle_tag = mxf_metadata_identification_handle_tag;
  metadata_base_class->name_quark = MXF_QUARK (IDENTIFICATION);
  metadata_base_class->to_structure = mxf_metadata_identification_to_structure;
  metadata_base_class->write_tags = mxf_metadata_identification_write_tags;
  metadata_class->type = 0x0130;
}

G_DEFINE_TYPE (MXFMetadataContentStorage, mxf_metadata_content_storage,
    MXF_TYPE_METADATA);

static void
mxf_metadata_content_storage_finalize (GObject * object)
{
  MXFMetadataContentStorage *self = MXF_METADATA_CONTENT_STORAGE (object);

  g_free (self->packages);
  self->packages = NULL;
  g_free (self->packages_uids);
  self->packages_uids = NULL;
  g_free (self->essence_container_data);
  self->essence_container_data = NULL;
  g_free (self->essence_container_data_uids);
  self->essence_container_data_uids = NULL;

  G_OBJECT_CLASS (mxf_metadata_content_storage_parent_class)->finalize (object);
}

static gboolean
mxf_metadata_content_storage_handle_tag (MXFMetadataBase * metadata,
    MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataContentStorage *self = MXF_METADATA_CONTENT_STORAGE (metadata);
  gboolean ret = TRUE;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  switch (tag) {
    case 0x1901:
      if (!mxf_uuid_array_parse (&self->packages_uids, &self->n_packages,
              tag_data, tag_size))
        goto error;
      GST_DEBUG ("  number of packages = %u", self->n_packages);
#ifndef GST_DISABLE_GST_DEBUG
      {
        guint i;
        for (i = 0; i < self->n_packages; i++) {
          GST_DEBUG ("  package %u = %s", i,
              mxf_uuid_to_string (&self->packages_uids[i], str));
        }
      }
#endif
      break;
    case 0x1902:
      if (!mxf_uuid_array_parse (&self->essence_container_data_uids,
              &self->n_essence_container_data, tag_data, tag_size))
        goto error;

      GST_DEBUG ("  number of essence container data = %u",
          self->n_essence_container_data);
#ifndef GST_DISABLE_GST_DEBUG
      {
        guint i;
        for (i = 0; i < self->n_essence_container_data; i++) {
          GST_DEBUG ("  essence container data %u = %s", i,
              mxf_uuid_to_string (&self->essence_container_data_uids[i], str));
        }
      }
#endif
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_content_storage_parent_class)->handle_tag (metadata,
          primer, tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR ("Invalid content storage local tag 0x%04x of size %u", tag,
      tag_size);

  return FALSE;
}

static gboolean
mxf_metadata_content_storage_resolve (MXFMetadataBase * m,
    GHashTable * metadata)
{
  MXFMetadataContentStorage *self = MXF_METADATA_CONTENT_STORAGE (m);
  MXFMetadataBase *current = NULL;
  guint i;
  gboolean have_package = FALSE;
  gboolean have_ecd = FALSE;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  if (self->packages)
    memset (self->packages, 0, sizeof (gpointer) * self->n_packages);
  else
    self->packages = g_new0 (MXFMetadataGenericPackage *, self->n_packages);

  for (i = 0; i < self->n_packages; i++) {
    current = g_hash_table_lookup (metadata, &self->packages_uids[i]);
    if (current && MXF_IS_METADATA_GENERIC_PACKAGE (current)) {
      if (mxf_metadata_base_resolve (current, metadata)) {
        self->packages[i] = MXF_METADATA_GENERIC_PACKAGE (current);
        have_package = TRUE;
      } else {
        GST_ERROR ("Couldn't resolve package %s",
            mxf_uuid_to_string (&self->packages_uids[i], str));
      }
    } else {
      GST_ERROR ("Package %s not found",
          mxf_uuid_to_string (&self->packages_uids[i], str));
    }
  }

  if (self->essence_container_data)
    memset (self->essence_container_data, 0,
        sizeof (gpointer) * self->n_essence_container_data);
  else
    self->essence_container_data =
        g_new0 (MXFMetadataEssenceContainerData *,
        self->n_essence_container_data);
  for (i = 0; i < self->n_essence_container_data; i++) {
    current =
        g_hash_table_lookup (metadata, &self->essence_container_data_uids[i]);
    if (current && MXF_IS_METADATA_ESSENCE_CONTAINER_DATA (current)) {
      if (mxf_metadata_base_resolve (current, metadata)) {
        self->essence_container_data[i] =
            MXF_METADATA_ESSENCE_CONTAINER_DATA (current);
        have_ecd = TRUE;
      } else {
        GST_ERROR ("Couldn't resolve essence container data %s",
            mxf_uuid_to_string (&self->essence_container_data_uids[i], str));
      }
    } else {
      GST_ERROR ("Essence container data %s not found",
          mxf_uuid_to_string (&self->essence_container_data_uids[i], str));
    }
  }

  if (!have_package) {
    GST_ERROR ("Couldn't resolve any package");
    return FALSE;
  } else if (!have_ecd) {
    GST_ERROR ("Couldn't resolve any essence container data");
    return FALSE;
  }

  return
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_content_storage_parent_class)->resolve (m, metadata);
}

static GstStructure *
mxf_metadata_content_storage_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_content_storage_parent_class)->to_structure (m);
  MXFMetadataContentStorage *self = MXF_METADATA_CONTENT_STORAGE (m);
  guint i;

  if (self->n_packages > 0) {
    GValue arr = { 0, }
    , val = {
    0,};

    g_value_init (&arr, GST_TYPE_ARRAY);

    for (i = 0; i < self->n_packages; i++) {
      GstStructure *s;

      if (self->packages[i] == NULL)
        continue;

      g_value_init (&val, GST_TYPE_STRUCTURE);

      s = mxf_metadata_base_to_structure (MXF_METADATA_BASE (self->packages
              [i]));
      gst_value_set_structure (&val, s);
      gst_structure_free (s);
      gst_value_array_append_value (&arr, &val);
      g_value_unset (&val);
    }

    if (gst_value_array_get_size (&arr) > 0)
      gst_structure_id_set_value (ret, MXF_QUARK (PACKAGES), &arr);

    g_value_unset (&arr);
  }

  if (self->n_essence_container_data > 0) {
    GValue arr = { 0, }
    , val = {
    0,};

    g_value_init (&arr, GST_TYPE_ARRAY);

    for (i = 0; i < self->n_essence_container_data; i++) {
      GstStructure *s;

      if (self->essence_container_data[i] == NULL)
        continue;

      g_value_init (&val, GST_TYPE_STRUCTURE);

      s = mxf_metadata_base_to_structure (MXF_METADATA_BASE
          (self->essence_container_data[i]));
      gst_value_set_structure (&val, s);
      gst_structure_free (s);
      gst_value_array_append_value (&arr, &val);
      g_value_unset (&val);
    }

    if (gst_value_array_get_size (&arr) > 0)
      gst_structure_id_set_value (ret, MXF_QUARK (ESSENCE_CONTAINER_DATA),
          &arr);

    g_value_unset (&arr);
  }

  return ret;
}

static GList *
mxf_metadata_content_storage_write_tags (MXFMetadataBase * m,
    MXFPrimerPack * primer)
{
  MXFMetadataContentStorage *self = MXF_METADATA_CONTENT_STORAGE (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_content_storage_parent_class)->write_tags (m, primer);
  MXFLocalTag *t;
  guint i;

  if (self->packages) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (PACKAGES), 16);
    t->size = 8 + 16 * self->n_packages;
    t->data = g_slice_alloc0 (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->n_packages);
    GST_WRITE_UINT32_BE (t->data + 4, 16);
    for (i = 0; i < self->n_packages; i++) {
      if (!self->packages[i])
        continue;

      memcpy (t->data + 8 + i * 16,
          &MXF_METADATA_BASE (self->packages[i])->instance_uid, 16);
    }

    mxf_primer_pack_add_mapping (primer, 0x1901, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->essence_container_data) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (ESSENCE_CONTAINER_DATA), 16);
    t->size = 8 + 16 * self->n_essence_container_data;
    t->data = g_slice_alloc0 (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->n_essence_container_data);
    GST_WRITE_UINT32_BE (t->data + 4, 16);
    for (i = 0; i < self->n_essence_container_data; i++) {
      if (!self->essence_container_data[i])
        continue;

      memcpy (t->data + 8 + i * 16,
          &MXF_METADATA_BASE (self->essence_container_data[i])->instance_uid,
          16);
    }

    mxf_primer_pack_add_mapping (primer, 0x1902, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  return ret;
}

static void
mxf_metadata_content_storage_init (MXFMetadataContentStorage * self)
{

}

static void
mxf_metadata_content_storage_class_init (MXFMetadataContentStorageClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  GObjectClass *object_class = (GObjectClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  object_class->finalize = mxf_metadata_content_storage_finalize;
  metadata_base_class->handle_tag = mxf_metadata_content_storage_handle_tag;
  metadata_base_class->resolve = mxf_metadata_content_storage_resolve;
  metadata_base_class->name_quark = MXF_QUARK (CONTENT_STORAGE);
  metadata_base_class->to_structure = mxf_metadata_content_storage_to_structure;
  metadata_base_class->write_tags = mxf_metadata_content_storage_write_tags;
  metadata_class->type = 0x0118;
}

G_DEFINE_TYPE (MXFMetadataEssenceContainerData,
    mxf_metadata_essence_container_data, MXF_TYPE_METADATA);

static gboolean
mxf_metadata_essence_container_data_handle_tag (MXFMetadataBase * metadata,
    MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataEssenceContainerData *self =
      MXF_METADATA_ESSENCE_CONTAINER_DATA (metadata);
  gboolean ret = TRUE;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[96];
#endif

  switch (tag) {
    case 0x2701:
      if (tag_size != 32)
        goto error;
      memcpy (&self->linked_package_uid, tag_data, 32);
      GST_DEBUG ("  linked package = %s",
          mxf_umid_to_string (&self->linked_package_uid, str));
      break;
    case 0x3f06:
      if (tag_size != 4)
        goto error;
      self->index_sid = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  index sid = %u", self->index_sid);
      break;
    case 0x3f07:
      if (tag_size != 4)
        goto error;
      self->body_sid = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  body sid = %u", self->body_sid);
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_essence_container_data_parent_class)->handle_tag
          (metadata, primer, tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR ("Invalid essence container data local tag 0x%04x of size %u", tag,
      tag_size);

  return FALSE;
}

static gboolean
mxf_metadata_essence_container_data_resolve (MXFMetadataBase * m,
    GHashTable * metadata)
{
  MXFMetadataEssenceContainerData *self =
      MXF_METADATA_ESSENCE_CONTAINER_DATA (m);
  MXFMetadataBase *current = NULL;
  GHashTableIter iter;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[96];
#endif

  g_hash_table_iter_init (&iter, metadata);

  while (g_hash_table_iter_next (&iter, NULL, (gpointer) & current)) {
    if (MXF_IS_METADATA_SOURCE_PACKAGE (current)) {
      MXFMetadataSourcePackage *package = MXF_METADATA_SOURCE_PACKAGE (current);

      if (mxf_umid_is_equal (&package->parent.package_uid,
              &self->linked_package_uid)) {
        if (mxf_metadata_base_resolve (current, metadata)) {
          self->linked_package = package;
        } else {
          GST_ERROR ("Couldn't resolve linked package %s",
              mxf_umid_to_string (&self->linked_package_uid, str));
        }
        break;
      }
    }
  }

  if (!self->linked_package) {
    GST_ERROR ("Couldn't resolve or find linked package %s",
        mxf_umid_to_string (&self->linked_package_uid, str));
    return FALSE;
  }

  return
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_essence_container_data_parent_class)->resolve (m, metadata);
}

static GstStructure *
mxf_metadata_essence_container_data_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_essence_container_data_parent_class)->to_structure (m);
  MXFMetadataEssenceContainerData *self =
      MXF_METADATA_ESSENCE_CONTAINER_DATA (m);
  gchar str[96];

  if (!mxf_umid_is_zero (&self->linked_package_uid)) {
    mxf_umid_to_string (&self->linked_package_uid, str);
    gst_structure_id_set (ret, MXF_QUARK (LINKED_PACKAGE), G_TYPE_STRING, str,
        NULL);
  }

  gst_structure_id_set (ret, MXF_QUARK (INDEX_SID), G_TYPE_UINT,
      self->index_sid, MXF_QUARK (BODY_SID), G_TYPE_UINT, self->body_sid, NULL);


  return ret;
}

static GList *
mxf_metadata_essence_container_data_write_tags (MXFMetadataBase * m,
    MXFPrimerPack * primer)
{
  MXFMetadataEssenceContainerData *self =
      MXF_METADATA_ESSENCE_CONTAINER_DATA (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_essence_container_data_parent_class)->write_tags (m,
      primer);
  MXFLocalTag *t;

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (LINKED_PACKAGE_UID), 16);
  t->size = 32;
  t->data = g_slice_alloc0 (32);
  t->g_slice = TRUE;
  if (self->linked_package)
    memcpy (t->data, &self->linked_package->parent.package_uid, 32);
  mxf_primer_pack_add_mapping (primer, 0x2701, &t->ul);
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (BODY_SID), 16);
  t->size = 4;
  t->data = g_slice_alloc (4);
  t->g_slice = TRUE;
  GST_WRITE_UINT32_BE (t->data, self->body_sid);
  mxf_primer_pack_add_mapping (primer, 0x3f07, &t->ul);
  ret = g_list_prepend (ret, t);

  if (self->index_sid) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (INDEX_SID), 16);
    t->size = 4;
    t->data = g_slice_alloc (4);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->index_sid);
    mxf_primer_pack_add_mapping (primer, 0x3f06, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  return ret;
}

static void
mxf_metadata_essence_container_data_init (MXFMetadataEssenceContainerData *
    self)
{

}

static void
    mxf_metadata_essence_container_data_class_init
    (MXFMetadataEssenceContainerDataClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  metadata_base_class->handle_tag =
      mxf_metadata_essence_container_data_handle_tag;
  metadata_base_class->resolve = mxf_metadata_essence_container_data_resolve;
  metadata_base_class->name_quark = MXF_QUARK (ESSENCE_CONTAINER_DATA);
  metadata_base_class->to_structure =
      mxf_metadata_essence_container_data_to_structure;
  metadata_base_class->write_tags =
      mxf_metadata_essence_container_data_write_tags;
  metadata_class->type = 0x0123;
}

G_DEFINE_ABSTRACT_TYPE (MXFMetadataGenericPackage, mxf_metadata_generic_package,
    MXF_TYPE_METADATA);

static void
mxf_metadata_generic_package_finalize (GObject * object)
{
  MXFMetadataGenericPackage *self = MXF_METADATA_GENERIC_PACKAGE (object);

  g_free (self->name);
  self->name = NULL;
  g_free (self->tracks_uids);
  self->tracks_uids = NULL;

  g_free (self->tracks);
  self->tracks = NULL;

  G_OBJECT_CLASS (mxf_metadata_generic_package_parent_class)->finalize (object);
}

static gboolean
mxf_metadata_generic_package_handle_tag (MXFMetadataBase * metadata,
    MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataGenericPackage *self = MXF_METADATA_GENERIC_PACKAGE (metadata);
  gboolean ret = TRUE;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[96];
#endif

  switch (tag) {
    case 0x4401:
      if (tag_size != 32)
        goto error;
      memcpy (&self->package_uid, tag_data, 32);
      GST_DEBUG ("  UMID = %s", mxf_umid_to_string (&self->package_uid, str));
      break;
    case 0x4402:
      self->name = mxf_utf16_to_utf8 (tag_data, tag_size);
      GST_DEBUG ("  name = %s", GST_STR_NULL (self->name));
      break;
    case 0x4405:
      if (!mxf_timestamp_parse (&self->package_creation_date,
              tag_data, tag_size))
        goto error;
      GST_DEBUG ("  creation date = %s",
          mxf_timestamp_to_string (&self->package_creation_date, str));
      break;
    case 0x4404:
      if (!mxf_timestamp_parse (&self->package_modified_date,
              tag_data, tag_size))
        goto error;
      GST_DEBUG ("  modification date = %s",
          mxf_timestamp_to_string (&self->package_modified_date, str));
      break;
    case 0x4403:
      if (!mxf_uuid_array_parse (&self->tracks_uids, &self->n_tracks, tag_data,
              tag_size))
        goto error;

      GST_DEBUG ("  number of tracks = %u", self->n_tracks);
#ifndef GST_DISABLE_GST_DEBUG
      {
        guint i;
        for (i = 0; i < self->n_tracks; i++) {
          GST_DEBUG ("  track %u = %s", i,
              mxf_uuid_to_string (&self->tracks_uids[i], str));
        }
      }
#endif
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_generic_package_parent_class)->handle_tag (metadata,
          primer, tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR ("Invalid generic package local tag 0x%04x of size %u", tag,
      tag_size);

  return FALSE;
}

static gboolean
mxf_metadata_generic_package_resolve (MXFMetadataBase * m,
    GHashTable * metadata)
{
  MXFMetadataGenericPackage *self = MXF_METADATA_GENERIC_PACKAGE (m);
  MXFMetadataBase *current = NULL;
  guint i;
  gboolean have_track = FALSE;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  if (self->tracks)
    memset (self->tracks, 0, sizeof (gpointer) * self->n_tracks);
  else
    self->tracks = g_new0 (MXFMetadataTrack *, self->n_tracks);
  for (i = 0; i < self->n_tracks; i++) {
    current = g_hash_table_lookup (metadata, &self->tracks_uids[i]);
    if (current && MXF_IS_METADATA_TRACK (current)) {
      if (mxf_metadata_base_resolve (current, metadata)) {
        MXFMetadataTrack *track = MXF_METADATA_TRACK (current);

        self->tracks[i] = track;
        have_track = TRUE;
        if ((track->type & 0xf0) == 0x10)
          self->n_timecode_tracks++;
        else if ((track->type & 0xf0) == 0x20)
          self->n_metadata_tracks++;
        else if ((track->type & 0xf0) == 0x30)
          self->n_essence_tracks++;
        else if ((track->type & 0xf0) == 0x40)
          self->n_other_tracks++;
      } else {
        GST_ERROR ("Track %s couldn't be resolved",
            mxf_uuid_to_string (&self->tracks_uids[i], str));
      }
    } else {
      GST_ERROR ("Track %s not found",
          mxf_uuid_to_string (&self->tracks_uids[i], str));
    }
  }

  if (!have_track) {
    GST_ERROR ("Couldn't resolve a track");
    return FALSE;
  }

  return
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_generic_package_parent_class)->resolve (m, metadata);
}

static GstStructure *
mxf_metadata_generic_package_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_generic_package_parent_class)->to_structure (m);
  MXFMetadataGenericPackage *self = MXF_METADATA_GENERIC_PACKAGE (m);
  guint i;
  gchar str[96];

  mxf_umid_to_string (&self->package_uid, str);
  gst_structure_id_set (ret, MXF_QUARK (PACKAGE_UID), G_TYPE_STRING, str, NULL);

  if (self->name)
    gst_structure_id_set (ret, MXF_QUARK (NAME), G_TYPE_STRING, self->name,
        NULL);

  if (!mxf_timestamp_is_unknown (&self->package_creation_date)) {
    mxf_timestamp_to_string (&self->package_creation_date, str);
    gst_structure_id_set (ret, MXF_QUARK (PACKAGE_CREATION_DATE), G_TYPE_STRING,
        str, NULL);
  }

  if (!mxf_timestamp_is_unknown (&self->package_modified_date)) {
    mxf_timestamp_to_string (&self->package_modified_date, str);
    gst_structure_id_set (ret, MXF_QUARK (PACKAGE_MODIFIED_DATE), G_TYPE_STRING,
        str, NULL);
  }

  if (self->n_tracks > 0) {
    GValue arr = { 0, }
    , val = {
    0,};

    g_value_init (&arr, GST_TYPE_ARRAY);

    for (i = 0; i < self->n_tracks; i++) {
      GstStructure *s;

      if (self->tracks[i] == NULL)
        continue;

      g_value_init (&val, GST_TYPE_STRUCTURE);

      s = mxf_metadata_base_to_structure (MXF_METADATA_BASE (self->tracks[i]));
      gst_value_set_structure (&val, s);
      gst_structure_free (s);
      gst_value_array_append_value (&arr, &val);
      g_value_unset (&val);
    }

    if (gst_value_array_get_size (&arr) > 0)
      gst_structure_id_set_value (ret, MXF_QUARK (TRACKS), &arr);

    g_value_unset (&arr);
  }

  return ret;
}

static GList *
mxf_metadata_generic_package_write_tags (MXFMetadataBase * m,
    MXFPrimerPack * primer)
{
  MXFMetadataGenericPackage *self = MXF_METADATA_GENERIC_PACKAGE (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_generic_package_parent_class)->write_tags (m, primer);
  MXFLocalTag *t;

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (PACKAGE_UID), 16);
  t->size = 32;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  memcpy (t->data, &self->package_uid, 32);
  mxf_primer_pack_add_mapping (primer, 0x4401, &t->ul);
  ret = g_list_prepend (ret, t);

  if (self->name) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (PACKAGE_NAME), 16);
    t->data = mxf_utf8_to_utf16 (self->name, &t->size);
    mxf_primer_pack_add_mapping (primer, 0x4402, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (PACKAGE_CREATION_DATE), 16);
  t->size = 8;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  mxf_timestamp_write (&self->package_creation_date, t->data);
  mxf_primer_pack_add_mapping (primer, 0x4405, &t->ul);
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (PACKAGE_MODIFIED_DATE), 16);
  t->size = 8;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  mxf_timestamp_write (&self->package_modified_date, t->data);
  mxf_primer_pack_add_mapping (primer, 0x4404, &t->ul);
  ret = g_list_prepend (ret, t);

  if (self->tracks) {
    guint i;

    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (TRACKS), 16);
    t->size = 8 + 16 * self->n_tracks;
    t->data = g_slice_alloc0 (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->n_tracks);
    GST_WRITE_UINT32_BE (t->data + 4, 16);
    for (i = 0; i < self->n_tracks; i++) {
      if (!self->tracks[i])
        continue;

      memcpy (t->data + 8 + 16 * i,
          &MXF_METADATA_BASE (self->tracks[i])->instance_uid, 16);
    }
    mxf_primer_pack_add_mapping (primer, 0x4403, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  return ret;
}

static void
mxf_metadata_generic_package_init (MXFMetadataGenericPackage * self)
{

}

static void
mxf_metadata_generic_package_class_init (MXFMetadataGenericPackageClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  GObjectClass *object_class = (GObjectClass *) klass;

  object_class->finalize = mxf_metadata_generic_package_finalize;
  metadata_base_class->handle_tag = mxf_metadata_generic_package_handle_tag;
  metadata_base_class->resolve = mxf_metadata_generic_package_resolve;
  metadata_base_class->to_structure = mxf_metadata_generic_package_to_structure;
  metadata_base_class->write_tags = mxf_metadata_generic_package_write_tags;
}

G_DEFINE_TYPE (MXFMetadataMaterialPackage, mxf_metadata_material_package,
    MXF_TYPE_METADATA_GENERIC_PACKAGE);

static gboolean
mxf_metadata_material_package_resolve (MXFMetadataBase * m,
    GHashTable * metadata)
{
  gboolean ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_material_package_parent_class)->resolve (m, metadata);
  MXFMetadataGenericPackage *self = MXF_METADATA_GENERIC_PACKAGE (m);
  guint i;
  guint ntracks = 0;

  if (!ret)
    return ret;

  for (i = 0; i < self->n_tracks; i++) {
    MXFMetadataTrack *track = self->tracks[i];
    MXFMetadataSequence *sequence;
    guint j;

    if (!track)
      continue;

    sequence = track->sequence;

    if (!sequence || !sequence->structural_components)
      continue;

    for (j = 0; j < sequence->n_structural_components; j++) {
      MXFMetadataSourceClip *sc;
      MXFMetadataTimelineTrack *st = NULL;
      guint k;

      if (!sequence->structural_components[j]
          || !MXF_IS_METADATA_SOURCE_CLIP (sequence->structural_components[j]))
        continue;

      sc = MXF_METADATA_SOURCE_CLIP (sequence->structural_components[j]);

      if (!sc->source_package) {
        GST_ERROR ("Material package track %u without resolved source package",
            i);
        track = NULL;
        break;
      }

      if (!mxf_metadata_base_resolve (MXF_METADATA_BASE (sc->source_package),
              metadata)) {
        GST_ERROR ("Couldn't resolve source package for track %u", i);
        track = NULL;
        break;
      }

      sc->source_package->top_level = TRUE;
      for (k = 0; k < sc->source_package->parent.n_tracks; k++) {
        MXFMetadataTimelineTrack *tmp;

        if (!sc->source_package->parent.tracks[k] ||
            !MXF_IS_METADATA_TIMELINE_TRACK (sc->source_package->parent.
                tracks[k]))
          continue;

        tmp =
            MXF_METADATA_TIMELINE_TRACK (sc->source_package->parent.tracks[k]);
        if (tmp->parent.track_id == sc->source_track_id) {
          st = tmp;
          break;
        }
      }

      if (!st) {
        GST_ERROR ("Material package track %u without resolved source track",
            i);
        track = NULL;
      }
    }

    if (track)
      ntracks++;
    else
      self->tracks[i] = NULL;
  }

  if (ntracks == 0) {
    GST_ERROR ("No tracks could be resolved");
    return FALSE;
  } else if (ntracks != self->n_tracks) {
    GST_WARNING ("Not all tracks could be resolved");
  }

  return TRUE;
}

static void
mxf_metadata_material_package_init (MXFMetadataMaterialPackage * self)
{
}

static void
mxf_metadata_material_package_class_init (MXFMetadataMaterialPackageClass *
    klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  metadata_base_class->resolve = mxf_metadata_material_package_resolve;
  metadata_base_class->name_quark = MXF_QUARK (MATERIAL_PACKAGE);
  metadata_class->type = 0x0136;
}

G_DEFINE_TYPE (MXFMetadataSourcePackage, mxf_metadata_source_package,
    MXF_TYPE_METADATA_GENERIC_PACKAGE);

static gboolean
mxf_metadata_source_package_handle_tag (MXFMetadataBase * metadata,
    MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataSourcePackage *self = MXF_METADATA_SOURCE_PACKAGE (metadata);
  gboolean ret = TRUE;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  switch (tag) {
    case 0x4701:
      if (tag_size != 16)
        goto error;

      memcpy (&self->descriptor_uid, tag_data, 16);
      GST_DEBUG ("  descriptor = %s",
          mxf_uuid_to_string (&self->descriptor_uid, str));
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_source_package_parent_class)->handle_tag (metadata,
          primer, tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR ("Invalid source package local tag 0x%04x of size %u", tag,
      tag_size);

  return FALSE;
}

static gboolean
mxf_metadata_source_package_resolve (MXFMetadataBase * m, GHashTable * metadata)
{
  MXFMetadataSourcePackage *self = MXF_METADATA_SOURCE_PACKAGE (m);
  MXFMetadataGenericPackage *package = MXF_METADATA_GENERIC_PACKAGE (m);
  MXFMetadataBase *current = NULL;
  guint i;
  gboolean ret;
  MXFMetadataFileDescriptor *d;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  if (mxf_uuid_is_zero (&self->descriptor_uid))
    return
        MXF_METADATA_BASE_CLASS
        (mxf_metadata_source_package_parent_class)->resolve (m, metadata);

  current = g_hash_table_lookup (metadata, &self->descriptor_uid);
  if (!current) {
    GST_ERROR ("Descriptor %s not found",
        mxf_uuid_to_string (&self->descriptor_uid, str));
    return FALSE;
  }

  if (!mxf_metadata_base_resolve (MXF_METADATA_BASE (current), metadata)) {
    GST_ERROR ("Couldn't resolve descriptor %s",
        mxf_uuid_to_string (&self->descriptor_uid, str));
    return FALSE;
  }

  self->descriptor = MXF_METADATA_GENERIC_DESCRIPTOR (current);

  ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_source_package_parent_class)->resolve (m, metadata);

  if (!MXF_IS_METADATA_FILE_DESCRIPTOR (self->descriptor))
    return ret;

  d = MXF_METADATA_FILE_DESCRIPTOR (current);

  for (i = 0; i < package->n_tracks; i++) {
    if (!MXF_IS_METADATA_MULTIPLE_DESCRIPTOR (d)) {
      if (d->linked_track_id == package->tracks[i]->track_id ||
          (d->linked_track_id == 0 && package->n_essence_tracks == 1 &&
              (package->tracks[i]->type & 0xf0) == 0x30)) {
        g_free (package->tracks[i]->descriptor);
        package->tracks[i]->descriptor =
            g_new0 (MXFMetadataFileDescriptor *, 1);
        package->tracks[i]->descriptor[0] = d;
        package->tracks[i]->n_descriptor = 1;
        break;
      }
    } else {
      guint n_descriptor = 0, j, k = 0;
      MXFMetadataMultipleDescriptor *md = MXF_METADATA_MULTIPLE_DESCRIPTOR (d);

      for (j = 0; j < md->n_sub_descriptors; j++) {
        MXFMetadataFileDescriptor *fd;

        if (!md->sub_descriptors[j] ||
            !MXF_METADATA_FILE_DESCRIPTOR (md->sub_descriptors[j]))
          continue;

        fd = MXF_METADATA_FILE_DESCRIPTOR (md->sub_descriptors[j]);

        if (fd->linked_track_id == package->tracks[i]->track_id ||
            (fd->linked_track_id == 0 && package->n_essence_tracks == 1 &&
                (package->tracks[i]->type & 0xf0) == 0x30))
          n_descriptor++;
      }

      g_free (package->tracks[i]->descriptor);
      package->tracks[i]->descriptor =
          g_new0 (MXFMetadataFileDescriptor *, n_descriptor);
      package->tracks[i]->n_descriptor = n_descriptor;

      for (j = 0; j < md->n_sub_descriptors; j++) {
        MXFMetadataFileDescriptor *fd;

        if (!md->sub_descriptors[j] ||
            !MXF_METADATA_FILE_DESCRIPTOR (md->sub_descriptors[j]))
          continue;

        fd = MXF_METADATA_FILE_DESCRIPTOR (md->sub_descriptors[j]);

        if (fd->linked_track_id == package->tracks[i]->track_id ||
            (fd->linked_track_id == 0 && package->n_essence_tracks == 1 &&
                (package->tracks[i]->type & 0xf0) == 0x30)) {
          package->tracks[i]->descriptor[k] = fd;
          k++;
        }
      }
    }
  }

  return ret;
}

static GstStructure *
mxf_metadata_source_package_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_source_package_parent_class)->to_structure (m);
  MXFMetadataSourcePackage *self = MXF_METADATA_SOURCE_PACKAGE (m);
  GstStructure *s;

  if (!self->descriptor)
    return ret;

  s = mxf_metadata_base_to_structure (MXF_METADATA_BASE (self->descriptor));
  gst_structure_id_set (ret, MXF_QUARK (DESCRIPTOR), GST_TYPE_STRUCTURE, s,
      NULL);
  gst_structure_free (s);

  return ret;
}

static GList *
mxf_metadata_source_package_write_tags (MXFMetadataBase * m,
    MXFPrimerPack * primer)
{
  MXFMetadataSourcePackage *self = MXF_METADATA_SOURCE_PACKAGE (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_source_package_parent_class)->write_tags (m, primer);
  MXFLocalTag *t;

  if (self->descriptor) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (DESCRIPTOR), 16);
    t->size = 16;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    memcpy (t->data, &MXF_METADATA_BASE (self->descriptor)->instance_uid, 16);
    mxf_primer_pack_add_mapping (primer, 0x4701, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  return ret;
}

static void
mxf_metadata_source_package_init (MXFMetadataSourcePackage * self)
{

}

static void
mxf_metadata_source_package_class_init (MXFMetadataSourcePackageClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  metadata_base_class->handle_tag = mxf_metadata_source_package_handle_tag;
  metadata_base_class->resolve = mxf_metadata_source_package_resolve;
  metadata_base_class->name_quark = MXF_QUARK (SOURCE_PACKAGE);
  metadata_base_class->to_structure = mxf_metadata_source_package_to_structure;
  metadata_base_class->write_tags = mxf_metadata_source_package_write_tags;
  metadata_class->type = 0x0137;
}

G_DEFINE_ABSTRACT_TYPE (MXFMetadataTrack, mxf_metadata_track,
    MXF_TYPE_METADATA);

static void
mxf_metadata_track_finalize (GObject * object)
{
  MXFMetadataTrack *self = MXF_METADATA_TRACK (object);

  g_free (self->track_name);
  self->track_name = NULL;
  g_free (self->descriptor);
  self->descriptor = NULL;

  G_OBJECT_CLASS (mxf_metadata_track_parent_class)->finalize (object);
}

static gboolean
mxf_metadata_track_handle_tag (MXFMetadataBase * metadata,
    MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataTrack *self = MXF_METADATA_TRACK (metadata);
  gboolean ret = TRUE;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  switch (tag) {
    case 0x4801:
      if (tag_size != 4)
        goto error;
      self->track_id = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  track id = %u", self->track_id);
      break;
    case 0x4804:
      if (tag_size != 4)
        goto error;
      self->track_number = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  track number = %u", self->track_number);
      break;
    case 0x4802:
      self->track_name = mxf_utf16_to_utf8 (tag_data, tag_size);
      GST_DEBUG ("  track name = %s", GST_STR_NULL (self->track_name));
      break;
    case 0x4803:
      if (tag_size != 16)
        goto error;
      memcpy (&self->sequence_uid, tag_data, 16);
      GST_DEBUG ("  sequence uid = %s",
          mxf_uuid_to_string (&self->sequence_uid, str));
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS (mxf_metadata_track_parent_class)->handle_tag
          (metadata, primer, tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR ("Invalid track local tag 0x%04x of size %u", tag, tag_size);

  return FALSE;
}

static gboolean
mxf_metadata_track_resolve (MXFMetadataBase * m, GHashTable * metadata)
{
  MXFMetadataTrack *self = MXF_METADATA_TRACK (m);
  MXFMetadataBase *current = NULL;
  guint i;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  current = g_hash_table_lookup (metadata, &self->sequence_uid);
  if (current && MXF_IS_METADATA_SEQUENCE (current)) {
    if (mxf_metadata_base_resolve (current, metadata)) {
      self->sequence = MXF_METADATA_SEQUENCE (current);
    } else {
      GST_ERROR ("Couldn't resolve sequence %s",
          mxf_uuid_to_string (&self->sequence_uid, str));
      return FALSE;
    }
  } else {
    GST_ERROR ("Couldn't find sequence %s",
        mxf_uuid_to_string (&self->sequence_uid, str));
    return FALSE;
  }

  self->type =
      mxf_metadata_track_identifier_parse (&self->sequence->data_definition);
  if (self->type == MXF_METADATA_TRACK_UNKNOWN) {
    MXFMetadataSequence *sequence = self->sequence;

    for (i = 0; i < sequence->n_structural_components; i++) {
      MXFMetadataStructuralComponent *component =
          sequence->structural_components[i];

      if (!component)
        continue;

      self->type =
          mxf_metadata_track_identifier_parse (&component->data_definition);
      if (self->type != MXF_METADATA_TRACK_UNKNOWN)
        break;
    }
  }

  return MXF_METADATA_BASE_CLASS (mxf_metadata_track_parent_class)->resolve (m,
      metadata);
}

static GstStructure *
mxf_metadata_track_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS (mxf_metadata_track_parent_class)->to_structure
      (m);
  MXFMetadataTrack *self = MXF_METADATA_TRACK (m);

  gst_structure_id_set (ret, MXF_QUARK (TRACK_ID), G_TYPE_UINT, self->track_id,
      MXF_QUARK (TRACK_NUMBER), G_TYPE_UINT, self->track_number, NULL);

  if (self->track_name)
    gst_structure_id_set (ret, MXF_QUARK (TRACK_NAME), G_TYPE_STRING,
        self->track_name, NULL);

  if (self->sequence) {
    GstStructure *s =
        mxf_metadata_base_to_structure (MXF_METADATA_BASE (self->sequence));

    gst_structure_id_set (ret, MXF_QUARK (SEQUENCE), GST_TYPE_STRUCTURE, s,
        NULL);
    gst_structure_free (s);
  }


  return ret;
}

static GList *
mxf_metadata_track_write_tags (MXFMetadataBase * m, MXFPrimerPack * primer)
{
  MXFMetadataTrack *self = MXF_METADATA_TRACK (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS (mxf_metadata_track_parent_class)->write_tags (m,
      primer);
  MXFLocalTag *t;

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (TRACK_ID), 16);
  t->size = 4;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT32_BE (t->data, self->track_id);
  mxf_primer_pack_add_mapping (primer, 0x4801, &t->ul);
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (TRACK_NUMBER), 16);
  t->size = 4;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT32_BE (t->data, self->track_number);
  mxf_primer_pack_add_mapping (primer, 0x4804, &t->ul);
  ret = g_list_prepend (ret, t);

  if (self->track_name) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (TRACK_NAME), 16);
    t->data = mxf_utf8_to_utf16 (self->track_name, &t->size);
    mxf_primer_pack_add_mapping (primer, 0x4802, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (SEQUENCE), 16);
  t->size = 16;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  memcpy (t->data, &MXF_METADATA_BASE (self->sequence)->instance_uid, 16);
  mxf_primer_pack_add_mapping (primer, 0x4803, &t->ul);
  ret = g_list_prepend (ret, t);

  return ret;
}

static void
mxf_metadata_track_init (MXFMetadataTrack * self)
{

}

static void
mxf_metadata_track_class_init (MXFMetadataTrackClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  GObjectClass *object_class = (GObjectClass *) klass;

  object_class->finalize = mxf_metadata_track_finalize;
  metadata_base_class->handle_tag = mxf_metadata_track_handle_tag;
  metadata_base_class->resolve = mxf_metadata_track_resolve;
  metadata_base_class->to_structure = mxf_metadata_track_to_structure;
  metadata_base_class->write_tags = mxf_metadata_track_write_tags;
}

/* SMPTE RP224 */
static const struct
{
  const MXFUL *ul;
  const MXFMetadataTrackType type;
} mxf_metadata_track_identifier[] = {
  {
  MXF_UL (TRACK_TIMECODE_12M_INACTIVE),
        MXF_METADATA_TRACK_TIMECODE_12M_INACTIVE}, {
  MXF_UL (TRACK_TIMECODE_12M_ACTIVE), MXF_METADATA_TRACK_TIMECODE_12M_ACTIVE}, {
  MXF_UL (TRACK_TIMECODE_309M), MXF_METADATA_TRACK_TIMECODE_309M}, {
  MXF_UL (TRACK_METADATA), MXF_METADATA_TRACK_METADATA}, {
  MXF_UL (TRACK_PICTURE_ESSENCE), MXF_METADATA_TRACK_PICTURE_ESSENCE}, {
  MXF_UL (TRACK_SOUND_ESSENCE), MXF_METADATA_TRACK_SOUND_ESSENCE}, {
  MXF_UL (TRACK_DATA_ESSENCE), MXF_METADATA_TRACK_DATA_ESSENCE}, {
  MXF_UL (TRACK_AUXILIARY_DATA), MXF_METADATA_TRACK_AUXILIARY_DATA}, {
  MXF_UL (TRACK_PARSED_TEXT), MXF_METADATA_TRACK_PARSED_TEXT},
      /* Avid video? */
  {
  MXF_UL (TRACK_AVID_PICTURE_ESSENCE), MXF_METADATA_TRACK_PICTURE_ESSENCE}
};

MXFMetadataTrackType
mxf_metadata_track_identifier_parse (const MXFUL * track_identifier)
{
  guint i;

  for (i = 0; i < G_N_ELEMENTS (mxf_metadata_track_identifier); i++)
    if (mxf_ul_is_equal (mxf_metadata_track_identifier[i].ul, track_identifier))
      return mxf_metadata_track_identifier[i].type;

  return MXF_METADATA_TRACK_UNKNOWN;
}

const MXFUL *
mxf_metadata_track_identifier_get (MXFMetadataTrackType type)
{
  guint i;

  for (i = 0; i < G_N_ELEMENTS (mxf_metadata_track_identifier); i++)
    if (mxf_metadata_track_identifier[i].type == type)
      return mxf_metadata_track_identifier[i].ul;

  return NULL;
}

G_DEFINE_TYPE (MXFMetadataTimelineTrack, mxf_metadata_timeline_track,
    MXF_TYPE_METADATA_TRACK);

static gboolean
mxf_metadata_timeline_track_handle_tag (MXFMetadataBase * metadata,
    MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataTimelineTrack *self = MXF_METADATA_TIMELINE_TRACK (metadata);
  gboolean ret = TRUE;

  switch (tag) {
    case 0x4b01:
      if (!mxf_fraction_parse (&self->edit_rate, tag_data, tag_size))
        goto error;
      GST_DEBUG ("  edit rate = %d/%d", self->edit_rate.n, self->edit_rate.d);
      break;
    case 0x4b02:
      if (tag_size != 8)
        goto error;
      self->origin = GST_READ_UINT64_BE (tag_data);
      GST_DEBUG ("  origin = %" G_GINT64_FORMAT, self->origin);
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_timeline_track_parent_class)->handle_tag (metadata,
          primer, tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR ("Invalid timeline track local tag 0x%04x of size %u", tag,
      tag_size);

  return FALSE;
}

static GstStructure *
mxf_metadata_timeline_track_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_timeline_track_parent_class)->to_structure (m);
  MXFMetadataTimelineTrack *self = MXF_METADATA_TIMELINE_TRACK (m);

  gst_structure_id_set (ret, MXF_QUARK (EDIT_RATE), GST_TYPE_FRACTION,
      self->edit_rate.n, self->edit_rate.d, MXF_QUARK (ORIGIN), G_TYPE_INT64,
      self->origin, NULL);

  return ret;
}

static GList *
mxf_metadata_timeline_track_write_tags (MXFMetadataBase * m,
    MXFPrimerPack * primer)
{
  MXFMetadataTimelineTrack *self = MXF_METADATA_TIMELINE_TRACK (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_timeline_track_parent_class)->write_tags (m, primer);
  MXFLocalTag *t;

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (EDIT_RATE), 16);
  t->size = 8;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT32_BE (t->data, self->edit_rate.n);
  GST_WRITE_UINT32_BE (t->data + 4, self->edit_rate.d);
  mxf_primer_pack_add_mapping (primer, 0x4b01, &t->ul);
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (ORIGIN), 16);
  t->size = 8;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT64_BE (t->data, self->origin);
  mxf_primer_pack_add_mapping (primer, 0x4b02, &t->ul);
  ret = g_list_prepend (ret, t);

  return ret;
}

static void
mxf_metadata_timeline_track_init (MXFMetadataTimelineTrack * self)
{

}

static void
mxf_metadata_timeline_track_class_init (MXFMetadataTimelineTrackClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  metadata_base_class->handle_tag = mxf_metadata_timeline_track_handle_tag;
  metadata_base_class->name_quark = MXF_QUARK (TIMELINE_TRACK);
  metadata_base_class->to_structure = mxf_metadata_timeline_track_to_structure;
  metadata_base_class->write_tags = mxf_metadata_timeline_track_write_tags;
  metadata_class->type = 0x013b;
}

G_DEFINE_TYPE (MXFMetadataEventTrack, mxf_metadata_event_track,
    MXF_TYPE_METADATA_TRACK);

static gboolean
mxf_metadata_event_track_handle_tag (MXFMetadataBase * metadata,
    MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataEventTrack *self = MXF_METADATA_EVENT_TRACK (metadata);
  gboolean ret = TRUE;

  switch (tag) {
    case 0x4901:
      if (!mxf_fraction_parse (&self->event_edit_rate, tag_data, tag_size))
        goto error;
      GST_DEBUG ("  event edit rate = %d/%d", self->event_edit_rate.n,
          self->event_edit_rate.d);
      break;
    case 0x4902:
      if (tag_size != 8)
        goto error;
      self->event_origin = GST_READ_UINT64_BE (tag_data);
      GST_DEBUG ("  event origin = %" G_GINT64_FORMAT, self->event_origin);
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_event_track_parent_class)->handle_tag (metadata, primer,
          tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR ("Invalid event track local tag 0x%04x of size %u", tag, tag_size);

  return FALSE;
}

static GstStructure *
mxf_metadata_event_track_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_event_track_parent_class)->to_structure (m);
  MXFMetadataEventTrack *self = MXF_METADATA_EVENT_TRACK (m);

  gst_structure_id_set (ret, MXF_QUARK (EVENT_EDIT_RATE), GST_TYPE_FRACTION,
      self->event_edit_rate.n, self->event_edit_rate.d,
      MXF_QUARK (EVENT_ORIGIN), G_TYPE_INT64, self->event_origin, NULL);

  return ret;
}

static GList *
mxf_metadata_event_track_write_tags (MXFMetadataBase * m,
    MXFPrimerPack * primer)
{
  MXFMetadataEventTrack *self = MXF_METADATA_EVENT_TRACK (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_event_track_parent_class)->write_tags (m, primer);
  MXFLocalTag *t;

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (EVENT_EDIT_RATE), 16);
  t->size = 8;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT32_BE (t->data, self->event_edit_rate.n);
  GST_WRITE_UINT32_BE (t->data + 4, self->event_edit_rate.d);
  mxf_primer_pack_add_mapping (primer, 0x4901, &t->ul);
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (EVENT_ORIGIN), 16);
  t->size = 8;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT64_BE (t->data, self->event_origin);
  mxf_primer_pack_add_mapping (primer, 0x4902, &t->ul);
  ret = g_list_prepend (ret, t);

  return ret;
}

static void
mxf_metadata_event_track_init (MXFMetadataEventTrack * self)
{

}

static void
mxf_metadata_event_track_class_init (MXFMetadataEventTrackClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  metadata_base_class->handle_tag = mxf_metadata_event_track_handle_tag;
  metadata_base_class->name_quark = MXF_QUARK (EVENT_TRACK);
  metadata_base_class->to_structure = mxf_metadata_event_track_to_structure;
  metadata_base_class->write_tags = mxf_metadata_event_track_write_tags;
  metadata_class->type = 0x0139;
}

G_DEFINE_TYPE (MXFMetadataStaticTrack, mxf_metadata_static_track,
    MXF_TYPE_METADATA_TRACK);

static void
mxf_metadata_static_track_init (MXFMetadataStaticTrack * self)
{
}

static void
mxf_metadata_static_track_class_init (MXFMetadataStaticTrackClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  metadata_base_class->name_quark = MXF_QUARK (STATIC_TRACK);
  metadata_class->type = 0x013a;
}

G_DEFINE_TYPE (MXFMetadataSequence, mxf_metadata_sequence, MXF_TYPE_METADATA);

static void
mxf_metadata_sequence_finalize (GObject * object)
{
  MXFMetadataSequence *self = MXF_METADATA_SEQUENCE (object);

  g_free (self->structural_components_uids);
  self->structural_components_uids = NULL;
  g_free (self->structural_components);
  self->structural_components = NULL;

  G_OBJECT_CLASS (mxf_metadata_sequence_parent_class)->finalize (object);
}

static gboolean
mxf_metadata_sequence_handle_tag (MXFMetadataBase * metadata,
    MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataSequence *self = MXF_METADATA_SEQUENCE (metadata);
  gboolean ret = TRUE;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  switch (tag) {
    case 0x0201:
      if (tag_size != 16)
        goto error;
      memcpy (&self->data_definition, tag_data, 16);
      GST_DEBUG ("  data definition = %s",
          mxf_ul_to_string (&self->data_definition, str));
      break;
    case 0x0202:
      if (tag_size != 8)
        goto error;
      self->duration = GST_READ_UINT64_BE (tag_data);
      GST_DEBUG ("  duration = %" G_GINT64_FORMAT, self->duration);
      break;
    case 0x1001:
      if (!mxf_uuid_array_parse (&self->structural_components_uids,
              &self->n_structural_components, tag_data, tag_size))
        goto error;

      GST_DEBUG ("  number of structural components = %u",
          self->n_structural_components);
#ifndef GST_DISABLE_GST_DEBUG
      {
        guint i;
        for (i = 0; i < self->n_structural_components; i++) {
          GST_DEBUG ("  structural component %u = %s", i,
              mxf_uuid_to_string (&self->structural_components_uids[i], str));
        }
      }
#endif
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_sequence_parent_class)->handle_tag (metadata, primer,
          tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR ("Invalid sequence local tag 0x%04x of size %u", tag, tag_size);

  return FALSE;
}

static gboolean
mxf_metadata_sequence_resolve (MXFMetadataBase * m, GHashTable * metadata)
{
  MXFMetadataSequence *self = MXF_METADATA_SEQUENCE (m);
  MXFMetadataBase *current = NULL;
  guint i;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  if (self->structural_components)
    memset (self->structural_components, 0,
        sizeof (gpointer) * self->n_structural_components);
  else
    self->structural_components =
        g_new0 (MXFMetadataStructuralComponent *,
        self->n_structural_components);
  for (i = 0; i < self->n_structural_components; i++) {
    current =
        g_hash_table_lookup (metadata, &self->structural_components_uids[i]);
    if (current && MXF_IS_METADATA_STRUCTURAL_COMPONENT (current)) {
      if (mxf_metadata_base_resolve (current, metadata)) {
        self->structural_components[i] =
            MXF_METADATA_STRUCTURAL_COMPONENT (current);
      } else {
        GST_ERROR ("Couldn't resolve structural component %s",
            mxf_uuid_to_string (&self->structural_components_uids[i], str));
        return FALSE;
      }
    } else {
      GST_ERROR ("Structural component %s not found",
          mxf_uuid_to_string (&self->structural_components_uids[i], str));
      return FALSE;
    }
  }

  return
      MXF_METADATA_BASE_CLASS (mxf_metadata_sequence_parent_class)->resolve (m,
      metadata);

}

static GstStructure *
mxf_metadata_sequence_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS (mxf_metadata_sequence_parent_class)->to_structure
      (m);
  MXFMetadataSequence *self = MXF_METADATA_SEQUENCE (m);
  guint i;
  gchar str[48];

  mxf_ul_to_string (&self->data_definition, str);
  gst_structure_id_set (ret, MXF_QUARK (DATA_DEFINITION), G_TYPE_STRING, str,
      MXF_QUARK (DURATION), G_TYPE_INT64, self->duration, NULL);

  if (self->n_structural_components > 0) {
    GValue arr = { 0, }
    , val = {
    0,};

    g_value_init (&arr, GST_TYPE_ARRAY);

    for (i = 0; i < self->n_structural_components; i++) {
      GstStructure *s;

      if (self->structural_components[i] == NULL)
        continue;

      g_value_init (&val, GST_TYPE_STRUCTURE);

      s = mxf_metadata_base_to_structure (MXF_METADATA_BASE
          (self->structural_components[i]));
      gst_value_set_structure (&val, s);
      gst_structure_free (s);
      gst_value_array_append_value (&arr, &val);
      g_value_unset (&val);
    }

    if (gst_value_array_get_size (&arr) > 0)
      gst_structure_id_set_value (ret, MXF_QUARK (STRUCTURAL_COMPONENTS), &arr);

    g_value_unset (&arr);
  }

  return ret;
}

static GList *
mxf_metadata_sequence_write_tags (MXFMetadataBase * m, MXFPrimerPack * primer)
{
  MXFMetadataSequence *self = MXF_METADATA_SEQUENCE (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS (mxf_metadata_sequence_parent_class)->write_tags
      (m, primer);
  MXFLocalTag *t;

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (DATA_DEFINITION), 16);
  t->size = 16;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  memcpy (t->data, &self->data_definition, 16);
  mxf_primer_pack_add_mapping (primer, 0x0201, &t->ul);
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (DURATION), 16);
  t->size = 8;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT64_BE (t->data, self->duration);
  mxf_primer_pack_add_mapping (primer, 0x0202, &t->ul);
  ret = g_list_prepend (ret, t);

  if (self->structural_components) {
    guint i;
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (STRUCTURAL_COMPONENTS), 16);
    t->size = 8 + 16 * self->n_structural_components;
    t->data = g_slice_alloc0 (t->size);
    t->g_slice = TRUE;

    GST_WRITE_UINT32_BE (t->data, self->n_structural_components);
    GST_WRITE_UINT32_BE (t->data + 4, 16);
    for (i = 0; i < self->n_structural_components; i++) {
      if (!self->structural_components[i])
        continue;

      memcpy (t->data + 8 + i * 16,
          &MXF_METADATA_BASE (self->structural_components[i])->instance_uid,
          16);
    }

    mxf_primer_pack_add_mapping (primer, 0x1001, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  return ret;
}

static void
mxf_metadata_sequence_init (MXFMetadataSequence * self)
{
  self->duration = -1;
}

static void
mxf_metadata_sequence_class_init (MXFMetadataSequenceClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  GObjectClass *object_class = (GObjectClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  object_class->finalize = mxf_metadata_sequence_finalize;
  metadata_base_class->handle_tag = mxf_metadata_sequence_handle_tag;
  metadata_base_class->resolve = mxf_metadata_sequence_resolve;
  metadata_base_class->name_quark = MXF_QUARK (SEQUENCE);
  metadata_base_class->to_structure = mxf_metadata_sequence_to_structure;
  metadata_base_class->write_tags = mxf_metadata_sequence_write_tags;
  metadata_class->type = 0x010f;
}

G_DEFINE_TYPE (MXFMetadataStructuralComponent,
    mxf_metadata_structural_component, MXF_TYPE_METADATA);

static gboolean
mxf_metadata_structural_component_handle_tag (MXFMetadataBase * metadata,
    MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataStructuralComponent *self =
      MXF_METADATA_STRUCTURAL_COMPONENT (metadata);
  gboolean ret = TRUE;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  switch (tag) {
    case 0x0201:
      if (tag_size != 16)
        goto error;
      memcpy (&self->data_definition, tag_data, 16);
      GST_DEBUG ("  data definition = %s",
          mxf_ul_to_string (&self->data_definition, str));
      break;
    case 0x0202:
      if (tag_size != 8)
        goto error;
      self->duration = GST_READ_UINT64_BE (tag_data);
      GST_DEBUG ("  duration = %" G_GINT64_FORMAT, self->duration);
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_structural_component_parent_class)->handle_tag
          (metadata, primer, tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR ("Invalid structural component local tag 0x%04x of size %u", tag,
      tag_size);

  return FALSE;
}

static GstStructure *
mxf_metadata_structural_component_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_structural_component_parent_class)->to_structure (m);
  MXFMetadataStructuralComponent *self = MXF_METADATA_STRUCTURAL_COMPONENT (m);
  gchar str[48];

  mxf_ul_to_string (&self->data_definition, str);
  gst_structure_id_set (ret, MXF_QUARK (DATA_DEFINITION), G_TYPE_STRING, str,
      MXF_QUARK (DURATION), G_TYPE_INT64, self->duration, NULL);

  return ret;
}

static GList *
mxf_metadata_structural_component_write_tags (MXFMetadataBase * m,
    MXFPrimerPack * primer)
{
  MXFMetadataStructuralComponent *self = MXF_METADATA_STRUCTURAL_COMPONENT (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_structural_component_parent_class)->write_tags (m, primer);
  MXFLocalTag *t;

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (DATA_DEFINITION), 16);
  t->size = 16;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  memcpy (t->data, &self->data_definition, 16);
  mxf_primer_pack_add_mapping (primer, 0x0201, &t->ul);
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (DURATION), 16);
  t->size = 8;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT64_BE (t->data, self->duration);
  mxf_primer_pack_add_mapping (primer, 0x0202, &t->ul);
  ret = g_list_prepend (ret, t);

  return ret;
}

static void
mxf_metadata_structural_component_init (MXFMetadataStructuralComponent * self)
{
  self->duration = -1;
}

static void
    mxf_metadata_structural_component_class_init
    (MXFMetadataStructuralComponentClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;

  metadata_base_class->handle_tag =
      mxf_metadata_structural_component_handle_tag;
  metadata_base_class->to_structure =
      mxf_metadata_structural_component_to_structure;
  metadata_base_class->write_tags =
      mxf_metadata_structural_component_write_tags;
}

G_DEFINE_TYPE (MXFMetadataTimecodeComponent, mxf_metadata_timecode_component,
    MXF_TYPE_METADATA_STRUCTURAL_COMPONENT);

static gboolean
mxf_metadata_timecode_component_handle_tag (MXFMetadataBase * metadata,
    MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataTimecodeComponent *self =
      MXF_METADATA_TIMECODE_COMPONENT (metadata);
  gboolean ret = TRUE;

  switch (tag) {
    case 0x1502:
      if (tag_size != 2)
        goto error;
      self->rounded_timecode_base = GST_READ_UINT16_BE (tag_data);
      GST_DEBUG ("  rounded timecode base = %u", self->rounded_timecode_base);
      break;
    case 0x1501:
      if (tag_size != 8)
        goto error;
      self->start_timecode = GST_READ_UINT64_BE (tag_data);
      GST_DEBUG ("  start timecode = %" G_GINT64_FORMAT, self->start_timecode);
      break;
    case 0x1503:
      if (tag_size != 1)
        goto error;
      self->drop_frame = (GST_READ_UINT8 (tag_data) != 0);
      GST_DEBUG ("  drop frame = %s", (self->drop_frame) ? "yes" : "no");
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_timecode_component_parent_class)->handle_tag (metadata,
          primer, tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR ("Invalid timecode component local tag 0x%04x of size %u", tag,
      tag_size);

  return FALSE;
}

static GstStructure *
mxf_metadata_timecode_component_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_timecode_component_parent_class)->to_structure (m);
  MXFMetadataTimecodeComponent *self = MXF_METADATA_TIMECODE_COMPONENT (m);

  gst_structure_id_set (ret, MXF_QUARK (START_TIMECODE), G_TYPE_INT64,
      self->start_timecode, MXF_QUARK (ROUNDED_TIMECODE_BASE), G_TYPE_UINT,
      self->rounded_timecode_base, MXF_QUARK (DROP_FRAME), G_TYPE_BOOLEAN,
      self->drop_frame, NULL);

  return ret;
}

static GList *
mxf_metadata_timecode_component_write_tags (MXFMetadataBase * m,
    MXFPrimerPack * primer)
{
  MXFMetadataTimecodeComponent *self = MXF_METADATA_TIMECODE_COMPONENT (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_timecode_component_parent_class)->write_tags (m, primer);
  MXFLocalTag *t;

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (ROUNDED_TIMECODE_BASE), 16);
  t->size = 2;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT16_BE (t->data, self->rounded_timecode_base);
  mxf_primer_pack_add_mapping (primer, 0x1502, &t->ul);
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (START_TIMECODE), 16);
  t->size = 8;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT64_BE (t->data, self->start_timecode);
  mxf_primer_pack_add_mapping (primer, 0x1501, &t->ul);
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (DROP_FRAME), 16);
  t->size = 1;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT8 (t->data, (self->drop_frame) ? 1 : 0);
  mxf_primer_pack_add_mapping (primer, 0x1503, &t->ul);
  ret = g_list_prepend (ret, t);

  return ret;
}

static void
mxf_metadata_timecode_component_init (MXFMetadataTimecodeComponent * self)
{

}

static void
mxf_metadata_timecode_component_class_init (MXFMetadataTimecodeComponentClass *
    klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  metadata_base_class->handle_tag = mxf_metadata_timecode_component_handle_tag;
  metadata_base_class->name_quark = MXF_QUARK (TIMECODE_COMPONENT);
  metadata_base_class->to_structure =
      mxf_metadata_timecode_component_to_structure;
  metadata_base_class->write_tags = mxf_metadata_timecode_component_write_tags;
  metadata_class->type = 0x0114;
}

G_DEFINE_TYPE (MXFMetadataSourceClip, mxf_metadata_source_clip,
    MXF_TYPE_METADATA_STRUCTURAL_COMPONENT);

static gboolean
mxf_metadata_source_clip_handle_tag (MXFMetadataBase * metadata,
    MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataSourceClip *self = MXF_METADATA_SOURCE_CLIP (metadata);
  gboolean ret = TRUE;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[96];
#endif

  switch (tag) {
    case 0x1201:
      if (tag_size != 8)
        goto error;

      self->start_position = GST_READ_UINT64_BE (tag_data);
      GST_DEBUG ("  start position = %" G_GINT64_FORMAT, self->start_position);
      break;
    case 0x1101:
      if (tag_size != 32)
        goto error;

      memcpy (&self->source_package_id, tag_data, 32);
      GST_DEBUG ("  source package id = %s",
          mxf_umid_to_string (&self->source_package_id, str));
      break;
    case 0x1102:
      if (tag_size != 4)
        goto error;

      self->source_track_id = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  source track id = %u", self->source_track_id);
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_source_clip_parent_class)->handle_tag (metadata, primer,
          tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR ("Invalid source clip local tag 0x%04x of size %u", tag, tag_size);

  return FALSE;
}

static gboolean
mxf_metadata_source_clip_resolve (MXFMetadataBase * m, GHashTable * metadata)
{
  MXFMetadataSourceClip *self = MXF_METADATA_SOURCE_CLIP (m);
  MXFMetadataBase *current = NULL;
  GHashTableIter iter;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[96];
#endif

  g_hash_table_iter_init (&iter, metadata);

  while (g_hash_table_iter_next (&iter, NULL, (gpointer) & current)) {
    if (MXF_IS_METADATA_SOURCE_PACKAGE (current)) {
      MXFMetadataGenericPackage *p = MXF_METADATA_GENERIC_PACKAGE (current);

      if (mxf_umid_is_equal (&p->package_uid, &self->source_package_id)) {
        self->source_package = MXF_METADATA_SOURCE_PACKAGE (current);
        break;
      }
    }
  }

  if (!self->source_package) {
    GST_ERROR ("Couldn't find source package %s",
        mxf_umid_to_string (&self->source_package_id, str));
  }

  return
      MXF_METADATA_BASE_CLASS (mxf_metadata_source_clip_parent_class)->resolve
      (m, metadata);
}

static GstStructure *
mxf_metadata_source_clip_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_source_clip_parent_class)->to_structure (m);
  MXFMetadataSourceClip *self = MXF_METADATA_SOURCE_CLIP (m);
  gchar str[96];

  mxf_umid_to_string (&self->source_package_id, str);
  gst_structure_id_set (ret, MXF_QUARK (START_POSITION), G_TYPE_INT64,
      self->start_position, MXF_QUARK (SOURCE_PACKAGE), G_TYPE_STRING, str,
      MXF_QUARK (SOURCE_TRACK_ID), G_TYPE_UINT, self->source_track_id, NULL);

  return ret;
}

static GList *
mxf_metadata_source_clip_write_tags (MXFMetadataBase * m,
    MXFPrimerPack * primer)
{
  MXFMetadataSourceClip *self = MXF_METADATA_SOURCE_CLIP (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_source_clip_parent_class)->write_tags (m, primer);
  MXFLocalTag *t;

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (START_POSITION), 16);
  t->size = 8;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT64_BE (t->data, self->start_position);
  mxf_primer_pack_add_mapping (primer, 0x1201, &t->ul);
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (SOURCE_PACKAGE_ID), 16);
  t->size = 32;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  memcpy (t->data, &self->source_package_id, 32);
  mxf_primer_pack_add_mapping (primer, 0x1101, &t->ul);
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (SOURCE_TRACK_ID), 16);
  t->size = 4;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT32_BE (t->data, self->source_track_id);
  mxf_primer_pack_add_mapping (primer, 0x1102, &t->ul);
  ret = g_list_prepend (ret, t);

  return ret;
}

static void
mxf_metadata_source_clip_init (MXFMetadataSourceClip * self)
{

}

static void
mxf_metadata_source_clip_class_init (MXFMetadataSourceClipClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  metadata_base_class->handle_tag = mxf_metadata_source_clip_handle_tag;
  metadata_base_class->resolve = mxf_metadata_source_clip_resolve;
  metadata_base_class->name_quark = MXF_QUARK (SOURCE_CLIP);
  metadata_base_class->to_structure = mxf_metadata_source_clip_to_structure;
  metadata_base_class->write_tags = mxf_metadata_source_clip_write_tags;
  metadata_class->type = 0x0111;
}


G_DEFINE_TYPE (MXFMetadataFiller, mxf_metadata_filler,
    MXF_TYPE_METADATA_STRUCTURAL_COMPONENT);

static void
mxf_metadata_filler_init (MXFMetadataFiller * self)
{

}

static void
mxf_metadata_filler_class_init (MXFMetadataFillerClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  metadata_base_class->name_quark = MXF_QUARK (FILLER);
  metadata_class->type = 0x0109;
}

G_DEFINE_TYPE (MXFMetadataDMSourceClip, mxf_metadata_dm_source_clip,
    MXF_TYPE_METADATA_SOURCE_CLIP);

static void
mxf_metadata_dm_source_clip_finalize (GObject * object)
{
  MXFMetadataDMSourceClip *self = MXF_METADATA_DM_SOURCE_CLIP (object);

  g_free (self->track_ids);
  self->track_ids = NULL;

  G_OBJECT_CLASS (mxf_metadata_dm_source_clip_parent_class)->finalize (object);
}

static gboolean
mxf_metadata_dm_source_clip_handle_tag (MXFMetadataBase * metadata,
    MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataDMSourceClip *self = MXF_METADATA_DM_SOURCE_CLIP (metadata);
  gboolean ret = TRUE;

  switch (tag) {
    case 0x6103:
    {
      guint32 len;
      guint i;

      if (tag_size < 8)
        goto error;

      len = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  number of track ids = %u", len);
      if (len == 0)
        return TRUE;

      if (GST_READ_UINT32_BE (tag_data + 4) != 4)
        goto error;

      if (tag_size < 8 + 4 * len)
        goto error;

      tag_data += 8;
      tag_size -= 8;

      self->n_track_ids = len;
      self->track_ids = g_new0 (guint32, len);

      for (i = 0; i < len; i++) {
        self->track_ids[i] = GST_READ_UINT32_BE (tag_data);
        GST_DEBUG ("    track id %u = %u", i, self->track_ids[i]);
        tag_data += 4;
        tag_size -= 4;
      }
      break;
    }
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_dm_source_clip_parent_class)->handle_tag (metadata,
          primer, tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR ("Invalid DM source clip local tag 0x%04x of size %u", tag,
      tag_size);

  return FALSE;
}

static GstStructure *
mxf_metadata_dm_source_clip_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_dm_source_clip_parent_class)->to_structure (m);
  MXFMetadataDMSourceClip *self = MXF_METADATA_DM_SOURCE_CLIP (m);
  guint i;

  if (self->n_track_ids > 0) {
    GValue arr = { 0, }
    , val = {
    0,};

    g_value_init (&arr, GST_TYPE_ARRAY);

    for (i = 0; i < self->n_track_ids; i++) {
      g_value_init (&val, G_TYPE_UINT);

      g_value_set_uint (&val, self->track_ids[i]);
      gst_value_array_append_value (&arr, &val);
      g_value_unset (&val);
    }

    if (gst_value_array_get_size (&arr) > 0)
      gst_structure_id_set_value (ret, MXF_QUARK (TRACK_IDS), &arr);

    g_value_unset (&arr);
  }

  return ret;
}

static GList *
mxf_metadata_dm_source_clip_write_tags (MXFMetadataBase * m,
    MXFPrimerPack * primer)
{
  MXFMetadataDMSourceClip *self = MXF_METADATA_DM_SOURCE_CLIP (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_dm_source_clip_parent_class)->write_tags (m, primer);
  MXFLocalTag *t;

  if (self->track_ids) {
    guint i;

    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (DM_SOURCECLIP_TRACK_IDS), 16);
    t->size = 8 + 4 * self->n_track_ids;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->n_track_ids);
    GST_WRITE_UINT32_BE (t->data + 4, 4);
    for (i = 0; i < self->n_track_ids; i++)
      GST_WRITE_UINT32_BE (t->data + 8 + i * 4, self->track_ids[i]);
    mxf_primer_pack_add_mapping (primer, 0x6103, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  return ret;
}

static void
mxf_metadata_dm_source_clip_init (MXFMetadataDMSourceClip * self)
{

}

static void
mxf_metadata_dm_source_clip_class_init (MXFMetadataDMSourceClipClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  GObjectClass *object_class = (GObjectClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  object_class->finalize = mxf_metadata_dm_source_clip_finalize;
  metadata_base_class->handle_tag = mxf_metadata_dm_source_clip_handle_tag;
  metadata_base_class->name_quark = MXF_QUARK (DM_SOURCE_CLIP);
  metadata_base_class->to_structure = mxf_metadata_dm_source_clip_to_structure;
  metadata_base_class->write_tags = mxf_metadata_dm_source_clip_write_tags;
  metadata_class->type = 0x0145;
}

G_DEFINE_TYPE (MXFMetadataDMSegment, mxf_metadata_dm_segment,
    MXF_TYPE_METADATA_STRUCTURAL_COMPONENT);

static void
mxf_metadata_dm_segment_finalize (GObject * object)
{
  MXFMetadataDMSegment *self = MXF_METADATA_DM_SEGMENT (object);

  g_free (self->track_ids);
  self->track_ids = NULL;

  g_free (self->event_comment);
  self->event_comment = NULL;

  G_OBJECT_CLASS (mxf_metadata_dm_segment_parent_class)->finalize (object);
}

static gboolean
mxf_metadata_dm_segment_handle_tag (MXFMetadataBase * metadata,
    MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataDMSegment *self = MXF_METADATA_DM_SEGMENT (metadata);
  gboolean ret = TRUE;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  switch (tag) {
    case 0x0601:
      if (tag_size != 8)
        goto error;
      self->event_start_position = GST_READ_UINT64_BE (tag_data);
      GST_DEBUG ("  event start position = %" G_GINT64_FORMAT,
          self->event_start_position);
      break;
    case 0x0602:
      self->event_comment = mxf_utf16_to_utf8 (tag_data, tag_size);
      GST_DEBUG ("  event comment = %s", GST_STR_NULL (self->event_comment));
      break;
    case 0x6102:
    {
      guint32 len;
      guint i;

      if (tag_size < 8)
        goto error;
      len = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  number of track ids = %u", len);
      if (len == 0)
        return TRUE;

      if (GST_READ_UINT32_BE (tag_data + 4) != 4)
        goto error;

      if (len * 4 + 8 < tag_size)
        goto error;

      self->n_track_ids = len;
      self->track_ids = g_new0 (guint32, len);

      tag_data += 8;
      tag_size -= 8;

      for (i = 0; i < len; i++) {
        self->track_ids[i] = GST_READ_UINT32_BE (tag_data);
        GST_DEBUG ("    track id %u = %u", i, self->track_ids[i]);
        tag_data += 4;
        tag_size -= 4;
      }
      break;
    }
    case 0x6101:
      if (tag_size != 16)
        goto error;

      memcpy (&self->dm_framework_uid, tag_data, 16);
      GST_DEBUG ("  DM framework = %s",
          mxf_uuid_to_string (&self->dm_framework_uid, str));
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_dm_segment_parent_class)->handle_tag (metadata, primer,
          tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR ("Invalid DM segment local tag 0x%04x of size %u", tag, tag_size);

  return FALSE;
}

static gboolean
mxf_metadata_dm_segment_resolve (MXFMetadataBase * m, GHashTable * metadata)
{
  MXFMetadataDMSegment *self = MXF_METADATA_DM_SEGMENT (m);
  MXFMetadataBase *current = NULL;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  current = g_hash_table_lookup (metadata, &self->dm_framework_uid);
  if (current && MXF_IS_DESCRIPTIVE_METADATA_FRAMEWORK (current)) {
    if (mxf_metadata_base_resolve (current, metadata)) {
      self->dm_framework = MXF_DESCRIPTIVE_METADATA_FRAMEWORK (current);
    } else {
      GST_ERROR ("Couldn't resolve DM framework %s",
          mxf_uuid_to_string (&self->dm_framework_uid, str));
      return FALSE;
    }
  } else {
    GST_ERROR ("Couldn't find DM framework %s",
        mxf_uuid_to_string (&self->dm_framework_uid, str));
    return FALSE;
  }


  return
      MXF_METADATA_BASE_CLASS (mxf_metadata_dm_segment_parent_class)->resolve
      (m, metadata);
}

static GstStructure *
mxf_metadata_dm_segment_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_dm_segment_parent_class)->to_structure (m);
  MXFMetadataDMSegment *self = MXF_METADATA_DM_SEGMENT (m);
  guint i;

  gst_structure_id_set (ret, MXF_QUARK (EVENT_START_POSITION), G_TYPE_INT64,
      self->event_start_position, NULL);

  if (self->event_comment)
    gst_structure_id_set (ret, MXF_QUARK (EVENT_COMMENT), G_TYPE_STRING,
        self->event_comment, NULL);
  /* FIXME: DMS1 doesn't support serializing to a structure yet */
#if 0
  if (self->dm_framework) {
    GstStructure *s =
        mxf_metadata_base_to_structure (MXF_METADATA_BASE (self->dm_framework));

    gst_structure_id_set (ret, MXF_QUARK (DM_FRAMEWORK), GST_TYPE_STRUCTURE,
        s, NULL);
    gst_structure_free (s);
  }
#endif

  if (self->n_track_ids > 0) {
    GValue arr = { 0, }
    , val = {
    0,};

    g_value_init (&arr, GST_TYPE_ARRAY);

    for (i = 0; i < self->n_track_ids; i++) {
      g_value_init (&val, G_TYPE_UINT);

      g_value_set_uint (&val, self->track_ids[i]);
      gst_value_array_append_value (&arr, &val);
      g_value_unset (&val);
    }

    if (gst_value_array_get_size (&arr) > 0)
      gst_structure_id_set_value (ret, MXF_QUARK (TRACK_IDS), &arr);

    g_value_unset (&arr);
  }

  return ret;
}

static GList *
mxf_metadata_dm_segment_write_tags (MXFMetadataBase * m, MXFPrimerPack * primer)
{
  MXFMetadataDMSegment *self = MXF_METADATA_DM_SEGMENT (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS (mxf_metadata_dm_segment_parent_class)->write_tags
      (m, primer);
  MXFLocalTag *t;

  if (self->event_start_position != -1) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (EVENT_START_POSITION), 16);
    t->size = 8;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT64_BE (t->data, self->event_start_position);
    mxf_primer_pack_add_mapping (primer, 0x0601, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->event_comment) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (EVENT_COMMENT), 16);
    t->data = mxf_utf8_to_utf16 (self->event_comment, &t->size);
    mxf_primer_pack_add_mapping (primer, 0x0602, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->track_ids) {
    guint i;

    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (DM_SEGMENT_TRACK_IDS), 16);
    t->size = 8 + 4 * self->n_track_ids;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->n_track_ids);
    GST_WRITE_UINT32_BE (t->data + 4, 4);
    for (i = 0; i < self->n_track_ids; i++)
      GST_WRITE_UINT32_BE (t->data + 8 + i * 4, self->track_ids[i]);
    mxf_primer_pack_add_mapping (primer, 0x6102, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->dm_framework) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (DM_FRAMEWORK), 16);
    t->size = 16;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    memcpy (t->data, &MXF_METADATA_BASE (self->dm_framework)->instance_uid, 16);
    mxf_primer_pack_add_mapping (primer, 0x6101, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  return ret;
}

static void
mxf_metadata_dm_segment_init (MXFMetadataDMSegment * self)
{
  self->event_start_position = -1;
}

static void
mxf_metadata_dm_segment_class_init (MXFMetadataDMSegmentClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  GObjectClass *object_class = (GObjectClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  object_class->finalize = mxf_metadata_dm_segment_finalize;
  metadata_base_class->handle_tag = mxf_metadata_dm_segment_handle_tag;
  metadata_base_class->resolve = mxf_metadata_dm_segment_resolve;
  metadata_base_class->name_quark = MXF_QUARK (DM_SEGMENT);
  metadata_base_class->to_structure = mxf_metadata_dm_segment_to_structure;
  metadata_base_class->write_tags = mxf_metadata_dm_segment_write_tags;
  metadata_class->type = 0x0141;
}

G_DEFINE_ABSTRACT_TYPE (MXFMetadataGenericDescriptor,
    mxf_metadata_generic_descriptor, MXF_TYPE_METADATA);

static void
mxf_metadata_generic_descriptor_finalize (GObject * object)
{
  MXFMetadataGenericDescriptor *self = MXF_METADATA_GENERIC_DESCRIPTOR (object);

  g_free (self->locators_uids);
  self->locators_uids = NULL;

  g_free (self->locators);
  self->locators = NULL;

  G_OBJECT_CLASS (mxf_metadata_generic_descriptor_parent_class)->finalize
      (object);
}

static gboolean
mxf_metadata_generic_descriptor_handle_tag (MXFMetadataBase * metadata,
    MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataGenericDescriptor *self =
      MXF_METADATA_GENERIC_DESCRIPTOR (metadata);
  gboolean ret = TRUE;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  switch (tag) {
    case 0x2f01:
      if (!mxf_uuid_array_parse (&self->locators_uids, &self->n_locators,
              tag_data, tag_size))
        goto error;

      GST_DEBUG ("  number of locators = %u", self->n_locators);
#ifndef GST_DISABLE_GST_DEBUG
      {
        guint i;
        for (i = 0; i < self->n_locators; i++) {
          GST_DEBUG ("  locator %u = %s", i,
              mxf_uuid_to_string (&self->locators_uids[i], str));
        }
      }
#endif
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_generic_descriptor_parent_class)->handle_tag (metadata,
          primer, tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR ("Invalid generic descriptor local tag 0x%04x of size %u", tag,
      tag_size);

  return FALSE;
}

static gboolean
mxf_metadata_generic_descriptor_resolve (MXFMetadataBase * m,
    GHashTable * metadata)
{
  MXFMetadataGenericDescriptor *self = MXF_METADATA_GENERIC_DESCRIPTOR (m);
  MXFMetadataBase *current = NULL;
  guint i;
  gboolean have_locator = FALSE;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  if (self->locators)
    memset (self->locators, 0, sizeof (gpointer) * self->n_locators);
  else
    self->locators = g_new0 (MXFMetadataLocator *, self->n_locators);
  for (i = 0; i < self->n_locators; i++) {
    current = g_hash_table_lookup (metadata, &self->locators_uids[i]);
    if (current && MXF_IS_METADATA_LOCATOR (current)) {
      if (mxf_metadata_base_resolve (current, metadata)) {
        self->locators[i] = MXF_METADATA_LOCATOR (current);
        have_locator = TRUE;
      } else {
        GST_ERROR ("Couldn't resolve locator %s",
            mxf_uuid_to_string (&self->locators_uids[i], str));
      }
    } else {
      GST_ERROR ("Locator %s not found",
          mxf_uuid_to_string (&self->locators_uids[i], str));
    }
  }

  if (!have_locator && self->n_locators > 0) {
    GST_ERROR ("Couldn't resolve a locator");
    return FALSE;
  }

  return
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_generic_descriptor_parent_class)->resolve (m, metadata);
}

static GstStructure *
mxf_metadata_generic_descriptor_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_generic_descriptor_parent_class)->to_structure (m);
  MXFMetadataGenericDescriptor *self = MXF_METADATA_GENERIC_DESCRIPTOR (m);
  guint i;

  if (self->n_locators > 0) {
    GValue arr = { 0, }
    , val = {
    0,};

    g_value_init (&arr, GST_TYPE_ARRAY);

    for (i = 0; i < self->n_locators; i++) {
      GstStructure *s;

      if (self->locators[i] == NULL)
        continue;

      g_value_init (&val, GST_TYPE_STRUCTURE);

      s = mxf_metadata_base_to_structure (MXF_METADATA_BASE (self->locators
              [i]));
      gst_value_set_structure (&val, s);
      gst_structure_free (s);
      gst_value_array_append_value (&arr, &val);
      g_value_unset (&val);
    }

    if (gst_value_array_get_size (&arr) > 0)
      gst_structure_id_set_value (ret, MXF_QUARK (LOCATORS), &arr);

    g_value_unset (&arr);
  }

  return ret;
}

static GList *
mxf_metadata_generic_descriptor_write_tags (MXFMetadataBase * m,
    MXFPrimerPack * primer)
{
  MXFMetadataGenericDescriptor *self = MXF_METADATA_GENERIC_DESCRIPTOR (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_generic_descriptor_parent_class)->write_tags (m, primer);
  MXFLocalTag *t;

  if (self->locators) {
    guint i;

    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (LOCATORS), 16);
    t->size = 8 + 16 * self->n_locators;
    t->data = g_slice_alloc0 (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->n_locators);
    GST_WRITE_UINT32_BE (t->data + 4, 16);
    for (i = 0; i < self->n_locators; i++) {
      if (!self->locators[i])
        continue;
      memcpy (t->data + 8 + 16 * i,
          &MXF_METADATA_BASE (self->locators[i])->instance_uid, 16);
    }
    mxf_primer_pack_add_mapping (primer, 0x2f01, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  return ret;
}

static void
mxf_metadata_generic_descriptor_init (MXFMetadataGenericDescriptor * self)
{

}

static void
mxf_metadata_generic_descriptor_class_init (MXFMetadataGenericDescriptorClass *
    klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  GObjectClass *object_class = (GObjectClass *) klass;

  object_class->finalize = mxf_metadata_generic_descriptor_finalize;
  metadata_base_class->handle_tag = mxf_metadata_generic_descriptor_handle_tag;
  metadata_base_class->resolve = mxf_metadata_generic_descriptor_resolve;
  metadata_base_class->to_structure =
      mxf_metadata_generic_descriptor_to_structure;
  metadata_base_class->write_tags = mxf_metadata_generic_descriptor_write_tags;
}

G_DEFINE_TYPE (MXFMetadataFileDescriptor, mxf_metadata_file_descriptor,
    MXF_TYPE_METADATA_GENERIC_DESCRIPTOR);

static gboolean
mxf_metadata_file_descriptor_handle_tag (MXFMetadataBase * metadata,
    MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataFileDescriptor *self = MXF_METADATA_FILE_DESCRIPTOR (metadata);
  gboolean ret = TRUE;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  switch (tag) {
    case 0x3006:
      if (tag_size != 4)
        goto error;
      self->linked_track_id = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  linked track id = %u", self->linked_track_id);
      break;
    case 0x3001:
      if (!mxf_fraction_parse (&self->sample_rate, tag_data, tag_size))
        goto error;
      GST_DEBUG ("  sample rate = %d/%d", self->sample_rate.n,
          self->sample_rate.d);
      break;
    case 0x3002:
      if (tag_size != 8)
        goto error;
      self->container_duration = GST_READ_UINT64_BE (tag_data);
      GST_DEBUG ("  container duration = %" G_GINT64_FORMAT,
          self->container_duration);
      break;
    case 0x3004:
      if (tag_size != 16)
        goto error;
      memcpy (&self->essence_container, tag_data, 16);
      GST_DEBUG ("  essence container = %s",
          mxf_ul_to_string (&self->essence_container, str));
      break;
    case 0x3005:
      if (tag_size != 16)
        goto error;
      memcpy (&self->codec, tag_data, 16);
      GST_DEBUG ("  codec = %s", mxf_ul_to_string (&self->codec, str));
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_file_descriptor_parent_class)->handle_tag (metadata,
          primer, tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR ("Invalid file descriptor local tag 0x%04x of size %u", tag,
      tag_size);

  return FALSE;
}

static GstStructure *
mxf_metadata_file_descriptor_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_file_descriptor_parent_class)->to_structure (m);
  MXFMetadataFileDescriptor *self = MXF_METADATA_FILE_DESCRIPTOR (m);
  gchar str[48];

  if (self->linked_track_id)
    gst_structure_id_set (ret, MXF_QUARK (LINKED_TRACK_ID), G_TYPE_UINT,
        self->linked_track_id, NULL);

  if (self->sample_rate.n && self->sample_rate.d)
    gst_structure_id_set (ret, MXF_QUARK (SAMPLE_RATE), GST_TYPE_FRACTION,
        self->sample_rate.n, self->sample_rate.d, NULL);

  if (self->container_duration)
    gst_structure_id_set (ret, MXF_QUARK (CONTAINER_DURATION), G_TYPE_INT64,
        self->container_duration, NULL);

  mxf_ul_to_string (&self->essence_container, str);
  gst_structure_id_set (ret, MXF_QUARK (ESSENCE_CONTAINER), G_TYPE_STRING, str,
      NULL);

  if (!mxf_ul_is_zero (&self->codec)) {
    mxf_ul_to_string (&self->codec, str);
    gst_structure_id_set (ret, MXF_QUARK (CODEC), G_TYPE_STRING, str, NULL);
  }

  return ret;
}

static GList *
mxf_metadata_file_descriptor_write_tags (MXFMetadataBase * m,
    MXFPrimerPack * primer)
{
  MXFMetadataFileDescriptor *self = MXF_METADATA_FILE_DESCRIPTOR (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_file_descriptor_parent_class)->write_tags (m, primer);
  MXFLocalTag *t;

  if (self->linked_track_id) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (LINKED_TRACK_ID), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->linked_track_id);
    mxf_primer_pack_add_mapping (primer, 0x3006, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (SAMPLE_RATE), 16);
  t->size = 8;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT32_BE (t->data, self->sample_rate.n);
  GST_WRITE_UINT32_BE (t->data + 4, self->sample_rate.d);
  mxf_primer_pack_add_mapping (primer, 0x3001, &t->ul);
  ret = g_list_prepend (ret, t);

  if (self->container_duration > 0) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (CONTAINER_DURATION), 16);
    t->size = 8;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT64_BE (t->data, self->container_duration);
    mxf_primer_pack_add_mapping (primer, 0x3002, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (ESSENCE_CONTAINER), 16);
  t->size = 16;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  memcpy (t->data, &self->essence_container, 16);
  mxf_primer_pack_add_mapping (primer, 0x3004, &t->ul);
  ret = g_list_prepend (ret, t);

  if (!mxf_ul_is_zero (&self->codec)) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (CODEC), 16);
    t->size = 16;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    memcpy (t->data, &self->codec, 16);
    mxf_primer_pack_add_mapping (primer, 0x3005, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  return ret;
}

static void
mxf_metadata_file_descriptor_init (MXFMetadataFileDescriptor * self)
{

}

static void
mxf_metadata_file_descriptor_class_init (MXFMetadataFileDescriptorClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  metadata_base_class->handle_tag = mxf_metadata_file_descriptor_handle_tag;
  metadata_base_class->name_quark = MXF_QUARK (FILE_DESCRIPTOR);
  metadata_base_class->to_structure = mxf_metadata_file_descriptor_to_structure;
  metadata_base_class->write_tags = mxf_metadata_file_descriptor_write_tags;
  metadata_class->type = 0x0125;
}

G_DEFINE_TYPE (MXFMetadataGenericPictureEssenceDescriptor,
    mxf_metadata_generic_picture_essence_descriptor,
    MXF_TYPE_METADATA_FILE_DESCRIPTOR);

static gboolean
mxf_metadata_generic_picture_essence_descriptor_handle_tag (MXFMetadataBase *
    metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataGenericPictureEssenceDescriptor *self =
      MXF_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (metadata);
  gboolean ret = TRUE;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  switch (tag) {
    case 0x3215:
      if (tag_size != 1)
        goto error;
      self->signal_standard = GST_READ_UINT8 (tag_data);
      GST_DEBUG ("  signal standard = %u", self->signal_standard);
      break;
    case 0x320c:
      if (tag_size != 1)
        goto error;
      self->frame_layout = GST_READ_UINT8 (tag_data);
      GST_DEBUG ("  frame layout = %u", self->frame_layout);
      break;
    case 0x3203:
      if (tag_size != 4)
        goto error;
      self->stored_width = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  stored width = %u", self->stored_width);
      break;
    case 0x3202:
      if (tag_size != 4)
        goto error;
      self->stored_height = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  stored height = %u", self->stored_height);
      break;
    case 0x3216:
      if (tag_size != 4)
        goto error;
      self->stored_f2_offset = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  stored f2 offset = %d", self->stored_f2_offset);
      break;
    case 0x3205:
      if (tag_size != 4)
        goto error;
      self->sampled_width = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  sampled width = %u", self->sampled_width);
      break;
    case 0x3204:
      if (tag_size != 4)
        goto error;
      self->sampled_height = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  sampled height = %u", self->sampled_height);
      break;
    case 0x3206:
      if (tag_size != 4)
        goto error;
      self->sampled_x_offset = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  sampled x offset = %d", self->sampled_x_offset);
      break;
    case 0x3207:
      if (tag_size != 4)
        goto error;
      self->sampled_y_offset = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  sampled y offset = %d", self->sampled_y_offset);
      break;
    case 0x3208:
      if (tag_size != 4)
        goto error;
      self->display_height = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  display height = %u", self->display_height);
      break;
    case 0x3209:
      if (tag_size != 4)
        goto error;
      self->display_width = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  display width = %u", self->display_width);
      break;
    case 0x320a:
      if (tag_size != 4)
        goto error;
      self->display_x_offset = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  display x offset = %d", self->display_x_offset);
      break;
    case 0x320b:
      if (tag_size != 4)
        goto error;
      self->display_y_offset = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  display y offset = %d", self->display_y_offset);
      break;
    case 0x3217:
      if (tag_size != 4)
        goto error;
      self->display_f2_offset = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  display f2 offset = %d", self->display_f2_offset);
      break;
    case 0x320e:
      if (!mxf_fraction_parse (&self->aspect_ratio, tag_data, tag_size))
        goto error;
      GST_DEBUG ("  aspect ratio = %d/%d", self->aspect_ratio.n,
          self->aspect_ratio.d);
      break;
    case 0x3218:
      if (tag_size != 1)
        goto error;
      self->active_format_descriptor = GST_READ_UINT8 (tag_data);
      GST_DEBUG ("  active format descriptor = %u",
          self->active_format_descriptor);
      break;
    case 0x320d:
      if (tag_size < 8)
        goto error;

      if (GST_READ_UINT32_BE (tag_data) == 0)
        return TRUE;

      if (GST_READ_UINT32_BE (tag_data + 4) != 4)
        goto error;

      if (GST_READ_UINT32_BE (tag_data) != 1 &&
          GST_READ_UINT32_BE (tag_data) != 2)
        goto error;

      if ((GST_READ_UINT32_BE (tag_data) == 1 && tag_size != 12) ||
          (GST_READ_UINT32_BE (tag_data) == 2 && tag_size != 16))
        goto error;

      self->video_line_map[0] = GST_READ_UINT32_BE (tag_data + 8);

      /* Workaround for files created by ffmpeg */
      if (GST_READ_UINT32_BE (tag_data) == 1)
        self->video_line_map[0] = 0;
      else
        self->video_line_map[1] = GST_READ_UINT32_BE (tag_data + 12);

      GST_DEBUG ("  video line map = {%i, %i}", self->video_line_map[0],
          self->video_line_map[1]);
      break;
    case 0x320f:
      if (tag_size != 1)
        goto error;
      self->alpha_transparency = GST_READ_UINT8 (tag_data);
      GST_DEBUG ("  alpha transparency = %u", self->alpha_transparency);
      break;
    case 0x3210:
      if (tag_size != 16)
        goto error;
      memcpy (&self->capture_gamma, tag_data, 16);
      GST_DEBUG ("  capture gamma = %s",
          mxf_ul_to_string (&self->capture_gamma, str));
      break;
    case 0x3211:
      if (tag_size != 4)
        goto error;
      self->image_alignment_offset = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  image alignment offset = %u", self->image_alignment_offset);
      break;
    case 0x3213:
      if (tag_size != 4)
        goto error;
      self->image_start_offset = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  image start offset = %u", self->image_start_offset);
      break;
    case 0x3214:
      if (tag_size != 4)
        goto error;
      self->image_end_offset = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  image end offset = %u", self->image_end_offset);
      break;
    case 0x3212:
      if (tag_size != 1)
        goto error;
      self->field_dominance = GST_READ_UINT8 (tag_data);
      GST_DEBUG ("  field dominance = %u", self->field_dominance);
      break;
    case 0x3201:
      if (tag_size != 16)
        goto error;
      memcpy (&self->picture_essence_coding, tag_data, 16);
      GST_DEBUG ("  picture essence coding = %s",
          mxf_ul_to_string (&self->picture_essence_coding, str));
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_generic_picture_essence_descriptor_parent_class)->handle_tag
          (metadata, primer, tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR
      ("Invalid generic picture essence descriptor local tag 0x%04x of size %u",
      tag, tag_size);

  return FALSE;
}

static GstStructure *
mxf_metadata_generic_picture_essence_descriptor_to_structure (MXFMetadataBase *
    m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_generic_picture_essence_descriptor_parent_class)->to_structure
      (m);
  MXFMetadataGenericPictureEssenceDescriptor *self =
      MXF_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (m);
  gchar str[48];

  gst_structure_id_set (ret, MXF_QUARK (SIGNAL_STANDARD), G_TYPE_UCHAR,
      self->signal_standard, NULL);

  gst_structure_id_set (ret, MXF_QUARK (FRAME_LAYOUT), G_TYPE_UCHAR,
      self->frame_layout, NULL);

  gst_structure_id_set (ret, MXF_QUARK (STORED_WIDTH), G_TYPE_UINT,
      self->stored_width, MXF_QUARK (STORED_HEIGHT), G_TYPE_UINT,
      self->stored_height, NULL);

  if (self->stored_f2_offset != 0)
    gst_structure_id_set (ret, MXF_QUARK (STORED_F2_OFFSET), G_TYPE_INT,
        self->stored_f2_offset, NULL);

  if (self->sampled_width != 0 && self->sampled_height != 0)
    gst_structure_id_set (ret, MXF_QUARK (SAMPLED_WIDTH), G_TYPE_UINT,
        self->sampled_width, MXF_QUARK (SAMPLED_HEIGHT), G_TYPE_UINT,
        self->sampled_height, NULL);

  if (self->sampled_x_offset != 0)
    gst_structure_id_set (ret, MXF_QUARK (SAMPLED_X_OFFSET), G_TYPE_INT,
        self->sampled_x_offset, NULL);

  if (self->sampled_y_offset != 0)
    gst_structure_id_set (ret, MXF_QUARK (SAMPLED_Y_OFFSET), G_TYPE_INT,
        self->sampled_y_offset, NULL);

  if (self->display_width != 0 && self->display_height != 0)
    gst_structure_id_set (ret, MXF_QUARK (DISPLAY_WIDTH), G_TYPE_UINT,
        self->display_width, MXF_QUARK (DISPLAY_HEIGHT), G_TYPE_UINT,
        self->display_height, NULL);

  if (self->display_x_offset != 0)
    gst_structure_id_set (ret, MXF_QUARK (DISPLAY_X_OFFSET), G_TYPE_INT,
        self->display_x_offset, NULL);

  if (self->display_y_offset != 0)
    gst_structure_id_set (ret, MXF_QUARK (DISPLAY_Y_OFFSET), G_TYPE_INT,
        self->display_y_offset, NULL);

  if (self->display_f2_offset != 0)
    gst_structure_id_set (ret, MXF_QUARK (DISPLAY_F2_OFFSET), G_TYPE_INT,
        self->display_f2_offset, NULL);

  if (self->aspect_ratio.n != 0 && self->aspect_ratio.d != 0)
    gst_structure_id_set (ret, MXF_QUARK (ASPECT_RATIO), GST_TYPE_FRACTION,
        self->aspect_ratio.n, self->aspect_ratio.d, NULL);

  if (self->active_format_descriptor)
    gst_structure_id_set (ret, MXF_QUARK (ACTIVE_FORMAT_DESCRIPTOR),
        G_TYPE_UCHAR, self->active_format_descriptor, NULL);

  gst_structure_id_set (ret, MXF_QUARK (VIDEO_LINE_MAP_0), G_TYPE_UINT,
      self->video_line_map[0], MXF_QUARK (VIDEO_LINE_MAP_1), G_TYPE_UINT,
      self->video_line_map[1], NULL);

  if (self->alpha_transparency != 0)
    gst_structure_id_set (ret, MXF_QUARK (ALPHA_TRANSPARENCY), G_TYPE_UCHAR,
        self->alpha_transparency, NULL);

  if (!mxf_ul_is_zero (&self->capture_gamma)) {
    mxf_ul_to_string (&self->capture_gamma, str);
    gst_structure_id_set (ret, MXF_QUARK (CAPTURE_GAMMA), G_TYPE_STRING, str,
        NULL);
  }

  if (self->image_alignment_offset != 0)
    gst_structure_id_set (ret, MXF_QUARK (IMAGE_ALIGNMENT_OFFSET), G_TYPE_UINT,
        self->image_alignment_offset, NULL);

  if (self->image_start_offset != 0)
    gst_structure_id_set (ret, MXF_QUARK (IMAGE_START_OFFSET), G_TYPE_UINT,
        self->image_start_offset, NULL);

  if (self->image_end_offset != 0)
    gst_structure_id_set (ret, MXF_QUARK (IMAGE_END_OFFSET), G_TYPE_UINT,
        self->image_end_offset, NULL);

  if (self->field_dominance != 0)
    gst_structure_id_set (ret, MXF_QUARK (FIELD_DOMINANCE), G_TYPE_UCHAR,
        self->field_dominance, NULL);

  if (!mxf_ul_is_zero (&self->picture_essence_coding)) {
    mxf_ul_to_string (&self->picture_essence_coding, str);
    gst_structure_id_set (ret, MXF_QUARK (PICTURE_ESSENCE_CODING),
        G_TYPE_STRING, str, NULL);
  }

  return ret;
}

static GList *
mxf_metadata_generic_picture_essence_descriptor_write_tags (MXFMetadataBase * m,
    MXFPrimerPack * primer)
{
  MXFMetadataGenericPictureEssenceDescriptor *self =
      MXF_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_generic_picture_essence_descriptor_parent_class)->write_tags
      (m, primer);
  MXFLocalTag *t;

  if (self->signal_standard != 1) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (SIGNAL_STANDARD), 16);
    t->size = 1;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT8 (t->data, self->signal_standard);
    mxf_primer_pack_add_mapping (primer, 0x3215, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (FRAME_LAYOUT), 16);
  t->size = 1;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT8 (t->data, self->frame_layout);
  mxf_primer_pack_add_mapping (primer, 0x320c, &t->ul);
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (STORED_WIDTH), 16);
  t->size = 4;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT32_BE (t->data, self->stored_width);
  mxf_primer_pack_add_mapping (primer, 0x3203, &t->ul);
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (STORED_HEIGHT), 16);
  t->size = 4;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT32_BE (t->data, self->stored_height);
  mxf_primer_pack_add_mapping (primer, 0x3202, &t->ul);
  ret = g_list_prepend (ret, t);

  if (self->stored_f2_offset != 0) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (STORED_F2_OFFSET), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->stored_f2_offset);
    mxf_primer_pack_add_mapping (primer, 0x3216, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->sampled_width != 0) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (SAMPLED_WIDTH), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->sampled_width);
    mxf_primer_pack_add_mapping (primer, 0x3205, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->sampled_height != 0) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (SAMPLED_HEIGHT), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->sampled_height);
    mxf_primer_pack_add_mapping (primer, 0x3204, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->sampled_x_offset != 0) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (SAMPLED_X_OFFSET), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->sampled_x_offset);
    mxf_primer_pack_add_mapping (primer, 0x3206, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->sampled_y_offset != 0) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (SAMPLED_Y_OFFSET), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->sampled_y_offset);
    mxf_primer_pack_add_mapping (primer, 0x3207, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->display_height != 0) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (DISPLAY_HEIGHT), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->display_height);
    mxf_primer_pack_add_mapping (primer, 0x3208, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->display_width != 0) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (DISPLAY_WIDTH), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->display_width);
    mxf_primer_pack_add_mapping (primer, 0x3209, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->display_x_offset != 0) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (DISPLAY_X_OFFSET), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->display_x_offset);
    mxf_primer_pack_add_mapping (primer, 0x320a, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->display_y_offset != 0) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (DISPLAY_Y_OFFSET), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->display_y_offset);
    mxf_primer_pack_add_mapping (primer, 0x320b, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->display_f2_offset != 0) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (DISPLAY_F2_OFFSET), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->display_f2_offset);
    mxf_primer_pack_add_mapping (primer, 0x3217, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (ASPECT_RATIO), 16);
  t->size = 8;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT32_BE (t->data, self->aspect_ratio.n);
  GST_WRITE_UINT32_BE (t->data + 4, self->aspect_ratio.d);
  mxf_primer_pack_add_mapping (primer, 0x320e, &t->ul);
  ret = g_list_prepend (ret, t);

  if (self->active_format_descriptor != 0) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (ACTIVE_FORMAT_DESCRIPTOR), 16);
    t->size = 1;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT8 (t->data, self->active_format_descriptor);
    mxf_primer_pack_add_mapping (primer, 0x3218, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (VIDEO_LINE_MAP), 16);
  t->size = 16;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT32_BE (t->data, 2);
  GST_WRITE_UINT32_BE (t->data + 4, 4);
  GST_WRITE_UINT32_BE (t->data + 8, self->video_line_map[0]);
  GST_WRITE_UINT32_BE (t->data + 12, self->video_line_map[1]);
  mxf_primer_pack_add_mapping (primer, 0x320d, &t->ul);
  ret = g_list_prepend (ret, t);

  if (self->alpha_transparency != 0) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (ALPHA_TRANSPARENCY), 16);
    t->size = 1;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT8 (t->data, self->alpha_transparency);
    mxf_primer_pack_add_mapping (primer, 0x320f, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (!mxf_ul_is_zero (&self->capture_gamma)) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (CAPTURE_GAMMA), 16);
    t->size = 16;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    memcpy (t->data, &self->capture_gamma, 16);
    mxf_primer_pack_add_mapping (primer, 0x3210, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->image_alignment_offset != 0) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (IMAGE_ALIGNMENT_OFFSET), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->image_alignment_offset);
    mxf_primer_pack_add_mapping (primer, 0x3211, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->image_start_offset != 0) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (IMAGE_START_OFFSET), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->image_start_offset);
    mxf_primer_pack_add_mapping (primer, 0x3213, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->image_end_offset != 0) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (IMAGE_END_OFFSET), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->image_end_offset);
    mxf_primer_pack_add_mapping (primer, 0x3214, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->field_dominance != 0) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (FIELD_DOMINANCE), 16);
    t->size = 1;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT8 (t->data, self->field_dominance);
    mxf_primer_pack_add_mapping (primer, 0x3212, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (!mxf_ul_is_zero (&self->picture_essence_coding)) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (PICTURE_ESSENCE_CODING), 16);
    t->size = 16;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    memcpy (t->data, &self->picture_essence_coding, 16);
    mxf_primer_pack_add_mapping (primer, 0x3201, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  return ret;
}

static void
    mxf_metadata_generic_picture_essence_descriptor_init
    (MXFMetadataGenericPictureEssenceDescriptor * self)
{
  self->signal_standard = 1;
  self->frame_layout = 255;
}

static void
    mxf_metadata_generic_picture_essence_descriptor_class_init
    (MXFMetadataGenericPictureEssenceDescriptorClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  metadata_base_class->handle_tag =
      mxf_metadata_generic_picture_essence_descriptor_handle_tag;
  metadata_base_class->name_quark =
      MXF_QUARK (GENERIC_PICTURE_ESSENCE_DESCRIPTOR);
  metadata_base_class->to_structure =
      mxf_metadata_generic_picture_essence_descriptor_to_structure;
  metadata_base_class->write_tags =
      mxf_metadata_generic_picture_essence_descriptor_write_tags;
  metadata_class->type = 0x0127;
}

void mxf_metadata_generic_picture_essence_descriptor_set_caps
    (MXFMetadataGenericPictureEssenceDescriptor * self, GstCaps * caps)
{
  guint par_n, par_d;
  guint width, height;
  MXFMetadataFileDescriptor *f = (MXFMetadataFileDescriptor *) self;

  g_return_if_fail (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (self));
  g_return_if_fail (GST_IS_CAPS (caps));

  if (f->sample_rate.d == 0) {
    GST_ERROR ("Invalid framerate");
  } else {
    gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION, f->sample_rate.n,
        f->sample_rate.d, NULL);
  }

  width = self->stored_width;
  height = self->stored_height;

  /* If the video is stored as separate fields the
   * height is only the height of one field, i.e.
   * half the height of the frame.
   *
   * See SMPTE 377M E2.2 and E1.2
   */
  if (self->frame_layout == 1 || self->frame_layout == 2
      || self->frame_layout == 4) {
    height *= 2;
    gst_caps_set_simple (caps, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL);
  }

  if (width == 0 || height == 0) {
    GST_ERROR ("Invalid width/height");
    return;
  }

  gst_caps_set_simple (caps, "width", G_TYPE_INT, width, "height", G_TYPE_INT,
      height, NULL);

  if (self->aspect_ratio.n == 0 && self->aspect_ratio.d == 0) {
    gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
        1, 1, NULL);
  } else if (self->aspect_ratio.n == 0 || self->aspect_ratio.d == 0) {
    GST_ERROR ("Invalid aspect ratio");
  } else {
    par_n = height * self->aspect_ratio.n;
    par_d = width * self->aspect_ratio.d;

    gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
        par_n, par_d, NULL);
  }
}

static gint
gst_greatest_common_divisor (gint a, gint b)
{
  while (b != 0) {
    int temp = a;

    a = b;
    b = temp % b;
  }

  return ABS (a);
}

gboolean
    mxf_metadata_generic_picture_essence_descriptor_from_caps
    (MXFMetadataGenericPictureEssenceDescriptor * self, GstCaps * caps) {
  gint par_n, par_d, gcd;
  gint width, height;
  gint fps_n, fps_d;
  MXFMetadataFileDescriptor *f = (MXFMetadataFileDescriptor *) self;
  GstStructure *s;
  gboolean interlaced = FALSE;

  g_return_val_if_fail (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR
      (self), FALSE);
  g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);

  s = gst_caps_get_structure (caps, 0);

  if (!gst_structure_get_boolean (s, "interlaced", &interlaced) || !interlaced)
    self->frame_layout = 0;
  else
    self->frame_layout = 3;

  if (!gst_structure_get_fraction (s, "framerate", &fps_n, &fps_d)) {
    GST_ERROR ("Invalid framerate");
    return FALSE;
  }
  f->sample_rate.n = fps_n;
  f->sample_rate.d = fps_d;

  if (!gst_structure_get_int (s, "width", &width) ||
      !gst_structure_get_int (s, "height", &height)) {
    GST_ERROR ("Invalid width/height");
    return FALSE;
  }

  self->stored_width = width;
  self->stored_height = height;

  if (!gst_structure_get_fraction (s, "pixel-aspect-ratio", &par_n, &par_d)) {
    par_n = 1;
    par_d = 1;
  }

  self->aspect_ratio.n = par_n * width;
  self->aspect_ratio.d = par_d * height;
  gcd =
      gst_greatest_common_divisor (self->aspect_ratio.n, self->aspect_ratio.d);
  self->aspect_ratio.n /= gcd;
  self->aspect_ratio.d /= gcd;

  return TRUE;
}


G_DEFINE_TYPE (MXFMetadataGenericSoundEssenceDescriptor,
    mxf_metadata_generic_sound_essence_descriptor,
    MXF_TYPE_METADATA_FILE_DESCRIPTOR);

static gboolean
mxf_metadata_generic_sound_essence_descriptor_handle_tag (MXFMetadataBase *
    metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataGenericSoundEssenceDescriptor *self =
      MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (metadata);
  gboolean ret = TRUE;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  switch (tag) {
    case 0x3d03:
      if (!mxf_fraction_parse (&self->audio_sampling_rate, tag_data, tag_size))
        goto error;
      GST_DEBUG ("  audio sampling rate = %d/%d",
          self->audio_sampling_rate.n, self->audio_sampling_rate.d);
      break;
    case 0x3d02:
      if (tag_size != 1)
        goto error;
      self->locked = (GST_READ_UINT8 (tag_data) != 0);
      GST_DEBUG ("  locked = %s", (self->locked) ? "yes" : "no");
      break;
    case 0x3d04:
      if (tag_size != 1)
        goto error;
      self->audio_ref_level = GST_READ_UINT8 (tag_data);
      GST_DEBUG ("  audio ref level = %d", self->audio_ref_level);
      break;
    case 0x3d05:
      if (tag_size != 1)
        goto error;
      self->electro_spatial_formulation = GST_READ_UINT8 (tag_data);
      GST_DEBUG ("  electro spatial formulation = %u",
          self->electro_spatial_formulation);
      break;
    case 0x3d07:
      if (tag_size != 4)
        goto error;
      self->channel_count = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  channel count = %u", self->channel_count);
      break;
    case 0x3d01:
      if (tag_size != 4)
        goto error;
      self->quantization_bits = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  quantization bits = %u", self->quantization_bits);
      break;
    case 0x3d0c:
      if (tag_size != 1)
        goto error;
      self->dial_norm = GST_READ_UINT8 (tag_data);
      GST_DEBUG ("  dial norm = %d", self->dial_norm);
      break;
    case 0x3d06:
      if (tag_size != 16)
        goto error;
      memcpy (&self->sound_essence_compression, tag_data, 16);
      GST_DEBUG ("  sound essence compression = %s",
          mxf_ul_to_string (&self->sound_essence_compression, str));
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_generic_sound_essence_descriptor_parent_class)->handle_tag
          (metadata, primer, tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR
      ("Invalid generic sound essence descriptor local tag 0x%04x of size %u",
      tag, tag_size);

  return FALSE;
}

static GstStructure *
mxf_metadata_generic_sound_essence_descriptor_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_generic_sound_essence_descriptor_parent_class)->to_structure
      (m);
  MXFMetadataGenericSoundEssenceDescriptor *self =
      MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (m);

  gst_structure_id_set (ret, MXF_QUARK (AUDIO_SAMPLING_RATE), GST_TYPE_FRACTION,
      self->audio_sampling_rate.n, self->audio_sampling_rate.d, NULL);

  gst_structure_id_set (ret, MXF_QUARK (LOCKED), G_TYPE_BOOLEAN, self->locked,
      NULL);

  if (self->electro_spatial_formulation != 0)
    gst_structure_id_set (ret, MXF_QUARK (ELECTRO_SPATIAL_FORMULATION),
        G_TYPE_UCHAR, self->electro_spatial_formulation, NULL);

  gst_structure_id_set (ret, MXF_QUARK (CHANNEL_COUNT), G_TYPE_UINT,
      self->channel_count, NULL);

  gst_structure_id_set (ret, MXF_QUARK (QUANTIZATION_BITS), G_TYPE_UINT,
      self->quantization_bits, NULL);

  if (self->dial_norm != 0)
    gst_structure_id_set (ret, MXF_QUARK (DIAL_NORM), G_TYPE_CHAR,
        self->dial_norm, NULL);

  if (!mxf_ul_is_zero (&self->sound_essence_compression)) {
    gchar str[48];

    mxf_ul_to_string (&self->sound_essence_compression, str);
    gst_structure_id_set (ret, MXF_QUARK (SOUND_ESSENCE_COMPRESSION),
        G_TYPE_STRING, str, NULL);
  }

  return ret;
}

static GList *
mxf_metadata_generic_sound_essence_descriptor_write_tags (MXFMetadataBase * m,
    MXFPrimerPack * primer)
{
  MXFMetadataGenericSoundEssenceDescriptor *self =
      MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_generic_sound_essence_descriptor_parent_class)->write_tags
      (m, primer);
  MXFLocalTag *t;

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (AUDIO_SAMPLING_RATE), 16);
  t->size = 8;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT32_BE (t->data, self->audio_sampling_rate.n);
  GST_WRITE_UINT32_BE (t->data + 4, self->audio_sampling_rate.d);
  mxf_primer_pack_add_mapping (primer, 0x3d03, &t->ul);
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (LOCKED), 16);
  t->size = 1;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT8 (t->data, (self->locked) ? 1 : 0);
  mxf_primer_pack_add_mapping (primer, 0x3d02, &t->ul);
  ret = g_list_prepend (ret, t);

  if (self->audio_ref_level) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (AUDIO_REF_LEVEL), 16);
    t->size = 1;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT8 (t->data, self->audio_ref_level);
    mxf_primer_pack_add_mapping (primer, 0x3d04, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->electro_spatial_formulation != 255) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (ELECTRO_SPATIAL_FORMULATION), 16);
    t->size = 1;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT8 (t->data, self->electro_spatial_formulation);
    mxf_primer_pack_add_mapping (primer, 0x3d05, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (CHANNEL_COUNT), 16);
  t->size = 4;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT32_BE (t->data, self->channel_count);
  mxf_primer_pack_add_mapping (primer, 0x3d07, &t->ul);
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (QUANTIZATION_BITS), 16);
  t->size = 4;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT32_BE (t->data, self->quantization_bits);
  mxf_primer_pack_add_mapping (primer, 0x3d01, &t->ul);
  ret = g_list_prepend (ret, t);

  if (self->dial_norm != 0) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (DIAL_NORM), 16);
    t->size = 1;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT8 (t->data, self->dial_norm);
    mxf_primer_pack_add_mapping (primer, 0x3d0c, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (!mxf_ul_is_zero (&self->sound_essence_compression)) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (SOUND_ESSENCE_COMPRESSION), 16);
    t->size = 16;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    memcpy (t->data, &self->sound_essence_compression, 16);
    mxf_primer_pack_add_mapping (primer, 0x3d06, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  return ret;
}

static void
    mxf_metadata_generic_sound_essence_descriptor_init
    (MXFMetadataGenericSoundEssenceDescriptor * self)
{
  self->audio_sampling_rate.n = 0;
  self->audio_sampling_rate.d = 1;
  self->electro_spatial_formulation = 255;
}

static void
    mxf_metadata_generic_sound_essence_descriptor_class_init
    (MXFMetadataGenericSoundEssenceDescriptorClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  metadata_base_class->handle_tag =
      mxf_metadata_generic_sound_essence_descriptor_handle_tag;
  metadata_base_class->name_quark =
      MXF_QUARK (GENERIC_SOUND_ESSENCE_DESCRIPTOR);
  metadata_base_class->to_structure =
      mxf_metadata_generic_sound_essence_descriptor_to_structure;
  metadata_base_class->write_tags =
      mxf_metadata_generic_sound_essence_descriptor_write_tags;
  metadata_class->type = 0x0142;
}

void mxf_metadata_generic_sound_essence_descriptor_set_caps
    (MXFMetadataGenericSoundEssenceDescriptor * self, GstCaps * caps)
{
  g_return_if_fail (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (self));
  g_return_if_fail (GST_IS_CAPS (caps));

  if (self->audio_sampling_rate.n == 0 || self->audio_sampling_rate.d == 0) {
    GST_ERROR ("Invalid audio sampling rate");
  } else {
    gst_caps_set_simple (caps, "rate", G_TYPE_INT,
        (gint) (mxf_fraction_to_double (&self->audio_sampling_rate) + 0.5),
        NULL);
  }

  if (self->channel_count == 0) {
    GST_ERROR ("Invalid number of channels (0)");
  } else {
    gst_caps_set_simple (caps, "channels", G_TYPE_INT, self->channel_count,
        NULL);
  }
}

GstCaps *mxf_metadata_generic_sound_essence_descriptor_create_caps
    (MXFMetadataGenericSoundEssenceDescriptor * self, GstAudioFormat * format)
{
  GstAudioInfo info;
  gint rate = 0;
  gint channels = 0;

  g_return_val_if_fail (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (self),
      NULL);

  gst_audio_info_init (&info);

  if (self->audio_sampling_rate.n == 0 || self->audio_sampling_rate.d == 0) {
    GST_ERROR ("Invalid audio sampling rate");
  } else {
    rate = (gint) (mxf_fraction_to_double (&self->audio_sampling_rate)
        + 0.5);
  }

  if (self->channel_count == 0) {
    GST_ERROR ("Invalid number of channels (0)");
  } else {
    channels = self->channel_count;
  }

  gst_audio_info_set_format (&info, *format, rate, channels, NULL);

  return gst_audio_info_to_caps (&info);
}

gboolean
    mxf_metadata_generic_sound_essence_descriptor_from_caps
    (MXFMetadataGenericSoundEssenceDescriptor * self, GstCaps * caps) {
  gint rate;
  gint channels;
  GstStructure *s;

  g_return_val_if_fail (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (self),
      FALSE);
  g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);

  s = gst_caps_get_structure (caps, 0);

  if (!gst_structure_get_int (s, "rate", &rate) || rate == 0) {
    GST_WARNING ("No samplerate");
    return FALSE;
  } else {
    self->audio_sampling_rate.n = rate;
    self->audio_sampling_rate.d = 1;
  }

  if (!gst_structure_get_int (s, "channels", &channels) || channels == 0) {
    GST_WARNING ("No channels");
    return FALSE;
  } else {
    self->channel_count = channels;
  }

  return TRUE;
}


G_DEFINE_TYPE (MXFMetadataCDCIPictureEssenceDescriptor,
    mxf_metadata_cdci_picture_essence_descriptor,
    MXF_TYPE_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR);

static gboolean
mxf_metadata_cdci_picture_essence_descriptor_handle_tag (MXFMetadataBase *
    metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataCDCIPictureEssenceDescriptor *self =
      MXF_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (metadata);
  gboolean ret = TRUE;

  switch (tag) {
    case 0x3301:
      if (tag_size != 4)
        goto error;
      self->component_depth = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  component depth = %u", self->component_depth);
      break;
    case 0x3302:
      if (tag_size != 4)
        goto error;
      self->horizontal_subsampling = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  horizontal subsampling = %u", self->horizontal_subsampling);
      break;
    case 0x3308:
      if (tag_size != 4)
        goto error;
      self->vertical_subsampling = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  vertical subsampling = %u", self->vertical_subsampling);
      break;
    case 0x3303:
      if (tag_size != 1)
        goto error;
      self->color_siting = GST_READ_UINT8 (tag_data);
      GST_DEBUG ("  color siting = %u", self->color_siting);
      break;
    case 0x330b:
      if (tag_size != 1)
        goto error;
      self->reversed_byte_order = GST_READ_UINT8 (tag_data);
      GST_DEBUG ("  reversed byte order = %s",
          (self->reversed_byte_order) ? "yes" : "no");
      break;
    case 0x3307:
      if (tag_size != 2)
        goto error;
      self->padding_bits = GST_READ_UINT16_BE (tag_data);
      GST_DEBUG ("  padding bits = %d", self->padding_bits);
      break;
    case 0x3309:
      if (tag_size != 4)
        goto error;
      self->alpha_sample_depth = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  alpha sample depth = %u", self->alpha_sample_depth);
      break;
    case 0x3304:
      if (tag_size != 4)
        goto error;
      self->black_ref_level = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  black ref level = %u", self->black_ref_level);
      break;
    case 0x3305:
      if (tag_size != 4)
        goto error;
      self->white_ref_level = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  white ref level = %u", self->white_ref_level);
      break;
    case 0x3306:
      if (tag_size != 4)
        goto error;
      self->color_range = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  color range = %u", self->color_range);
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_cdci_picture_essence_descriptor_parent_class)->handle_tag
          (metadata, primer, tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR
      ("Invalid CDCI picture essence descriptor local tag 0x%04x of size %u",
      tag, tag_size);

  return FALSE;
}

static GstStructure *
mxf_metadata_cdci_picture_essence_descriptor_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_cdci_picture_essence_descriptor_parent_class)->to_structure
      (m);
  MXFMetadataCDCIPictureEssenceDescriptor *self =
      MXF_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (m);

  gst_structure_id_set (ret, MXF_QUARK (COMPONENT_DEPTH), G_TYPE_UINT,
      self->component_depth, NULL);

  gst_structure_id_set (ret, MXF_QUARK (HORIZONTAL_SUBSAMPLING), G_TYPE_UINT,
      self->horizontal_subsampling, NULL);

  if (self->vertical_subsampling != 0)
    gst_structure_id_set (ret, MXF_QUARK (VERTICAL_SUBSAMPLING), G_TYPE_UINT,
        self->vertical_subsampling, NULL);

  if (self->color_siting != 255)
    gst_structure_id_set (ret, MXF_QUARK (COLOR_SITING), G_TYPE_UCHAR,
        self->color_siting, NULL);

  gst_structure_id_set (ret, MXF_QUARK (REVERSED_BYTE_ORDER), G_TYPE_BOOLEAN,
      self->reversed_byte_order, NULL);

  if (self->padding_bits != 0)
    gst_structure_id_set (ret, MXF_QUARK (PADDING_BITS), G_TYPE_INT,
        self->padding_bits, NULL);

  if (self->alpha_sample_depth != 0)
    gst_structure_id_set (ret, MXF_QUARK (ALPHA_SAMPLE_DEPTH), G_TYPE_UINT,
        self->alpha_sample_depth, NULL);

  if (self->black_ref_level != 0)
    gst_structure_id_set (ret, MXF_QUARK (BLACK_REF_LEVEL), G_TYPE_UINT,
        self->black_ref_level, NULL);

  if (self->white_ref_level != 0)
    gst_structure_id_set (ret, MXF_QUARK (WHITE_REF_LEVEL), G_TYPE_UINT,
        self->white_ref_level, NULL);

  if (self->color_range != 0)
    gst_structure_id_set (ret, MXF_QUARK (COLOR_RANGE), G_TYPE_UINT,
        self->color_range, NULL);

  return ret;
}

static GList *
mxf_metadata_cdci_picture_essence_descriptor_write_tags (MXFMetadataBase * m,
    MXFPrimerPack * primer)
{
  MXFMetadataCDCIPictureEssenceDescriptor *self =
      MXF_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_cdci_picture_essence_descriptor_parent_class)->write_tags
      (m, primer);
  MXFLocalTag *t;

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (COMPONENT_DEPTH), 16);
  t->size = 4;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT32_BE (t->data, self->component_depth);
  mxf_primer_pack_add_mapping (primer, 0x3301, &t->ul);
  ret = g_list_prepend (ret, t);

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (HORIZONTAL_SUBSAMPLING), 16);
  t->size = 4;
  t->data = g_slice_alloc (t->size);
  t->g_slice = TRUE;
  GST_WRITE_UINT32_BE (t->data, self->horizontal_subsampling);
  mxf_primer_pack_add_mapping (primer, 0x3302, &t->ul);
  ret = g_list_prepend (ret, t);

  if (self->vertical_subsampling) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (VERTICAL_SUBSAMPLING), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->vertical_subsampling);
    mxf_primer_pack_add_mapping (primer, 0x3308, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->color_siting != 0xff) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (COLOR_SITING), 16);
    t->size = 1;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT8 (t->data, self->color_siting);
    mxf_primer_pack_add_mapping (primer, 0x3303, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->reversed_byte_order) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (REVERSED_BYTE_ORDER), 16);
    t->size = 1;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT8 (t->data, (self->reversed_byte_order) ? 1 : 0);
    mxf_primer_pack_add_mapping (primer, 0x330b, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->padding_bits) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (PADDING_BITS), 16);
    t->size = 2;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT16_BE (t->data, self->padding_bits);
    mxf_primer_pack_add_mapping (primer, 0x3307, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->alpha_sample_depth) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (ALPHA_SAMPLE_DEPTH), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->alpha_sample_depth);
    mxf_primer_pack_add_mapping (primer, 0x3309, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->black_ref_level) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (BLACK_REF_LEVEL), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->black_ref_level);
    mxf_primer_pack_add_mapping (primer, 0x3304, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->white_ref_level) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (WHITE_REF_LEVEL), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->white_ref_level);
    mxf_primer_pack_add_mapping (primer, 0x3305, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->color_range) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (COLOR_RANGE), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->color_range);
    mxf_primer_pack_add_mapping (primer, 0x3306, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  return ret;
}

static void
    mxf_metadata_cdci_picture_essence_descriptor_init
    (MXFMetadataCDCIPictureEssenceDescriptor * self)
{
  self->color_siting = 0xff;
}

static void
    mxf_metadata_cdci_picture_essence_descriptor_class_init
    (MXFMetadataCDCIPictureEssenceDescriptorClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  metadata_base_class->handle_tag =
      mxf_metadata_cdci_picture_essence_descriptor_handle_tag;
  metadata_base_class->name_quark = MXF_QUARK (CDCI_PICTURE_ESSENCE_DESCRIPTOR);
  metadata_base_class->to_structure =
      mxf_metadata_cdci_picture_essence_descriptor_to_structure;
  metadata_base_class->write_tags =
      mxf_metadata_cdci_picture_essence_descriptor_write_tags;
  metadata_class->type = 0x0128;
}

G_DEFINE_TYPE (MXFMetadataRGBAPictureEssenceDescriptor,
    mxf_metadata_rgba_picture_essence_descriptor,
    MXF_TYPE_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR);

static void
mxf_metadata_rgba_picture_essence_descriptor_finalize (GObject * object)
{
  MXFMetadataRGBAPictureEssenceDescriptor *self =
      MXF_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (object);

  g_free (self->pixel_layout);
  self->pixel_layout = NULL;

  G_OBJECT_CLASS
      (mxf_metadata_rgba_picture_essence_descriptor_parent_class)->finalize
      (object);
}

static gboolean
mxf_metadata_rgba_picture_essence_descriptor_handle_tag (MXFMetadataBase *
    metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataRGBAPictureEssenceDescriptor *self =
      MXF_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (metadata);
  gboolean ret = TRUE;

  switch (tag) {
    case 0x3406:
      if (tag_size != 4)
        goto error;
      self->component_max_ref = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  component max ref = %u", self->component_max_ref);
      break;
    case 0x3407:
      if (tag_size != 4)
        goto error;
      self->component_min_ref = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  component min ref = %u", self->component_min_ref);
      break;
    case 0x3408:
      if (tag_size != 4)
        goto error;
      self->alpha_max_ref = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  alpha max ref = %u", self->alpha_max_ref);
      break;
    case 0x3409:
      if (tag_size != 4)
        goto error;
      self->alpha_min_ref = GST_READ_UINT32_BE (tag_data);
      GST_DEBUG ("  alpha min ref = %u", self->alpha_min_ref);
      break;
    case 0x3405:
      if (tag_size != 1)
        goto error;
      self->scanning_direction = GST_READ_UINT8 (tag_data);
      GST_DEBUG ("  scanning direction = %u", self->scanning_direction);
      break;
    case 0x3401:{
      guint i, len;

      if (tag_size % 2 != 0 || tag_size > 16)
        goto error;

      i = 0;
      while (tag_data[i] != 0 && tag_data[i + 1] != 0 && i + 2 <= tag_size)
        i += 2;
      len = i / 2;

      self->n_pixel_layout = len;
      GST_DEBUG ("  number of pixel layouts = %u", len);
      if (len == 0)
        return TRUE;

      self->pixel_layout = g_malloc0 (16);

      for (i = 0; i < len; i++) {
        self->pixel_layout[2 * i] = tag_data[2 * i];
        self->pixel_layout[2 * i + 1] = tag_data[2 * i + 1];
        GST_DEBUG ("    pixel layout %u = %c : %u", i,
            (gchar) self->pixel_layout[2 * i], self->pixel_layout[2 * i + 1]);
      }

      break;
    }
    case 0x3403:
    case 0x3404:
      /* TODO: handle this */
      GST_WARNING ("  tag 0x%04x not implemented yet", tag);
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_rgba_picture_essence_descriptor_parent_class)->handle_tag
          (metadata, primer, tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR
      ("Invalid RGBA picture essence descriptor local tag 0x%04x of size %u",
      tag, tag_size);

  return FALSE;
}

static GstStructure *
mxf_metadata_rgba_picture_essence_descriptor_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_rgba_picture_essence_descriptor_parent_class)->to_structure
      (m);
  MXFMetadataRGBAPictureEssenceDescriptor *self =
      MXF_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (m);

  if (self->component_max_ref != 255)
    gst_structure_id_set (ret, MXF_QUARK (COMPONENT_MAX_REF), G_TYPE_UINT,
        self->component_max_ref, NULL);

  if (self->component_min_ref != 0)
    gst_structure_id_set (ret, MXF_QUARK (COMPONENT_MIN_REF), G_TYPE_UINT,
        self->component_min_ref, NULL);

  if (self->alpha_max_ref != 255)
    gst_structure_id_set (ret, MXF_QUARK (ALPHA_MAX_REF), G_TYPE_UINT,
        self->alpha_max_ref, NULL);

  if (self->alpha_min_ref != 0)
    gst_structure_id_set (ret, MXF_QUARK (ALPHA_MIN_REF), G_TYPE_UINT,
        self->alpha_min_ref, NULL);

  if (self->scanning_direction != 0)
    gst_structure_id_set (ret, MXF_QUARK (SCANNING_DIRECTION), G_TYPE_UCHAR,
        self->scanning_direction, NULL);

  if (self->n_pixel_layout != 0) {
    gchar *pl = g_new0 (gchar, self->n_pixel_layout * 2 + 1);

    memcpy (pl, self->pixel_layout, self->n_pixel_layout * 2);

    gst_structure_id_set (ret, MXF_QUARK (PIXEL_LAYOUT), G_TYPE_STRING, pl,
        NULL);

    g_free (pl);
  }

  return ret;
}

static GList *
mxf_metadata_rgba_picture_essence_descriptor_write_tags (MXFMetadataBase * m,
    MXFPrimerPack * primer)
{
  MXFMetadataRGBAPictureEssenceDescriptor *self =
      MXF_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_rgba_picture_essence_descriptor_parent_class)->write_tags
      (m, primer);
  MXFLocalTag *t;

  if (self->component_max_ref != 255) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (COMPONENT_MAX_REF), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->component_max_ref);
    mxf_primer_pack_add_mapping (primer, 0x3406, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->component_min_ref) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (COMPONENT_MIN_REF), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->component_min_ref);
    mxf_primer_pack_add_mapping (primer, 0x3407, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->alpha_max_ref != 255) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (ALPHA_MAX_REF), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->alpha_max_ref);
    mxf_primer_pack_add_mapping (primer, 0x3408, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->alpha_min_ref) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (ALPHA_MIN_REF), 16);
    t->size = 4;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->alpha_min_ref);
    mxf_primer_pack_add_mapping (primer, 0x3409, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  if (self->scanning_direction) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (SCANNING_DIRECTION), 16);
    t->size = 1;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT8 (t->data, self->scanning_direction);
    mxf_primer_pack_add_mapping (primer, 0x3405, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  t = g_slice_new0 (MXFLocalTag);
  memcpy (&t->ul, MXF_UL (PIXEL_LAYOUT), 16);
  t->size = 16;
  t->data = g_slice_alloc0 (t->size);
  t->g_slice = TRUE;
  if (self->pixel_layout)
    memcpy (t->data, self->pixel_layout, self->n_pixel_layout * 2);
  mxf_primer_pack_add_mapping (primer, 0x3401, &t->ul);
  ret = g_list_prepend (ret, t);

  return ret;
}

static void
    mxf_metadata_rgba_picture_essence_descriptor_init
    (MXFMetadataRGBAPictureEssenceDescriptor * self)
{
  self->component_max_ref = 255;
  self->alpha_max_ref = 255;
}

static void
    mxf_metadata_rgba_picture_essence_descriptor_class_init
    (MXFMetadataRGBAPictureEssenceDescriptorClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  GObjectClass *object_class = (GObjectClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  object_class->finalize =
      mxf_metadata_rgba_picture_essence_descriptor_finalize;
  metadata_base_class->handle_tag =
      mxf_metadata_rgba_picture_essence_descriptor_handle_tag;
  metadata_base_class->name_quark = MXF_QUARK (RGBA_PICTURE_ESSENCE_DESCRIPTOR);
  metadata_base_class->to_structure =
      mxf_metadata_rgba_picture_essence_descriptor_to_structure;
  metadata_base_class->write_tags =
      mxf_metadata_rgba_picture_essence_descriptor_write_tags;
  metadata_class->type = 0x0129;
}

G_DEFINE_TYPE (MXFMetadataGenericDataEssenceDescriptor,
    mxf_metadata_generic_data_essence_descriptor,
    MXF_TYPE_METADATA_FILE_DESCRIPTOR);

static gboolean
mxf_metadata_generic_data_essence_descriptor_handle_tag (MXFMetadataBase *
    metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataGenericDataEssenceDescriptor *self =
      MXF_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR (metadata);
  gboolean ret = TRUE;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  switch (tag) {
    case 0x3e01:
      if (tag_size != 16)
        goto error;
      memcpy (&self->data_essence_coding, tag_data, 16);
      GST_DEBUG ("  data essence coding = %s",
          mxf_ul_to_string (&self->data_essence_coding, str));
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_generic_data_essence_descriptor_parent_class)->handle_tag
          (metadata, primer, tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR
      ("Invalid generic data essence descriptor local tag 0x%04x of size %u",
      tag, tag_size);

  return FALSE;
}

static GstStructure *
mxf_metadata_generic_data_essence_descriptor_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_generic_data_essence_descriptor_parent_class)->to_structure
      (m);
  MXFMetadataGenericDataEssenceDescriptor *self =
      MXF_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR (m);
  gchar str[48];

  if (!mxf_ul_is_zero (&self->data_essence_coding)) {
    mxf_ul_to_string (&self->data_essence_coding, str);
    gst_structure_id_set (ret, MXF_QUARK (DATA_ESSENCE_CODING), G_TYPE_STRING,
        str, NULL);
  }

  return ret;
}

static GList *
mxf_metadata_generic_data_essence_descriptor_write_tags (MXFMetadataBase * m,
    MXFPrimerPack * primer)
{
  MXFMetadataGenericDataEssenceDescriptor *self =
      MXF_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_generic_data_essence_descriptor_parent_class)->write_tags
      (m, primer);
  MXFLocalTag *t;

  if (!mxf_ul_is_zero (&self->data_essence_coding)) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (DATA_ESSENCE_CODING), 16);
    t->size = 16;
    t->data = g_slice_alloc (t->size);
    t->g_slice = TRUE;
    memcpy (t->data, &self->data_essence_coding, 16);
    mxf_primer_pack_add_mapping (primer, 0x3e01, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  return ret;
}

static void
    mxf_metadata_generic_data_essence_descriptor_init
    (MXFMetadataGenericDataEssenceDescriptor * self)
{

}

static void
    mxf_metadata_generic_data_essence_descriptor_class_init
    (MXFMetadataGenericDataEssenceDescriptorClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  metadata_base_class->handle_tag =
      mxf_metadata_generic_data_essence_descriptor_handle_tag;
  metadata_base_class->name_quark = MXF_QUARK (GENERIC_DATA_ESSENCE_DESCRIPTOR);
  metadata_base_class->to_structure =
      mxf_metadata_generic_data_essence_descriptor_to_structure;
  metadata_base_class->write_tags =
      mxf_metadata_generic_data_essence_descriptor_write_tags;
  metadata_class->type = 0x0143;
}

G_DEFINE_TYPE (MXFMetadataMultipleDescriptor, mxf_metadata_multiple_descriptor,
    MXF_TYPE_METADATA_FILE_DESCRIPTOR);

static void
mxf_metadata_multiple_descriptor_finalize (GObject * object)
{
  MXFMetadataMultipleDescriptor *self =
      MXF_METADATA_MULTIPLE_DESCRIPTOR (object);

  g_free (self->sub_descriptors_uids);
  self->sub_descriptors_uids = NULL;
  g_free (self->sub_descriptors);
  self->sub_descriptors = NULL;

  G_OBJECT_CLASS
      (mxf_metadata_multiple_descriptor_parent_class)->finalize (object);
}

static gboolean
mxf_metadata_multiple_descriptor_handle_tag (MXFMetadataBase * metadata,
    MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataMultipleDescriptor *self =
      MXF_METADATA_MULTIPLE_DESCRIPTOR (metadata);
  gboolean ret = TRUE;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  switch (tag) {
    case 0x3f01:
      if (!mxf_uuid_array_parse (&self->sub_descriptors_uids,
              &self->n_sub_descriptors, tag_data, tag_size))
        goto error;

      GST_DEBUG ("  number of sub descriptors = %u", self->n_sub_descriptors);
#ifndef GST_DISABLE_GST_DEBUG
      {
        guint i;
        for (i = 0; i < self->n_sub_descriptors; i++) {
          GST_DEBUG ("    sub descriptor %u = %s", i,
              mxf_uuid_to_string (&self->sub_descriptors_uids[i], str));
        }
      }
#endif

      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_multiple_descriptor_parent_class)->handle_tag (metadata,
          primer, tag, tag_data, tag_size);
      break;
  }

  return ret;

error:

  GST_ERROR ("Invalid multiple descriptor local tag 0x%04x of size %u", tag,
      tag_size);

  return FALSE;
}

static gboolean
mxf_metadata_multiple_descriptor_resolve (MXFMetadataBase * m,
    GHashTable * metadata)
{
  MXFMetadataMultipleDescriptor *self = MXF_METADATA_MULTIPLE_DESCRIPTOR (m);
  MXFMetadataBase *current = NULL;
  guint i, have_subdescriptors = 0;
#ifndef GST_DISABLE_GST_DEBUG
  gchar str[48];
#endif

  if (self->sub_descriptors)
    memset (self->sub_descriptors, 0,
        sizeof (gpointer) * self->n_sub_descriptors);
  else
    self->sub_descriptors =
        g_new0 (MXFMetadataGenericDescriptor *, self->n_sub_descriptors);
  for (i = 0; i < self->n_sub_descriptors; i++) {
    current = g_hash_table_lookup (metadata, &self->sub_descriptors_uids[i]);
    if (current && MXF_IS_METADATA_GENERIC_DESCRIPTOR (current)) {
      if (mxf_metadata_base_resolve (current, metadata)) {
        self->sub_descriptors[i] = MXF_METADATA_GENERIC_DESCRIPTOR (current);
        have_subdescriptors++;
      } else {
        GST_ERROR ("Couldn't resolve descriptor %s",
            mxf_uuid_to_string (&self->sub_descriptors_uids[i], str));
        return FALSE;
      }
    } else {
      GST_ERROR ("Descriptor %s not found",
          mxf_uuid_to_string (&self->sub_descriptors_uids[i], str));
    }
  }

  return
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_multiple_descriptor_parent_class)->resolve (m, metadata);
}

static GstStructure *
mxf_metadata_multiple_descriptor_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_multiple_descriptor_parent_class)->to_structure (m);
  MXFMetadataMultipleDescriptor *self = MXF_METADATA_MULTIPLE_DESCRIPTOR (m);
  guint i;

  if (self->n_sub_descriptors > 0) {
    GValue arr = { 0, }
    , val = {
    0,};

    g_value_init (&arr, GST_TYPE_ARRAY);

    for (i = 0; i < self->n_sub_descriptors; i++) {
      GstStructure *s;

      if (self->sub_descriptors[i] == NULL)
        continue;

      g_value_init (&val, GST_TYPE_STRUCTURE);

      s = mxf_metadata_base_to_structure (MXF_METADATA_BASE
          (self->sub_descriptors[i]));
      gst_value_set_structure (&val, s);
      gst_structure_free (s);
      gst_value_array_append_value (&arr, &val);
      g_value_unset (&val);
    }

    if (gst_value_array_get_size (&arr) > 0)
      gst_structure_id_set_value (ret, MXF_QUARK (SUB_DESCRIPTORS), &arr);

    g_value_unset (&arr);
  }

  return ret;
}

static GList *
mxf_metadata_multiple_descriptor_write_tags (MXFMetadataBase * m,
    MXFPrimerPack * primer)
{
  MXFMetadataMultipleDescriptor *self = MXF_METADATA_MULTIPLE_DESCRIPTOR (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_multiple_descriptor_parent_class)->write_tags (m, primer);
  MXFLocalTag *t;

  if (self->sub_descriptors) {
    guint i;

    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (SUB_DESCRIPTORS), 16);
    t->size = 8 + 16 * self->n_sub_descriptors;
    t->data = g_slice_alloc0 (t->size);
    t->g_slice = TRUE;
    GST_WRITE_UINT32_BE (t->data, self->n_sub_descriptors);
    GST_WRITE_UINT32_BE (t->data + 4, 16);
    for (i = 0; i < self->n_sub_descriptors; i++) {
      if (!self->sub_descriptors[i])
        continue;

      memcpy (t->data + 8 + 16 * i,
          &MXF_METADATA_BASE (self->sub_descriptors[i])->instance_uid, 16);
    }
    mxf_primer_pack_add_mapping (primer, 0x3f01, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  return ret;
}

static void
mxf_metadata_multiple_descriptor_init (MXFMetadataMultipleDescriptor * self)
{

}

static void
mxf_metadata_multiple_descriptor_class_init (MXFMetadataMultipleDescriptorClass
    * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  GObjectClass *object_class = (GObjectClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  object_class->finalize = mxf_metadata_multiple_descriptor_finalize;
  metadata_base_class->handle_tag = mxf_metadata_multiple_descriptor_handle_tag;
  metadata_base_class->resolve = mxf_metadata_multiple_descriptor_resolve;
  metadata_base_class->name_quark = MXF_QUARK (MULTIPLE_DESCRIPTOR);
  metadata_base_class->to_structure =
      mxf_metadata_multiple_descriptor_to_structure;
  metadata_base_class->write_tags = mxf_metadata_multiple_descriptor_write_tags;
  metadata_class->type = 0x0144;
}

G_DEFINE_ABSTRACT_TYPE (MXFMetadataLocator, mxf_metadata_locator,
    MXF_TYPE_METADATA);

static void
mxf_metadata_locator_init (MXFMetadataLocator * self)
{
}

static void
mxf_metadata_locator_class_init (MXFMetadataLocatorClass * klass)
{
}

G_DEFINE_TYPE (MXFMetadataTextLocator, mxf_metadata_text_locator,
    MXF_TYPE_METADATA_LOCATOR);

static void
mxf_metadata_text_locator_finalize (GObject * object)
{
  MXFMetadataTextLocator *self = MXF_METADATA_TEXT_LOCATOR (object);

  g_free (self->locator_name);
  self->locator_name = NULL;

  G_OBJECT_CLASS (mxf_metadata_text_locator_parent_class)->finalize (object);
}

static gboolean
mxf_metadata_text_locator_handle_tag (MXFMetadataBase * metadata,
    MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataTextLocator *self = MXF_METADATA_TEXT_LOCATOR (metadata);
  gboolean ret = TRUE;

  switch (tag) {
    case 0x4101:
      self->locator_name = mxf_utf16_to_utf8 (tag_data, tag_size);
      GST_DEBUG ("  text locator = %s", GST_STR_NULL (self->locator_name));
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_text_locator_parent_class)->handle_tag (metadata,
          primer, tag, tag_data, tag_size);
      break;
  }

  return ret;
}

static GstStructure *
mxf_metadata_text_locator_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_text_locator_parent_class)->to_structure (m);
  MXFMetadataTextLocator *self = MXF_METADATA_TEXT_LOCATOR (m);

  gst_structure_id_set (ret, MXF_QUARK (LOCATOR_NAME), G_TYPE_STRING,
      self->locator_name, NULL);

  return ret;
}

static GList *
mxf_metadata_text_locator_write_tags (MXFMetadataBase * m,
    MXFPrimerPack * primer)
{
  MXFMetadataTextLocator *self = MXF_METADATA_TEXT_LOCATOR (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_text_locator_parent_class)->write_tags (m, primer);
  MXFLocalTag *t;

  if (self->locator_name) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (LOCATOR_NAME), 16);
    t->data = mxf_utf8_to_utf16 (self->locator_name, &t->size);
    mxf_primer_pack_add_mapping (primer, 0x4101, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  return ret;
}

static void
mxf_metadata_text_locator_init (MXFMetadataTextLocator * self)
{

}

static void
mxf_metadata_text_locator_class_init (MXFMetadataTextLocatorClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  GObjectClass *object_class = (GObjectClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  object_class->finalize = mxf_metadata_text_locator_finalize;
  metadata_base_class->handle_tag = mxf_metadata_text_locator_handle_tag;
  metadata_base_class->name_quark = MXF_QUARK (TEXT_LOCATOR);
  metadata_base_class->to_structure = mxf_metadata_text_locator_to_structure;
  metadata_base_class->write_tags = mxf_metadata_text_locator_write_tags;
  metadata_class->type = 0x0133;
}

G_DEFINE_TYPE (MXFMetadataNetworkLocator, mxf_metadata_network_locator,
    MXF_TYPE_METADATA_LOCATOR);

static void
mxf_metadata_network_locator_finalize (GObject * object)
{
  MXFMetadataNetworkLocator *self = MXF_METADATA_NETWORK_LOCATOR (object);

  g_free (self->url_string);
  self->url_string = NULL;

  G_OBJECT_CLASS (mxf_metadata_network_locator_parent_class)->finalize (object);
}

static gboolean
mxf_metadata_network_locator_handle_tag (MXFMetadataBase * metadata,
    MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
    guint tag_size)
{
  MXFMetadataNetworkLocator *self = MXF_METADATA_NETWORK_LOCATOR (metadata);
  gboolean ret = TRUE;

  switch (tag) {
    case 0x4101:
      self->url_string = mxf_utf16_to_utf8 (tag_data, tag_size);
      GST_DEBUG ("  url string = %s", GST_STR_NULL (self->url_string));
      break;
    default:
      ret =
          MXF_METADATA_BASE_CLASS
          (mxf_metadata_network_locator_parent_class)->handle_tag (metadata,
          primer, tag, tag_data, tag_size);
      break;
  }

  return ret;
}

static GstStructure *
mxf_metadata_network_locator_to_structure (MXFMetadataBase * m)
{
  GstStructure *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_network_locator_parent_class)->to_structure (m);
  MXFMetadataNetworkLocator *self = MXF_METADATA_NETWORK_LOCATOR (m);

  gst_structure_id_set (ret, MXF_QUARK (URL_STRING), G_TYPE_STRING,
      self->url_string, NULL);

  return ret;
}

static GList *
mxf_metadata_network_locator_write_tags (MXFMetadataBase * m,
    MXFPrimerPack * primer)
{
  MXFMetadataNetworkLocator *self = MXF_METADATA_NETWORK_LOCATOR (m);
  GList *ret =
      MXF_METADATA_BASE_CLASS
      (mxf_metadata_network_locator_parent_class)->write_tags (m, primer);
  MXFLocalTag *t;

  if (self->url_string) {
    t = g_slice_new0 (MXFLocalTag);
    memcpy (&t->ul, MXF_UL (URL_STRING), 16);
    t->data = mxf_utf8_to_utf16 (self->url_string, &t->size);
    mxf_primer_pack_add_mapping (primer, 0x4001, &t->ul);
    ret = g_list_prepend (ret, t);
  }

  return ret;
}

static void
mxf_metadata_network_locator_init (MXFMetadataNetworkLocator * self)
{
}

static void
mxf_metadata_network_locator_class_init (MXFMetadataNetworkLocatorClass * klass)
{
  MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
  GObjectClass *object_class = (GObjectClass *) klass;
  MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;

  object_class->finalize = mxf_metadata_network_locator_finalize;
  metadata_base_class->handle_tag = mxf_metadata_network_locator_handle_tag;
  metadata_base_class->name_quark = MXF_QUARK (NETWORK_LOCATOR);
  metadata_base_class->to_structure = mxf_metadata_network_locator_to_structure;
  metadata_base_class->write_tags = mxf_metadata_network_locator_write_tags;
  metadata_class->type = 0x0133;
}

G_DEFINE_ABSTRACT_TYPE (MXFDescriptiveMetadata, mxf_descriptive_metadata,
    MXF_TYPE_METADATA_BASE);

static void
mxf_descriptive_metadata_init (MXFDescriptiveMetadata * self)
{
}

static void
mxf_descriptive_metadata_class_init (MXFDescriptiveMetadataClass * klass)
{
}

typedef struct
{
  guint8 scheme;
  GType *types;
} _MXFDescriptiveMetadataScheme;

static GArray *_dm_schemes = NULL;

void
mxf_descriptive_metadata_register (guint8 scheme, GType * types)
{
  _MXFDescriptiveMetadataScheme s;

  if (!_dm_schemes)
    _dm_schemes =
        g_array_new (FALSE, TRUE, sizeof (_MXFDescriptiveMetadataScheme));

  s.scheme = scheme;
  s.types = types;

  g_array_append_val (_dm_schemes, s);
}

MXFDescriptiveMetadata *
mxf_descriptive_metadata_new (guint8 scheme, guint32 type,
    MXFPrimerPack * primer, guint64 offset, const guint8 * data, guint size)
{
  guint i;
  GType t = G_TYPE_INVALID, *p;
  _MXFDescriptiveMetadataScheme *s = NULL;
  MXFDescriptiveMetadata *ret = NULL;

  g_return_val_if_fail (primer != NULL, NULL);

  if (G_UNLIKELY (type == 0)) {
    GST_WARNING ("Type 0 is invalid");
    return NULL;
  }

  for (i = 0; i < _dm_schemes->len; i++) {
    _MXFDescriptiveMetadataScheme *data =
        &g_array_index (_dm_schemes, _MXFDescriptiveMetadataScheme, i);

    if (data->scheme == scheme) {
      s = data;
      break;
    }
  }

  if (s == NULL) {
    GST_WARNING ("Descriptive metadata scheme 0x%02x not supported", scheme);
    return NULL;
  }

  p = s->types;
  while (*p) {
    GType tmp = *p;
    MXFDescriptiveMetadataClass *klass =
        MXF_DESCRIPTIVE_METADATA_CLASS (g_type_class_ref (tmp));

    if (klass->type == type) {
      g_type_class_unref (klass);
      t = tmp;
      break;
    }
    g_type_class_unref (klass);
    p++;
  }

  if (t == G_TYPE_INVALID) {
    GST_WARNING
        ("No handler for type 0x%06x of descriptive metadata scheme 0x%02x found",
        type, scheme);
    return NULL;
  }

  GST_DEBUG ("DM scheme 0x%02x type 0x%06x is handled by type %s", scheme, type,
      g_type_name (t));

  ret = (MXFDescriptiveMetadata *) g_type_create_instance (t);
  if (!mxf_metadata_base_parse (MXF_METADATA_BASE (ret), primer, data, size)) {
    GST_ERROR ("Parsing metadata failed");
    g_object_unref (ret);
    return NULL;
  }

  ret->parent.offset = offset;

  return ret;
}

GType
mxf_descriptive_metadata_framework_get_type (void)
{
  static volatile gsize type = 0;
  if (g_once_init_enter (&type)) {
    GType _type = 0;
    static const GTypeInfo info = {
      sizeof (MXFDescriptiveMetadataFrameworkInterface),
      NULL,                     /* base_init */
      NULL,                     /* base_finalize */
      NULL,                     /* class_init */
      NULL,                     /* class_finalize */
      NULL,                     /* class_data */
      0,                        /* instance_size */
      0,                        /* n_preallocs */
      NULL                      /* instance_init */
    };
    _type = g_type_register_static (G_TYPE_INTERFACE,
        "MXFDescriptiveMetadataFrameworkInterface", &info, 0);

    g_type_interface_add_prerequisite (_type, MXF_TYPE_DESCRIPTIVE_METADATA);

    g_once_init_leave (&type, (gsize) _type);
  }

  return (GType) type;
}

GHashTable *
mxf_metadata_hash_table_new (void)
{
  return g_hash_table_new_full ((GHashFunc) mxf_uuid_hash,
      (GEqualFunc) mxf_uuid_is_equal, (GDestroyNotify) NULL,
      (GDestroyNotify) g_object_unref);
}
