gst/mxf/: Rewrite parsing of descriptors to go top-down instead of bottom-up which...
authorSebastian Dröge <slomo@circular-chaos.org>
Tue, 25 Nov 2008 09:38:26 +0000 (09:38 +0000)
committerSebastian Dröge <slomo@circular-chaos.org>
Tue, 25 Nov 2008 09:38:26 +0000 (09:38 +0000)
Original commit message from CVS:
* gst/mxf/mxfaes-bwf.c:
(mxf_metadata_wave_audio_essence_descriptor_handle_tag):
* gst/mxf/mxfaes-bwf.h:
* gst/mxf/mxfdemux.c:
(gst_mxf_demux_handle_metadata_generic_descriptor),
(gst_mxf_demux_handle_metadata_file_descriptor),
(gst_mxf_demux_handle_metadata_multiple_descriptor),
(gst_mxf_demux_handle_metadata_generic_picture_essence_descriptor),
(gst_mxf_demux_handle_metadata_cdci_picture_essence_descriptor),
(gst_mxf_demux_handle_metadata_mpeg_video_descriptor),
(gst_mxf_demux_handle_metadata_generic_sound_essence_descriptor),
(gst_mxf_demux_handle_metadata_wave_audio_essence_descriptor),
(gst_mxf_demux_handle_header_metadata_resolve_references),
(gst_mxf_demux_handle_metadata):
* gst/mxf/mxfmpeg.c:
(mxf_metadata_mpeg_video_descriptor_handle_tag):
* gst/mxf/mxfmpeg.h:
* gst/mxf/mxfparse.c: (mxf_partition_pack_parse),
(mxf_primer_pack_parse), (mxf_metadata_preface_parse),
(mxf_metadata_identification_parse),
(mxf_metadata_content_storage_parse),
(mxf_metadata_essence_container_data_parse),
(mxf_metadata_generic_package_parse), (mxf_metadata_track_parse),
(mxf_metadata_sequence_parse),
(mxf_metadata_structural_component_parse),
(mxf_metadata_descriptor_parse),
(mxf_metadata_generic_descriptor_handle_tag),
(mxf_metadata_generic_descriptor_reset),
(mxf_metadata_file_descriptor_handle_tag),
(mxf_metadata_generic_sound_essence_descriptor_handle_tag),
(mxf_metadata_generic_picture_essence_descriptor_handle_tag),
(mxf_metadata_cdci_picture_essence_descriptor_handle_tag),
(mxf_metadata_multiple_descriptor_handle_tag),
(mxf_metadata_locator_parse):
* gst/mxf/mxfparse.h:
Rewrite parsing of descriptors to go top-down instead of bottom-up
which makes it possible to have the buffer data non-writable.
Improve debugging a bit.

ChangeLog
gst/mxf/mxfaes-bwf.c
gst/mxf/mxfaes-bwf.h
gst/mxf/mxfdemux.c
gst/mxf/mxfmpeg.c
gst/mxf/mxfmpeg.h
gst/mxf/mxfparse.c
gst/mxf/mxfparse.h

index f895365c5f6e07bae6cb3b8650f6b16c6913de6f..9e485493473006c7c50d122bd803b2270b95b4b1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,45 @@
+2008-11-25  Sebastian Dröge  <sebastian.droege@collabora.co.uk>
+
+       * gst/mxf/mxfaes-bwf.c:
+       (mxf_metadata_wave_audio_essence_descriptor_handle_tag):
+       * gst/mxf/mxfaes-bwf.h:
+       * gst/mxf/mxfdemux.c:
+       (gst_mxf_demux_handle_metadata_generic_descriptor),
+       (gst_mxf_demux_handle_metadata_file_descriptor),
+       (gst_mxf_demux_handle_metadata_multiple_descriptor),
+       (gst_mxf_demux_handle_metadata_generic_picture_essence_descriptor),
+       (gst_mxf_demux_handle_metadata_cdci_picture_essence_descriptor),
+       (gst_mxf_demux_handle_metadata_mpeg_video_descriptor),
+       (gst_mxf_demux_handle_metadata_generic_sound_essence_descriptor),
+       (gst_mxf_demux_handle_metadata_wave_audio_essence_descriptor),
+       (gst_mxf_demux_handle_header_metadata_resolve_references),
+       (gst_mxf_demux_handle_metadata):
+       * gst/mxf/mxfmpeg.c:
+       (mxf_metadata_mpeg_video_descriptor_handle_tag):
+       * gst/mxf/mxfmpeg.h:
+       * gst/mxf/mxfparse.c: (mxf_partition_pack_parse),
+       (mxf_primer_pack_parse), (mxf_metadata_preface_parse),
+       (mxf_metadata_identification_parse),
+       (mxf_metadata_content_storage_parse),
+       (mxf_metadata_essence_container_data_parse),
+       (mxf_metadata_generic_package_parse), (mxf_metadata_track_parse),
+       (mxf_metadata_sequence_parse),
+       (mxf_metadata_structural_component_parse),
+       (mxf_metadata_descriptor_parse),
+       (mxf_metadata_generic_descriptor_handle_tag),
+       (mxf_metadata_generic_descriptor_reset),
+       (mxf_metadata_file_descriptor_handle_tag),
+       (mxf_metadata_generic_sound_essence_descriptor_handle_tag),
+       (mxf_metadata_generic_picture_essence_descriptor_handle_tag),
+       (mxf_metadata_cdci_picture_essence_descriptor_handle_tag),
+       (mxf_metadata_multiple_descriptor_handle_tag),
+       (mxf_metadata_locator_parse):
+       * gst/mxf/mxfparse.h:
+       Rewrite parsing of descriptors to go top-down instead of bottom-up
+       which makes it possible to have the buffer data non-writable.
+
+       Improve debugging a bit.
+
 2008-11-24  Michael Smith <msmith@songbirdnest.com>
 
        * configure.ac:
index 0877204ff1082d8da8fa6bc237070a0fb973a540..7e7ddf90edf73331eb17693b7121ad22312d2ce9 100644 (file)
@@ -41,154 +41,134 @@ GST_DEBUG_CATEGORY_EXTERN (mxf_debug);
 
 /* SMPTE 382M Annex 1 */
 gboolean
-mxf_metadata_wave_audio_essence_descriptor_parse (const MXFUL * key,
-    MXFMetadataWaveAudioEssenceDescriptor * descriptor,
-    const MXFPrimerPack * primer, guint16 type, const guint8 * data, guint size)
+    mxf_metadata_wave_audio_essence_descriptor_handle_tag
+    (MXFMetadataGenericDescriptor * d, const MXFPrimerPack * primer,
+    guint16 tag, const guint8 * tag_data, guint16 tag_size)
 {
-  guint16 tag, tag_size;
-  const guint8 *tag_data;
+  MXFMetadataWaveAudioEssenceDescriptor *descriptor =
+      (MXFMetadataWaveAudioEssenceDescriptor *) d;
+  gboolean ret = FALSE;
   gchar str[48];
 
-  g_return_val_if_fail (data != NULL, FALSE);
-
-  memset (descriptor, 0, sizeof (MXFMetadataWaveAudioEssenceDescriptor));
-
-  if (!mxf_metadata_generic_sound_essence_descriptor_parse (key,
-          (MXFMetadataGenericSoundEssenceDescriptor *) descriptor, primer, type,
-          data, size))
-    goto error;
-
-  while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
-    if (tag_size == 0 || tag == 0x0000)
-      goto next;
-
-    switch (tag) {
-      case 0x3d0a:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 2)
-          goto error;
-        descriptor->block_align = GST_READ_UINT16_BE (tag_data);
-        break;
-      case 0x3d0b:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 1)
-          goto error;
-        descriptor->sequence_offset = GST_READ_UINT8 (tag_data);
-        break;
-      case 0x3d09:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->avg_bps = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3d32:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 16)
-          goto error;
-        memcpy (&descriptor->channel_assignment, tag_data, 16);
-        break;
-      case 0x3d29:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->peak_envelope_version = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3d2a:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->peak_envelope_format = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3d2b:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->points_per_peak_value = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3d2c:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->peak_envelope_block_size = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3d2d:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->peak_channels = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3d2e:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->peak_frames = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3d2f:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 8)
-          goto error;
-        descriptor->peak_of_peaks_position = GST_READ_UINT64_BE (tag_data);
-        break;
-      case 0x3d30:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (!mxf_timestamp_parse (&descriptor->peak_envelope_timestamp,
-                tag_data, tag_size))
-          goto error;
-        break;
-      case 0x3d31:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        descriptor->peak_envelope_data = g_memdup (tag_data, tag_size);
-        descriptor->peak_envelope_data_length = tag_size;
-        break;
-      default:
-        if (type != MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR)
-          goto next;
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size,
-                &((MXFMetadataGenericDescriptor *) descriptor)->other_tags))
-          goto error;
-        break;
-    }
-
-  next:
-    data += 4 + tag_size;
-    size -= 4 + tag_size;
+  switch (tag) {
+    case 0x3d0a:
+      if (tag_size != 2)
+        goto error;
+      descriptor->block_align = GST_READ_UINT16_BE (tag_data);
+      GST_DEBUG ("  block align = %u", descriptor->block_align);
+      ret = TRUE;
+      break;
+    case 0x3d0b:
+      if (tag_size != 1)
+        goto error;
+      descriptor->sequence_offset = GST_READ_UINT8 (tag_data);
+      GST_DEBUG ("  sequence offset = %u", descriptor->sequence_offset);
+      ret = TRUE;
+      break;
+    case 0x3d09:
+      if (tag_size != 4)
+        goto error;
+      descriptor->avg_bps = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  average bps = %u", descriptor->avg_bps);
+      ret = TRUE;
+      break;
+    case 0x3d32:
+      if (tag_size != 16)
+        goto error;
+      memcpy (&descriptor->channel_assignment, tag_data, 16);
+      GST_DEBUG ("  channel assignment = %s",
+          mxf_ul_to_string (&descriptor->channel_assignment, str));
+      ret = TRUE;
+      break;
+    case 0x3d29:
+      if (tag_size != 4)
+        goto error;
+      descriptor->peak_envelope_version = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  peak envelope version = %u",
+          descriptor->peak_envelope_version);
+      ret = TRUE;
+      break;
+    case 0x3d2a:
+      if (tag_size != 4)
+        goto error;
+      descriptor->peak_envelope_format = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  peak envelope format = %u",
+          descriptor->peak_envelope_format);
+      ret = TRUE;
+      break;
+    case 0x3d2b:
+      if (tag_size != 4)
+        goto error;
+      descriptor->points_per_peak_value = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  points per peak value = %u",
+          descriptor->points_per_peak_value);
+      ret = TRUE;
+      break;
+    case 0x3d2c:
+      if (tag_size != 4)
+        goto error;
+      descriptor->peak_envelope_block_size = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  peak envelope block size = %u",
+          descriptor->peak_envelope_block_size);
+      ret = TRUE;
+      break;
+    case 0x3d2d:
+      if (tag_size != 4)
+        goto error;
+      descriptor->peak_channels = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  peak channels = %u", descriptor->peak_channels);
+      ret = TRUE;
+      break;
+    case 0x3d2e:
+      if (tag_size != 4)
+        goto error;
+      descriptor->peak_frames = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  peak frames = %u", descriptor->peak_frames);
+      ret = TRUE;
+      break;
+    case 0x3d2f:
+      if (tag_size != 8)
+        goto error;
+      descriptor->peak_of_peaks_position = GST_READ_UINT64_BE (tag_data);
+      GST_DEBUG ("  peak of peaks position = %" G_GINT64_FORMAT,
+          descriptor->peak_of_peaks_position);
+      ret = TRUE;
+      break;
+    case 0x3d30:
+      if (!mxf_timestamp_parse (&descriptor->peak_envelope_timestamp,
+              tag_data, tag_size))
+        goto error;
+      GST_DEBUG ("  peak envelope timestamp = %d/%u/%u %u:%u:%u.%u",
+          descriptor->peak_envelope_timestamp.year,
+          descriptor->peak_envelope_timestamp.month,
+          descriptor->peak_envelope_timestamp.day,
+          descriptor->peak_envelope_timestamp.hour,
+          descriptor->peak_envelope_timestamp.minute,
+          descriptor->peak_envelope_timestamp.second,
+          (descriptor->peak_envelope_timestamp.quarter_msecond * 1000) / 256);
+      ret = TRUE;
+      break;
+    case 0x3d31:
+      descriptor->peak_envelope_data = g_memdup (tag_data, tag_size);
+      descriptor->peak_envelope_data_length = tag_size;
+      GST_DEBUG ("  peak evelope data size = %u",
+          descriptor->peak_envelope_data_length);
+      ret = TRUE;
+      break;
+    default:
+      ret =
+          mxf_metadata_generic_sound_essence_descriptor_handle_tag (d, primer,
+          tag, tag_data, tag_size);
+      break;
   }
 
-  GST_DEBUG ("Parsed wave audio essence descriptor:");
-  GST_DEBUG ("  block align = %u", descriptor->block_align);
-  GST_DEBUG ("  sequence offset = %u", descriptor->sequence_offset);
-  GST_DEBUG ("  average bps = %u", descriptor->avg_bps);
-  GST_DEBUG ("  channel assignment = %s",
-      mxf_ul_to_string (&descriptor->channel_assignment, str));
-  GST_DEBUG ("  peak envelope version = %u", descriptor->peak_envelope_version);
-  GST_DEBUG ("  peak envelope format = %u", descriptor->peak_envelope_format);
-  GST_DEBUG ("  points per peak value = %u", descriptor->points_per_peak_value);
-  GST_DEBUG ("  peak envelope block size = %u",
-      descriptor->peak_envelope_block_size);
-  GST_DEBUG ("  peak channels = %u", descriptor->peak_channels);
-  GST_DEBUG ("  peak frames = %u", descriptor->peak_frames);
-  GST_DEBUG ("  peak of peaks position = %" G_GINT64_FORMAT,
-      descriptor->peak_of_peaks_position);
-  GST_DEBUG ("  peak envelope timestamp = %d/%u/%u %u:%u:%u.%u",
-      descriptor->peak_envelope_timestamp.year,
-      descriptor->peak_envelope_timestamp.month,
-      descriptor->peak_envelope_timestamp.day,
-      descriptor->peak_envelope_timestamp.hour,
-      descriptor->peak_envelope_timestamp.minute,
-      descriptor->peak_envelope_timestamp.second,
-      (descriptor->peak_envelope_timestamp.quarter_msecond * 1000) / 256);
-
-  GST_DEBUG ("  peak evelope data size = %u",
-      descriptor->peak_envelope_data_length);
-
-  return TRUE;
+  return ret;
 
 error:
-  GST_ERROR ("Invalid wave audio essence descriptor");
-  mxf_metadata_wave_audio_essence_descriptor_reset (descriptor);
+  GST_ERROR ("Invalid wave audio essence descriptor tag 0x%04x of size %u", tag,
+      tag_size);
 
-  return FALSE;
+  return TRUE;
 }
 
 void mxf_metadata_wave_audio_essence_descriptor_reset
index 9f0a08aee265645ae5733b920a175e8160a35fc2..d7887e5ad2cbde3a27dadfc3cc3b4bfcfaf05f16 100644 (file)
@@ -55,7 +55,8 @@ typedef struct {
   guint16 peak_envelope_data_length;
 } MXFMetadataWaveAudioEssenceDescriptor;
 
-gboolean mxf_metadata_wave_audio_essence_descriptor_parse (const MXFUL *key, MXFMetadataWaveAudioEssenceDescriptor *descriptor, const MXFPrimerPack *primer, guint16 type, const guint8 *data, guint size);
+gboolean mxf_metadata_wave_audio_essence_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor,
+    const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size);
 void mxf_metadata_wave_audio_essence_descriptor_reset (MXFMetadataWaveAudioEssenceDescriptor *descriptor);
 
 gboolean mxf_is_aes_bwf_essence_track (const MXFMetadataTrack *track);
index 74ee5251bf1bb2b9d9fdecd83c64904f85940b9c..bb2721215dd5c1fd7ee0f0c9b132dc1834ec4cc8 100644 (file)
@@ -703,21 +703,26 @@ gst_mxf_demux_handle_metadata_generic_descriptor (GstMXFDemux * demux,
 {
   MXFMetadataGenericDescriptor descriptor;
 
+  memset (&descriptor, 0, sizeof (descriptor));
+
   GST_DEBUG_OBJECT (demux,
       "Handling metadata generic descriptor of size %u"
       " at offset %" G_GUINT64_FORMAT " with type 0x%04d",
       GST_BUFFER_SIZE (buffer), demux->offset, type);
 
-  if (!mxf_metadata_generic_descriptor_parse (key, &descriptor,
-          &demux->primer, type, GST_BUFFER_DATA (buffer),
-          GST_BUFFER_SIZE (buffer))) {
+  if (!mxf_metadata_descriptor_parse (key,
+          (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer,
+          type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer),
+          (MXFMetadataDescriptorHandleTag)
+          mxf_metadata_generic_descriptor_handle_tag,
+          (MXFMetadataDescriptorReset) mxf_metadata_generic_descriptor_reset)) {
     GST_ERROR_OBJECT (demux, "Parsing metadata generic descriptor failed");
     return GST_FLOW_ERROR;
   }
 
   if (!demux->generic_descriptor)
     demux->generic_descriptor =
-        g_array_new (FALSE, FALSE, sizeof (MXFMetadataGenericDescriptor));
+        g_array_new (FALSE, TRUE, sizeof (MXFMetadataGenericDescriptor));
 
   g_array_append_val (demux->generic_descriptor, descriptor);
 
@@ -730,21 +735,26 @@ gst_mxf_demux_handle_metadata_file_descriptor (GstMXFDemux * demux,
 {
   MXFMetadataFileDescriptor descriptor;
 
+  memset (&descriptor, 0, sizeof (descriptor));
+
   GST_DEBUG_OBJECT (demux,
       "Handling metadata file descriptor of size %u"
       " at offset %" G_GUINT64_FORMAT " with type 0x%04d",
       GST_BUFFER_SIZE (buffer), demux->offset, type);
 
-  if (!mxf_metadata_file_descriptor_parse (key, &descriptor,
-          &demux->primer, type, GST_BUFFER_DATA (buffer),
-          GST_BUFFER_SIZE (buffer))) {
+  if (!mxf_metadata_descriptor_parse (key,
+          (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer,
+          type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer),
+          (MXFMetadataDescriptorHandleTag)
+          mxf_metadata_file_descriptor_handle_tag,
+          (MXFMetadataDescriptorReset) mxf_metadata_file_descriptor_reset)) {
     GST_ERROR_OBJECT (demux, "Parsing metadata file descriptor failed");
     return GST_FLOW_ERROR;
   }
 
   if (!demux->file_descriptor)
     demux->file_descriptor =
-        g_array_new (FALSE, FALSE, sizeof (MXFMetadataFileDescriptor));
+        g_array_new (FALSE, TRUE, sizeof (MXFMetadataFileDescriptor));
 
   g_array_append_val (demux->file_descriptor, descriptor);
 
@@ -757,21 +767,27 @@ gst_mxf_demux_handle_metadata_multiple_descriptor (GstMXFDemux * demux,
 {
   MXFMetadataMultipleDescriptor descriptor;
 
+  memset (&descriptor, 0, sizeof (descriptor));
+
   GST_DEBUG_OBJECT (demux,
       "Handling metadata multiple descriptor of size %u"
       " at offset %" G_GUINT64_FORMAT " with type 0x%04d",
       GST_BUFFER_SIZE (buffer), demux->offset, type);
 
-  if (!mxf_metadata_multiple_descriptor_parse (key, &descriptor,
-          &demux->primer, type, GST_BUFFER_DATA (buffer),
-          GST_BUFFER_SIZE (buffer))) {
+  if (!mxf_metadata_descriptor_parse (key,
+          (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer,
+          type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer),
+          (MXFMetadataDescriptorHandleTag)
+          mxf_metadata_multiple_descriptor_handle_tag,
+          (MXFMetadataDescriptorReset) mxf_metadata_multiple_descriptor_reset))
+  {
     GST_ERROR_OBJECT (demux, "Parsing metadata multiple descriptor failed");
     return GST_FLOW_ERROR;
   }
 
   if (!demux->multiple_descriptor)
     demux->multiple_descriptor =
-        g_array_new (FALSE, FALSE, sizeof (MXFMetadataMultipleDescriptor));
+        g_array_new (FALSE, TRUE, sizeof (MXFMetadataMultipleDescriptor));
 
   g_array_append_val (demux->multiple_descriptor, descriptor);
 
@@ -784,14 +800,20 @@ gst_mxf_demux_handle_metadata_generic_picture_essence_descriptor (GstMXFDemux *
 {
   MXFMetadataGenericPictureEssenceDescriptor descriptor;
 
+  memset (&descriptor, 0, sizeof (descriptor));
+
   GST_DEBUG_OBJECT (demux,
       "Handling metadata generic picture essence descriptor of size %u"
       " at offset %" G_GUINT64_FORMAT " with type 0x%04d",
       GST_BUFFER_SIZE (buffer), demux->offset, type);
 
-  if (!mxf_metadata_generic_picture_essence_descriptor_parse (key, &descriptor,
-          &demux->primer, type, GST_BUFFER_DATA (buffer),
-          GST_BUFFER_SIZE (buffer))) {
+  if (!mxf_metadata_descriptor_parse (key,
+          (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer,
+          type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer),
+          (MXFMetadataDescriptorHandleTag)
+          mxf_metadata_generic_picture_essence_descriptor_handle_tag,
+          (MXFMetadataDescriptorReset)
+          mxf_metadata_generic_picture_essence_descriptor_reset)) {
     GST_ERROR_OBJECT (demux,
         "Parsing metadata generic picture essence descriptor failed");
     return GST_FLOW_ERROR;
@@ -799,7 +821,7 @@ gst_mxf_demux_handle_metadata_generic_picture_essence_descriptor (GstMXFDemux *
 
   if (!demux->generic_picture_essence_descriptor)
     demux->generic_picture_essence_descriptor =
-        g_array_new (FALSE, FALSE,
+        g_array_new (FALSE, TRUE,
         sizeof (MXFMetadataGenericPictureEssenceDescriptor));
 
   g_array_append_val (demux->generic_picture_essence_descriptor, descriptor);
@@ -813,14 +835,20 @@ gst_mxf_demux_handle_metadata_cdci_picture_essence_descriptor (GstMXFDemux *
 {
   MXFMetadataCDCIPictureEssenceDescriptor descriptor;
 
+  memset (&descriptor, 0, sizeof (descriptor));
+
   GST_DEBUG_OBJECT (demux,
       "Handling metadata CDCI picture essence descriptor of size %u"
       " at offset %" G_GUINT64_FORMAT " with type 0x%04d",
       GST_BUFFER_SIZE (buffer), demux->offset, type);
 
-  if (!mxf_metadata_cdci_picture_essence_descriptor_parse (key, &descriptor,
-          &demux->primer, type, GST_BUFFER_DATA (buffer),
-          GST_BUFFER_SIZE (buffer))) {
+  if (!mxf_metadata_descriptor_parse (key,
+          (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer,
+          type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer),
+          (MXFMetadataDescriptorHandleTag)
+          mxf_metadata_cdci_picture_essence_descriptor_handle_tag,
+          (MXFMetadataDescriptorReset)
+          mxf_metadata_cdci_picture_essence_descriptor_reset)) {
     GST_ERROR_OBJECT (demux,
         "Parsing metadata CDCI picture essence descriptor failed");
     return GST_FLOW_ERROR;
@@ -828,7 +856,7 @@ gst_mxf_demux_handle_metadata_cdci_picture_essence_descriptor (GstMXFDemux *
 
   if (!demux->cdci_picture_essence_descriptor)
     demux->cdci_picture_essence_descriptor =
-        g_array_new (FALSE, FALSE,
+        g_array_new (FALSE, TRUE,
         sizeof (MXFMetadataCDCIPictureEssenceDescriptor));
 
   g_array_append_val (demux->cdci_picture_essence_descriptor, descriptor);
@@ -842,21 +870,27 @@ gst_mxf_demux_handle_metadata_mpeg_video_descriptor (GstMXFDemux * demux,
 {
   MXFMetadataMPEGVideoDescriptor descriptor;
 
+  memset (&descriptor, 0, sizeof (descriptor));
+
   GST_DEBUG_OBJECT (demux,
       "Handling metadata MPEG video descriptor of size %u"
       " at offset %" G_GUINT64_FORMAT " with type 0x%04d",
       GST_BUFFER_SIZE (buffer), demux->offset, type);
 
-  if (!mxf_metadata_mpeg_video_descriptor_parse (key, &descriptor,
-          &demux->primer, type, GST_BUFFER_DATA (buffer),
-          GST_BUFFER_SIZE (buffer))) {
+  if (!mxf_metadata_descriptor_parse (key,
+          (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer,
+          type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer),
+          (MXFMetadataDescriptorHandleTag)
+          mxf_metadata_mpeg_video_descriptor_handle_tag,
+          (MXFMetadataDescriptorReset)
+          mxf_metadata_mpeg_video_descriptor_reset)) {
     GST_ERROR_OBJECT (demux, "Parsing metadata MPEG video descriptor failed");
     return GST_FLOW_ERROR;
   }
 
   if (!demux->mpeg_video_descriptor)
     demux->mpeg_video_descriptor =
-        g_array_new (FALSE, FALSE, sizeof (MXFMetadataMPEGVideoDescriptor));
+        g_array_new (FALSE, TRUE, sizeof (MXFMetadataMPEGVideoDescriptor));
 
   g_array_append_val (demux->mpeg_video_descriptor, descriptor);
 
@@ -869,14 +903,20 @@ gst_mxf_demux_handle_metadata_generic_sound_essence_descriptor (GstMXFDemux *
 {
   MXFMetadataGenericSoundEssenceDescriptor descriptor;
 
+  memset (&descriptor, 0, sizeof (descriptor));
+
   GST_DEBUG_OBJECT (demux,
       "Handling metadata generic sound essence descriptor of size %u"
       " at offset %" G_GUINT64_FORMAT " with type 0x%04d",
       GST_BUFFER_SIZE (buffer), demux->offset, type);
 
-  if (!mxf_metadata_generic_sound_essence_descriptor_parse (key, &descriptor,
-          &demux->primer, type, GST_BUFFER_DATA (buffer),
-          GST_BUFFER_SIZE (buffer))) {
+  if (!mxf_metadata_descriptor_parse (key,
+          (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer,
+          type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer),
+          (MXFMetadataDescriptorHandleTag)
+          mxf_metadata_generic_sound_essence_descriptor_handle_tag,
+          (MXFMetadataDescriptorReset)
+          mxf_metadata_generic_sound_essence_descriptor_reset)) {
     GST_ERROR_OBJECT (demux,
         "Parsing metadata generic sound essence descriptor failed");
     return GST_FLOW_ERROR;
@@ -884,7 +924,7 @@ gst_mxf_demux_handle_metadata_generic_sound_essence_descriptor (GstMXFDemux *
 
   if (!demux->generic_sound_essence_descriptor)
     demux->generic_sound_essence_descriptor =
-        g_array_new (FALSE, FALSE,
+        g_array_new (FALSE, TRUE,
         sizeof (MXFMetadataGenericSoundEssenceDescriptor));
 
   g_array_append_val (demux->generic_sound_essence_descriptor, descriptor);
@@ -898,14 +938,20 @@ gst_mxf_demux_handle_metadata_wave_audio_essence_descriptor (GstMXFDemux *
 {
   MXFMetadataWaveAudioEssenceDescriptor descriptor;
 
+  memset (&descriptor, 0, sizeof (descriptor));
+
   GST_DEBUG_OBJECT (demux,
       "Handling metadata wave sound essence descriptor of size %u"
       " at offset %" G_GUINT64_FORMAT " with type 0x%04d",
       GST_BUFFER_SIZE (buffer), demux->offset, type);
 
-  if (!mxf_metadata_wave_audio_essence_descriptor_parse (key, &descriptor,
-          &demux->primer, type, GST_BUFFER_DATA (buffer),
-          GST_BUFFER_SIZE (buffer))) {
+  if (!mxf_metadata_descriptor_parse (key,
+          (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer,
+          type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer),
+          (MXFMetadataDescriptorHandleTag)
+          mxf_metadata_wave_audio_essence_descriptor_handle_tag,
+          (MXFMetadataDescriptorReset)
+          mxf_metadata_wave_audio_essence_descriptor_reset)) {
     GST_ERROR_OBJECT (demux,
         "Parsing metadata wave sound essence descriptor failed");
     return GST_FLOW_ERROR;
@@ -913,7 +959,7 @@ gst_mxf_demux_handle_metadata_wave_audio_essence_descriptor (GstMXFDemux *
 
   if (!demux->wave_audio_essence_descriptor)
     demux->wave_audio_essence_descriptor =
-        g_array_new (FALSE, FALSE,
+        g_array_new (FALSE, TRUE,
         sizeof (MXFMetadataWaveAudioEssenceDescriptor));
 
   g_array_append_val (demux->wave_audio_essence_descriptor, descriptor);
@@ -1748,12 +1794,6 @@ gst_mxf_demux_handle_metadata (GstMXFDemux * demux, const MXFUL * key,
     return GST_FLOW_OK;
   }
 
-  /* Make writable as the parsing of descriptors sets already read local tags to 0x0000 */
-  if (!gst_buffer_is_writable (buffer))
-    buffer = gst_buffer_copy (buffer);
-  else
-    buffer = gst_buffer_ref (buffer);
-
   switch (type) {
     case MXF_METADATA_PREFACE:
       ret = gst_mxf_demux_handle_metadata_preface (demux, key, buffer);
@@ -1838,8 +1878,6 @@ gst_mxf_demux_handle_metadata (GstMXFDemux * demux, const MXFUL * key,
       break;
   }
 
-  gst_buffer_unref (buffer);
-
   return ret;
 }
 
index 6a36312877a7e45dd5f3059492e6dba54a5d04ee..ab70780bb2a0f5547ca5cc62a99914bdb36f3dcc 100644 (file)
@@ -89,116 +89,94 @@ static const guint8 _profile_and_level_ul[] = {
 };
 
 gboolean
-mxf_metadata_mpeg_video_descriptor_parse (const MXFUL * key,
-    MXFMetadataMPEGVideoDescriptor * descriptor,
-    const MXFPrimerPack * primer, guint16 type, const guint8 * data, guint size)
+mxf_metadata_mpeg_video_descriptor_handle_tag (MXFMetadataGenericDescriptor * d,
+    const MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
+    guint16 tag_size)
 {
-  guint16 tag, tag_size;
-  const guint8 *tag_data;
-
-  g_return_val_if_fail (data != NULL, FALSE);
-
-  memset (descriptor, 0, sizeof (MXFMetadataMPEGVideoDescriptor));
+  MXFMetadataMPEGVideoDescriptor *descriptor =
+      (MXFMetadataMPEGVideoDescriptor *) d;
+  gboolean ret = FALSE;
+  MXFUL *tag_ul = NULL;
+
+  if (!(tag_ul =
+          (MXFUL *) g_hash_table_lookup (primer->mappings,
+              GUINT_TO_POINTER (((guint) tag)))))
+    return FALSE;
 
-  if (!mxf_metadata_cdci_picture_essence_descriptor_parse (key,
-          (MXFMetadataCDCIPictureEssenceDescriptor *) descriptor, primer, type,
-          data, size))
-    goto error;
-
-  while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
-    MXFUL *tag_ul = NULL;
-
-    if (tag_size == 0 || tag == 0x0000)
-      goto next;
-
-    if (!(tag_ul =
-            (MXFUL *) g_hash_table_lookup (primer->mappings,
-                GUINT_TO_POINTER (((guint) tag)))))
-      goto next;
-
-    if (memcmp (tag_ul, &_single_sequence_ul, 16) == 0) {
-      GST_WRITE_UINT16_BE (data, 0x0000);
-      if (tag_size != 1)
-        goto error;
-      descriptor->single_sequence = GST_READ_UINT8 (tag_data);
-    } else if (memcmp (tag_ul, &_constant_b_frames_ul, 16) == 0) {
-      GST_WRITE_UINT16_BE (data, 0x0000);
-      if (tag_size != 1)
-        goto error;
-      descriptor->const_b_frames = GST_READ_UINT8 (tag_data);
-    } else if (memcmp (tag_ul, &_coded_content_type_ul, 16) == 0) {
-      GST_WRITE_UINT16_BE (data, 0x0000);
-      if (tag_size != 1)
-        goto error;
-      descriptor->coded_content_type = GST_READ_UINT8 (tag_data);
-    } else if (memcmp (tag_ul, &_low_delay_ul, 16) == 0) {
-      GST_WRITE_UINT16_BE (data, 0x0000);
-      if (tag_size != 1)
-        goto error;
-      descriptor->low_delay = GST_READ_UINT8 (tag_data);
-    } else if (memcmp (tag_ul, &_closed_gop_ul, 16) == 0) {
-      GST_WRITE_UINT16_BE (data, 0x0000);
-      if (tag_size != 1)
-        goto error;
-      descriptor->closed_gop = GST_READ_UINT8 (tag_data);
-    } else if (memcmp (tag_ul, &_identical_gop_ul, 16) == 0) {
-      GST_WRITE_UINT16_BE (data, 0x0000);
-      if (tag_size != 1)
-        goto error;
-      descriptor->identical_gop = GST_READ_UINT8 (tag_data);
-    } else if (memcmp (tag_ul, &_max_gop_ul, 16) == 0) {
-      GST_WRITE_UINT16_BE (data, 0x0000);
-      if (tag_size != 2)
-        goto error;
-      descriptor->max_gop = GST_READ_UINT16_BE (tag_data);
-    } else if (memcmp (tag_ul, &_b_picture_count_ul, 16) == 0) {
-      GST_WRITE_UINT16_BE (data, 0x0000);
-      if (tag_size != 2)
-        goto error;
-      descriptor->b_picture_count = GST_READ_UINT16_BE (tag_data);
-    } else if (memcmp (tag_ul, &_bitrate_ul, 16) == 0) {
-      GST_WRITE_UINT16_BE (data, 0x0000);
-      if (tag_size != 4)
-        goto error;
-      descriptor->bitrate = GST_READ_UINT32_BE (tag_data);
-    } else if (memcmp (tag_ul, &_profile_and_level_ul, 16) == 0) {
-      GST_WRITE_UINT16_BE (data, 0x0000);
-      if (tag_size != 1)
-        goto error;
-      descriptor->profile_and_level = GST_READ_UINT8 (tag_data);
-    } else {
-      if (type != MXF_METADATA_MPEG_VIDEO_DESCRIPTOR)
-        goto next;
-      GST_WRITE_UINT16_BE (data, 0x0000);
-      if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size,
-              &((MXFMetadataGenericDescriptor *) descriptor)->other_tags))
-        goto error;
-    }
-  next:
-    data += 4 + tag_size;
-    size -= 4 + tag_size;
+  if (memcmp (tag_ul, &_single_sequence_ul, 16) == 0) {
+    if (tag_size != 1)
+      goto error;
+    descriptor->single_sequence = GST_READ_UINT8 (tag_data);
+    GST_DEBUG ("  single sequence = %s",
+        (descriptor->single_sequence) ? "yes" : "no");
+    ret = TRUE;
+  } else if (memcmp (tag_ul, &_constant_b_frames_ul, 16) == 0) {
+    if (tag_size != 1)
+      goto error;
+    descriptor->const_b_frames = GST_READ_UINT8 (tag_data);
+    GST_DEBUG ("  constant b frames = %s",
+        (descriptor->single_sequence) ? "yes" : "no");
+    ret = TRUE;
+  } else if (memcmp (tag_ul, &_coded_content_type_ul, 16) == 0) {
+    if (tag_size != 1)
+      goto error;
+    descriptor->coded_content_type = GST_READ_UINT8 (tag_data);
+    GST_DEBUG ("  coded content type = %u", descriptor->coded_content_type);
+    ret = TRUE;
+  } else if (memcmp (tag_ul, &_low_delay_ul, 16) == 0) {
+    if (tag_size != 1)
+      goto error;
+    descriptor->low_delay = GST_READ_UINT8 (tag_data);
+    GST_DEBUG ("  low delay = %s", (descriptor->low_delay) ? "yes" : "no");
+    ret = TRUE;
+  } else if (memcmp (tag_ul, &_closed_gop_ul, 16) == 0) {
+    if (tag_size != 1)
+      goto error;
+    descriptor->closed_gop = GST_READ_UINT8 (tag_data);
+    GST_DEBUG ("  closed gop = %s", (descriptor->closed_gop) ? "yes" : "no");
+    ret = TRUE;
+  } else if (memcmp (tag_ul, &_identical_gop_ul, 16) == 0) {
+    if (tag_size != 1)
+      goto error;
+    descriptor->identical_gop = GST_READ_UINT8 (tag_data);
+    GST_DEBUG ("  identical gop = %s",
+        (descriptor->identical_gop) ? "yes" : "no");
+    ret = TRUE;
+  } else if (memcmp (tag_ul, &_max_gop_ul, 16) == 0) {
+    if (tag_size != 2)
+      goto error;
+    descriptor->max_gop = GST_READ_UINT16_BE (tag_data);
+    GST_DEBUG ("  max gop = %u", descriptor->max_gop);
+    ret = TRUE;
+  } else if (memcmp (tag_ul, &_b_picture_count_ul, 16) == 0) {
+    if (tag_size != 2)
+      goto error;
+    descriptor->b_picture_count = GST_READ_UINT16_BE (tag_data);
+    GST_DEBUG ("  b picture count = %u", descriptor->b_picture_count);
+    ret = TRUE;
+  } else if (memcmp (tag_ul, &_bitrate_ul, 16) == 0) {
+    if (tag_size != 4)
+      goto error;
+    descriptor->bitrate = GST_READ_UINT32_BE (tag_data);
+    GST_DEBUG ("  bitrate = %u", descriptor->bitrate);
+    ret = TRUE;
+  } else if (memcmp (tag_ul, &_profile_and_level_ul, 16) == 0) {
+    if (tag_size != 1)
+      goto error;
+    descriptor->profile_and_level = GST_READ_UINT8 (tag_data);
+    GST_DEBUG ("  profile & level = %u", descriptor->profile_and_level);
+    ret = TRUE;
+  } else {
+    ret =
+        mxf_metadata_cdci_picture_essence_descriptor_handle_tag (d, primer, tag,
+        tag_data, tag_size);
   }
 
-  GST_DEBUG ("Parsed mpeg video descriptors:");
-  GST_DEBUG ("  single sequence = %s",
-      (descriptor->single_sequence) ? "yes" : "no");
-  GST_DEBUG ("  constant b frames = %s",
-      (descriptor->single_sequence) ? "yes" : "no");
-  GST_DEBUG ("  coded content type = %u", descriptor->coded_content_type);
-  GST_DEBUG ("  low delay = %s", (descriptor->low_delay) ? "yes" : "no");
-  GST_DEBUG ("  closed gop = %s", (descriptor->closed_gop) ? "yes" : "no");
-  GST_DEBUG ("  identical gop = %s",
-      (descriptor->identical_gop) ? "yes" : "no");
-  GST_DEBUG ("  max gop = %u", descriptor->max_gop);
-  GST_DEBUG ("  b picture count = %u", descriptor->b_picture_count);
-  GST_DEBUG ("  bitrate = %u", descriptor->bitrate);
-  GST_DEBUG ("  profile & level = %u", descriptor->profile_and_level);
-
-  return TRUE;
+  return ret;
 
 error:
-  GST_ERROR ("Invalid mpeg video descriptor");
-  mxf_metadata_mpeg_video_descriptor_reset (descriptor);
+  GST_ERROR ("Invalid mpeg video descriptor tag 0x%04x of size %u", tag,
+      tag_size);
 
   return FALSE;
 }
index 53e396855c369c88b0bdf7a5557b81b9935d1246..be3e765f55515db08cb706a5802e8375ff25aeea 100644 (file)
@@ -49,7 +49,7 @@ typedef struct {
   guint8 profile_and_level;
 } MXFMetadataMPEGVideoDescriptor;
 
-gboolean mxf_metadata_mpeg_video_descriptor_parse (const MXFUL *key, MXFMetadataMPEGVideoDescriptor *descriptor, const MXFPrimerPack *primer, guint16 type, const guint8 *data, guint size);
+gboolean mxf_metadata_mpeg_video_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor, const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size);
 void mxf_metadata_mpeg_video_descriptor_reset (MXFMetadataMPEGVideoDescriptor *descriptor);
 
 gboolean mxf_is_mpeg_video_essence_track (const MXFMetadataTrack *track);
index e9efac92e559c0c738f4a0dec9b54d23311b7e65..41ba4d5dcaec0b0da8a9cb2d5be8fb71ef3b1888 100644 (file)
@@ -406,6 +406,8 @@ mxf_partition_pack_parse (const MXFUL * key, MXFPartitionPack * pack,
 
   memset (pack, 0, sizeof (MXFPartitionPack));
 
+  GST_DEBUG ("Parsing partition pack:");
+
   if (key->u[13] == 0x02)
     pack->type = MXF_PARTITION_PACK_HEADER;
   else if (key->u[13] == 0x03)
@@ -413,9 +415,16 @@ mxf_partition_pack_parse (const MXFUL * key, MXFPartitionPack * pack,
   else if (key->u[13] == 0x04)
     pack->type = MXF_PARTITION_PACK_FOOTER;
 
+  GST_DEBUG ("  type = %s",
+      (pack->type == MXF_PARTITION_PACK_HEADER) ? "header" : (pack->type ==
+          MXF_PARTITION_PACK_BODY) ? "body" : "footer");
+
   pack->closed = (key->u[14] == 0x02 || key->u[14] == 0x04);
   pack->complete = (key->u[14] == 0x03 || key->u[14] == 0x04);
 
+  GST_DEBUG ("  closed = %s, complete = %s", (pack->closed) ? "yes" : "no",
+      (pack->complete) ? "yes" : "no");
+
   pack->major_version = GST_READ_UINT16_BE (data);
   if (pack->major_version != 1)
     goto error;
@@ -426,26 +435,42 @@ mxf_partition_pack_parse (const MXFUL * key, MXFPartitionPack * pack,
   data += 2;
   size -= 2;
 
+  GST_DEBUG ("  MXF version = %u.%u", pack->major_version, pack->minor_version);
+
   pack->kag_size = GST_READ_UINT32_BE (data);
   data += 4;
   size -= 4;
 
+  GST_DEBUG ("  KAG size = %u", pack->kag_size);
+
   pack->this_partition = GST_READ_UINT64_BE (data);
   data += 8;
   size -= 8;
 
+  GST_DEBUG ("  this partition offset = %" G_GUINT64_FORMAT,
+      pack->this_partition);
+
   pack->prev_partition = GST_READ_UINT64_BE (data);
   data += 8;
   size -= 8;
 
+  GST_DEBUG ("  previous partition offset = %" G_GUINT64_FORMAT,
+      pack->prev_partition);
+
   pack->footer_partition = GST_READ_UINT64_BE (data);
   data += 8;
   size -= 8;
 
+  GST_DEBUG ("  footer partition offset = %" G_GUINT64_FORMAT,
+      pack->footer_partition);
+
   pack->header_byte_count = GST_READ_UINT64_BE (data);
   data += 8;
   size -= 8;
 
+  GST_DEBUG ("  header byte count = %" G_GUINT64_FORMAT,
+      pack->header_byte_count);
+
   pack->index_byte_count = GST_READ_UINT64_BE (data);
   data += 8;
   size -= 8;
@@ -454,6 +479,9 @@ mxf_partition_pack_parse (const MXFUL * key, MXFPartitionPack * pack,
   data += 4;
   size -= 4;
 
+  GST_DEBUG ("  index sid = %u, size = %" G_GUINT64_FORMAT, pack->index_sid,
+      pack->index_byte_count);
+
   pack->body_offset = GST_READ_UINT64_BE (data);
   data += 8;
   size -= 8;
@@ -462,14 +490,22 @@ mxf_partition_pack_parse (const MXFUL * key, MXFPartitionPack * pack,
   data += 4;
   size -= 4;
 
+  GST_DEBUG ("  body sid = %u, offset = %" G_GUINT64_FORMAT, pack->body_sid,
+      pack->body_offset);
+
   memcpy (&pack->operational_pattern, data, 16);
   data += 16;
   size -= 16;
 
+  GST_DEBUG ("  operational pattern = %s",
+      mxf_ul_to_string (&pack->operational_pattern, str));
+
   pack->n_essence_containers = GST_READ_UINT32_BE (data);
   data += 4;
   size -= 4;
 
+  GST_DEBUG ("  number of essence containers = %u", pack->n_essence_containers);
+
   if (GST_READ_UINT32_BE (data) != 16)
     goto error;
   data += 4;
@@ -480,37 +516,14 @@ mxf_partition_pack_parse (const MXFUL * key, MXFPartitionPack * pack,
 
   if (pack->n_essence_containers) {
     pack->essence_containers = g_new (MXFUL, pack->n_essence_containers);
-    for (i = 0; i < pack->n_essence_containers; i++)
+    for (i = 0; i < pack->n_essence_containers; i++) {
       memcpy (&pack->essence_containers[i], data + i * 16, 16);
+      GST_DEBUG ("  essence container %u = %s", i,
+          mxf_ul_to_string (&pack->essence_containers[i], str));
+    }
   }
 
   pack->valid = TRUE;
-  GST_DEBUG ("Parsed partition pack: \n"
-      "  type = %s, closed = %s, complete = %s\n"
-      "  MXF version = %u.%u\n"
-      "  KAG size = %u\n"
-      "  this partition offset = %" G_GUINT64_FORMAT "\n"
-      "  previous partition offset = %" G_GUINT64_FORMAT "\n"
-      "  footer partition offset = %" G_GUINT64_FORMAT "\n"
-      "  header size = %" G_GUINT64_FORMAT "\n"
-      "  index sid = %u, size %" G_GUINT64_FORMAT "\n"
-      "  body sid = %u, offset %" G_GUINT64_FORMAT "\n"
-      "  operational pattern = %s\n"
-      "  number of essence containers = %u",
-      (pack->type == MXF_PARTITION_PACK_HEADER) ? "header" : (pack->type ==
-          MXF_PARTITION_PACK_BODY) ? "body" : "footer",
-      (pack->closed) ? "yes" : "no", (pack->complete) ? "yes" : "no",
-      pack->major_version, pack->minor_version, pack->kag_size,
-      pack->this_partition, pack->prev_partition, pack->footer_partition,
-      pack->header_byte_count, pack->index_sid, pack->index_byte_count,
-      pack->body_sid, pack->body_offset,
-      mxf_ul_to_string (&pack->operational_pattern, str),
-      pack->n_essence_containers);
-
-  for (i = 0; i < pack->n_essence_containers; i++) {
-    GST_DEBUG ("  essence container %u = %s", i,
-        mxf_ul_to_string (&pack->essence_containers[i], str));
-  }
 
   return TRUE;
 
@@ -551,6 +564,8 @@ mxf_primer_pack_parse (const MXFUL * key, MXFPrimerPack * pack,
 
   memset (pack, 0, sizeof (MXFPrimerPack));
 
+  GST_DEBUG ("Parsing primer pack:");
+
   pack->mappings =
       g_hash_table_new_full (g_direct_hash, g_direct_equal,
       (GDestroyNotify) NULL, (GDestroyNotify) _mxf_mapping_ul_free);
@@ -558,6 +573,8 @@ mxf_primer_pack_parse (const MXFUL * key, MXFPrimerPack * pack,
   n = GST_READ_UINT32_BE (data);
   data += 4;
 
+  GST_DEBUG ("  number of mappings = %u", n);
+
   if (GST_READ_UINT32_BE (data) != 18)
     goto error;
   data += 4;
@@ -565,7 +582,6 @@ mxf_primer_pack_parse (const MXFUL * key, MXFPrimerPack * pack,
   if (size < 8 + n * 18)
     goto error;
 
-  GST_DEBUG ("Parsed primer pack:");
   for (i = 0; i < n; i++) {
     guint local_tag;
     gchar str[48];
@@ -582,7 +598,7 @@ mxf_primer_pack_parse (const MXFUL * key, MXFPrimerPack * pack,
     data += 16;
 
     g_hash_table_insert (pack->mappings, GUINT_TO_POINTER (local_tag), uid);
-    GST_DEBUG ("  Adding primer pack association: 0x%04x -> %s", local_tag,
+    GST_DEBUG ("  Adding mapping = 0x%04x -> %s", local_tag,
         mxf_ul_to_string (uid, str));
   }
 
@@ -687,62 +703,74 @@ mxf_metadata_preface_parse (const MXFUL * key,
   guint16 tag, tag_size;
   const guint8 *tag_data;
   gchar str[48];
-  guint i;
 
   g_return_val_if_fail (data != NULL, FALSE);
 
   memset (preface, 0, sizeof (MXFMetadataPreface));
 
+  GST_DEBUG ("Parsing preface:");
+
   while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
     if (tag_size == 0 || tag == 0x0000)
       goto next;
 
     switch (tag) {
       case 0x3c0a:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&preface->instance_uid, tag_data, 16);
+        GST_DEBUG ("  instance uid = %s",
+            mxf_ul_to_string (&preface->instance_uid, str));
         break;
       case 0x0102:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&preface->generation_uid, tag_data, 16);
+        GST_DEBUG ("  generation uid = %s",
+            mxf_ul_to_string (&preface->generation_uid, str));
         break;
       case 0x3b02:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (!mxf_timestamp_parse (&preface->last_modified_date, tag_data,
                 tag_size))
           goto error;
+        GST_DEBUG ("  last modified date = %d/%u/%u %u:%u:%u.%u",
+            preface->last_modified_date.year, preface->last_modified_date.month,
+            preface->last_modified_date.day, preface->last_modified_date.hour,
+            preface->last_modified_date.minute,
+            preface->last_modified_date.second,
+            (preface->last_modified_date.quarter_msecond * 1000) / 256);
         break;
       case 0x3b05:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 2)
           goto error;
         preface->version = GST_READ_UINT16_BE (tag_data);
+        GST_DEBUG ("  version = %u.%u", (preface->version >> 8),
+            (preface->version & 0x0f));
         break;
       case 0x3b07:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 4)
           goto error;
         preface->object_model_version = GST_READ_UINT32_BE (tag_data);
+        GST_DEBUG ("  object model version = %u",
+            preface->object_model_version);
         break;
       case 0x3b08:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&preface->primary_package_uid, tag_data, 16);
+        GST_DEBUG ("  primary package = %s",
+            mxf_ul_to_string (&preface->primary_package_uid, str));
         break;
       case 0x3b06:{
         guint32 len;
         guint i;
 
-        GST_WRITE_UINT16_BE (data, 0x0000);
 
         if (tag_size < 8)
           goto error;
         len = GST_READ_UINT32_BE (tag_data);
+        GST_DEBUG ("  number of identifications = %u",
+            preface->n_identifications);
         if (len == 0)
           break;
         if (GST_READ_UINT32_BE (tag_data + 4) != 16)
@@ -752,31 +780,36 @@ mxf_metadata_preface_parse (const MXFUL * key,
 
         preface->n_identifications = len;
         preface->identifications_uids = g_new (MXFUL, len);
-        for (i = 0; i < len; i++)
+        for (i = 0; i < len; i++) {
           memcpy (&preface->identifications_uids[i], tag_data + 8 + i * 16, 16);
+          GST_DEBUG ("  identification %u = %s", i,
+              mxf_ul_to_string (&preface->identifications_uids[i], str));
+        }
         break;
       }
       case 0x3b03:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&preface->content_storage_uid, tag_data, 16);
+        GST_DEBUG ("  content storage = %s",
+            mxf_ul_to_string (&preface->content_storage_uid, str));
         break;
       case 0x3b09:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&preface->operational_pattern, tag_data, 16);
+        GST_DEBUG ("  operational pattern = %s",
+            mxf_ul_to_string (&preface->operational_pattern, str));
         break;
       case 0x3b0a:{
         guint32 len;
         guint i;
 
-        GST_WRITE_UINT16_BE (data, 0x0000);
 
         if (tag_size < 8)
           goto error;
         len = GST_READ_UINT32_BE (tag_data);
+        GST_DEBUG ("  number of essence containers = %u", len);
         if (len == 0)
           break;
         if (GST_READ_UINT32_BE (tag_data + 4) != 16)
@@ -786,19 +819,22 @@ mxf_metadata_preface_parse (const MXFUL * key,
 
         preface->n_essence_containers = len;
         preface->essence_containers = g_new (MXFUL, len);
-        for (i = 0; i < len; i++)
+        for (i = 0; i < len; i++) {
           memcpy (&preface->essence_containers[i], tag_data + 8 + i * 16, 16);
+          GST_DEBUG ("  essence container %u = %s", i,
+              mxf_ul_to_string (&preface->essence_containers[i], str));
+        }
         break;
       }
       case 0x3b0b:{
         guint32 len;
         guint i;
 
-        GST_WRITE_UINT16_BE (data, 0x0000);
 
         if (tag_size < 8)
           goto error;
         len = GST_READ_UINT32_BE (tag_data);
+        GST_DEBUG ("  number of DM schemes = %u", len);
         if (len == 0)
           break;
         if (GST_READ_UINT32_BE (tag_data + 4) != 16)
@@ -808,12 +844,14 @@ mxf_metadata_preface_parse (const MXFUL * key,
 
         preface->n_dm_schemes = len;
         preface->dm_schemes = g_new (MXFUL, len);
-        for (i = 0; i < len; i++)
+        for (i = 0; i < len; i++) {
           memcpy (&preface->dm_schemes[i], tag_data + 8 + i * 16, 16);
+          GST_DEBUG ("  DM schemes %u = %s", i,
+              mxf_ul_to_string (&preface->dm_schemes[i], str));
+        }
         break;
       }
       default:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size,
                 &preface->other_tags))
           goto error;
@@ -825,42 +863,6 @@ mxf_metadata_preface_parse (const MXFUL * key,
     size -= 4 + tag_size;
   }
 
-  GST_DEBUG ("Parsed preface:");
-  GST_DEBUG ("  instance uid = %s", mxf_ul_to_string (&preface->instance_uid,
-          str));
-  GST_DEBUG ("  generation uid = %s",
-      mxf_ul_to_string (&preface->generation_uid, str));
-  GST_DEBUG ("  last modified date = %d/%u/%u %u:%u:%u.%u",
-      preface->last_modified_date.year, preface->last_modified_date.month,
-      preface->last_modified_date.day, preface->last_modified_date.hour,
-      preface->last_modified_date.minute, preface->last_modified_date.second,
-      (preface->last_modified_date.quarter_msecond * 1000) / 256);
-  GST_DEBUG ("  version = %u.%u", (preface->version >> 8),
-      (preface->version & 0x0f));
-  GST_DEBUG ("  object model version = %u", preface->object_model_version);
-  GST_DEBUG ("  primary package = %s",
-      mxf_ul_to_string (&preface->primary_package_uid, str));
-  GST_DEBUG ("  content storage = %s",
-      mxf_ul_to_string (&preface->content_storage_uid, str));
-  GST_DEBUG ("  operational pattern = %s",
-      mxf_ul_to_string (&preface->operational_pattern, str));
-  GST_DEBUG ("  number of identifications = %u", preface->n_identifications);
-  GST_DEBUG ("  number of essence containers = %u",
-      preface->n_essence_containers);
-  GST_DEBUG ("  number of DM schemes = %u", preface->n_dm_schemes);
-
-  for (i = 0; i < preface->n_identifications; i++)
-    GST_DEBUG ("  identification %u = %s", i,
-        mxf_ul_to_string (&preface->identifications_uids[i], str));
-
-  for (i = 0; i < preface->n_essence_containers; i++)
-    GST_DEBUG ("  essence container %u = %s", i,
-        mxf_ul_to_string (&preface->essence_containers[i], str));
-
-  for (i = 0; i < preface->n_dm_schemes; i++)
-    GST_DEBUG ("  DM schemes %u = %s", i,
-        mxf_ul_to_string (&preface->dm_schemes[i], str));
-
   return TRUE;
 
 error:
@@ -899,65 +901,89 @@ mxf_metadata_identification_parse (const MXFUL * key,
 
   memset (identification, 0, sizeof (MXFMetadataIdentification));
 
+  GST_DEBUG ("Parsing identification:");
+
   while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
     if (tag_size == 0 || tag == 0x0000)
       goto next;
 
     switch (tag) {
       case 0x3c0a:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&identification->instance_uid, tag_data, 16);
+        GST_DEBUG ("  instance uid = %s",
+            mxf_ul_to_string (&identification->instance_uid, str));
         break;
       case 0x3c09:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&identification->generation_uid, tag_data, 16);
+        GST_DEBUG ("  generation uid = %s",
+            mxf_ul_to_string (&identification->generation_uid, str));
         break;
       case 0x3c01:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         identification->company_name = mxf_utf16_to_utf8 (tag_data, tag_size);
+        GST_DEBUG ("  company name = %s",
+            GST_STR_NULL (identification->company_name));
         break;
       case 0x3c02:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         identification->product_name = mxf_utf16_to_utf8 (tag_data, tag_size);
+        GST_DEBUG ("  product name = %s",
+            GST_STR_NULL (identification->product_name));
         break;
       case 0x3c03:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (!mxf_product_version_parse (&identification->product_version,
                 tag_data, tag_size))
           goto error;
+        GST_DEBUG ("  product version = %u.%u.%u.%u.%u",
+            identification->product_version.major,
+            identification->product_version.minor,
+            identification->product_version.patch,
+            identification->product_version.build,
+            identification->product_version.release);
         break;
       case 0x3c04:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         identification->version_string = mxf_utf16_to_utf8 (tag_data, tag_size);
+        GST_DEBUG ("  version string = %s",
+            GST_STR_NULL (identification->version_string));
         break;
       case 0x3c05:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&identification->product_uid, tag_data, 16);
+        GST_DEBUG ("  product uid = %s",
+            mxf_ul_to_string (&identification->product_uid, str));
         break;
       case 0x3c06:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (!mxf_timestamp_parse (&identification->modification_date, tag_data,
                 tag_size))
           goto error;
+        GST_DEBUG ("  modification date = %d/%u/%u %u:%u:%u.%u",
+            identification->modification_date.year,
+            identification->modification_date.month,
+            identification->modification_date.day,
+            identification->modification_date.hour,
+            identification->modification_date.minute,
+            identification->modification_date.second,
+            (identification->modification_date.quarter_msecond * 1000) / 256);
         break;
       case 0x3c07:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (!mxf_product_version_parse (&identification->toolkit_version,
                 tag_data, tag_size))
           goto error;
+        GST_DEBUG ("  toolkit version = %u.%u.%u.%u.%u",
+            identification->toolkit_version.major,
+            identification->toolkit_version.minor,
+            identification->toolkit_version.patch,
+            identification->toolkit_version.build,
+            identification->toolkit_version.release);
         break;
       case 0x3c08:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         identification->platform = mxf_utf16_to_utf8 (tag_data, tag_size);
+        GST_DEBUG ("  platform = %s", GST_STR_NULL (identification->platform));
         break;
       default:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size,
                 &identification->other_tags))
           goto error;
@@ -969,39 +995,6 @@ mxf_metadata_identification_parse (const MXFUL * key,
     size -= 4 + tag_size;
   }
 
-  GST_DEBUG ("Parsed identification:");
-  GST_DEBUG ("  instance uid = %s",
-      mxf_ul_to_string (&identification->instance_uid, str));
-  GST_DEBUG ("  generation uid = %s",
-      mxf_ul_to_string (&identification->generation_uid, str));
-  GST_DEBUG ("  company name = %s",
-      GST_STR_NULL (identification->company_name));
-  GST_DEBUG ("  product version = %u.%u.%u.%u.%u",
-      identification->product_version.major,
-      identification->product_version.minor,
-      identification->product_version.patch,
-      identification->product_version.build,
-      identification->product_version.release);
-  GST_DEBUG ("  version string = %s",
-      GST_STR_NULL (identification->version_string));
-  GST_DEBUG ("  product uid = %s",
-      mxf_ul_to_string (&identification->product_uid, str));
-  GST_DEBUG ("  modification date = %d/%u/%u %u:%u:%u.%u",
-      identification->modification_date.year,
-      identification->modification_date.month,
-      identification->modification_date.day,
-      identification->modification_date.hour,
-      identification->modification_date.minute,
-      identification->modification_date.second,
-      (identification->modification_date.quarter_msecond * 1000) / 256);
-  GST_DEBUG ("  toolkit version = %u.%u.%u.%u.%u",
-      identification->toolkit_version.major,
-      identification->toolkit_version.minor,
-      identification->toolkit_version.patch,
-      identification->toolkit_version.build,
-      identification->toolkit_version.release);
-  GST_DEBUG ("  platform = %s", GST_STR_NULL (identification->platform));
-
   return TRUE;
 
 error:
@@ -1035,36 +1028,39 @@ mxf_metadata_content_storage_parse (const MXFUL * key,
   guint16 tag, tag_size;
   const guint8 *tag_data;
   gchar str[48];
-  guint i;
 
   g_return_val_if_fail (data != NULL, FALSE);
 
   memset (content_storage, 0, sizeof (MXFMetadataContentStorage));
 
+  GST_DEBUG ("Parsing content storage:");
+
   while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
     if (tag_size == 0 || tag == 0x0000)
       goto next;
 
     switch (tag) {
       case 0x3c0a:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&content_storage->instance_uid, tag_data, 16);
+        GST_DEBUG ("  instance uid = %s",
+            mxf_ul_to_string (&content_storage->instance_uid, str));
         break;
       case 0x0102:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&content_storage->generation_uid, tag_data, 16);
+        GST_DEBUG ("  generation uid = %s",
+            mxf_ul_to_string (&content_storage->generation_uid, str));
         break;
       case 0x1901:{
         guint32 len;
         guint i;
 
-        GST_WRITE_UINT16_BE (data, 0x0000);
 
         len = GST_READ_UINT32_BE (tag_data);
+        GST_DEBUG ("  number of packages = %u", len);
         if (len == 0)
           break;
         if (GST_READ_UINT32_BE (tag_data + 4) != 16)
@@ -1074,18 +1070,21 @@ mxf_metadata_content_storage_parse (const MXFUL * key,
 
         content_storage->packages_uids = g_new (MXFUL, len);
         content_storage->n_packages = len;
-        for (i = 0; i < len; i++)
+        for (i = 0; i < len; i++) {
           memcpy (&content_storage->packages_uids[i], tag_data + 8 + i * 16,
               16);
+          GST_DEBUG ("  package %u = %s", i,
+              mxf_ul_to_string (&content_storage->packages_uids[i], str));
+        }
         break;
       }
       case 0x1902:{
         guint32 len;
         guint i;
 
-        GST_WRITE_UINT16_BE (data, 0x0000);
 
         len = GST_READ_UINT32_BE (tag_data);
+        GST_DEBUG ("  number of essence container data = %u", len);
         if (len == 0)
           break;
         if (GST_READ_UINT32_BE (tag_data + 4) != 16)
@@ -1095,13 +1094,16 @@ mxf_metadata_content_storage_parse (const MXFUL * key,
 
         content_storage->essence_container_data_uids = g_new (MXFUL, len);
         content_storage->n_essence_container_data = len;
-        for (i = 0; i < len; i++)
+        for (i = 0; i < len; i++) {
           memcpy (&content_storage->essence_container_data_uids[i],
               tag_data + 8 + i * 16, 16);
+          GST_DEBUG ("  essence container data %u = %s", i,
+              mxf_ul_to_string (&content_storage->essence_container_data_uids
+                  [i], str));
+        }
         break;
       }
       default:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size,
                 &content_storage->other_tags))
           goto error;
@@ -1113,23 +1115,6 @@ mxf_metadata_content_storage_parse (const MXFUL * key,
     size -= 4 + tag_size;
   }
 
-  GST_DEBUG ("Parsed content storage:");
-  GST_DEBUG ("  instance uid = %s",
-      mxf_ul_to_string (&content_storage->instance_uid, str));
-  GST_DEBUG ("  generation uid = %s",
-      mxf_ul_to_string (&content_storage->generation_uid, str));
-  GST_DEBUG ("  number of packages = %u", content_storage->n_packages);
-  GST_DEBUG ("  number of essence container data = %u",
-      content_storage->n_essence_container_data);
-
-  for (i = 0; i < content_storage->n_packages; i++)
-    GST_DEBUG ("  package %u = %s", i,
-        mxf_ul_to_string (&content_storage->packages_uids[i], str));
-  for (i = 0; i < content_storage->n_essence_container_data; i++)
-    GST_DEBUG ("  essence container data %u = %s", i,
-        mxf_ul_to_string (&content_storage->essence_container_data_uids[i],
-            str));
-
   return TRUE;
 
 error:
@@ -1168,43 +1153,48 @@ mxf_metadata_essence_container_data_parse (const MXFUL * key,
 
   memset (essence_container_data, 0, sizeof (MXFMetadataEssenceContainerData));
 
+  GST_DEBUG ("Parsing essence container data:");
+
   while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
     if (tag_size == 0 || tag == 0x0000)
       goto next;
 
     switch (tag) {
       case 0x3c0a:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&essence_container_data->instance_uid, tag_data, 16);
+        GST_DEBUG ("  instance uid = %s",
+            mxf_ul_to_string (&essence_container_data->instance_uid, str));
         break;
       case 0x2701:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 32)
           goto error;
         memcpy (&essence_container_data->linked_package_uid, tag_data, 32);
+        GST_DEBUG ("  linked package = %s",
+            mxf_umid_to_string (&essence_container_data->linked_package_uid,
+                str));
         break;
       case 0x0102:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&essence_container_data->generation_uid, tag_data, 16);
+        GST_DEBUG ("  generation uid = %s",
+            mxf_ul_to_string (&essence_container_data->generation_uid, str));
         break;
       case 0x3f06:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 4)
           goto error;
         essence_container_data->index_sid = GST_READ_UINT32_BE (tag_data);
+        GST_DEBUG ("  index sid = %u", essence_container_data->index_sid);
         break;
       case 0x3f07:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 4)
           goto error;
         essence_container_data->body_sid = GST_READ_UINT32_BE (tag_data);
+        GST_DEBUG ("  body sid = %u", essence_container_data->body_sid);
         break;
       default:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size,
                 &essence_container_data->other_tags))
           goto error;
@@ -1216,16 +1206,6 @@ mxf_metadata_essence_container_data_parse (const MXFUL * key,
     size -= 4 + tag_size;
   }
 
-  GST_DEBUG ("Parsed essence container data:");
-  GST_DEBUG ("  instance uid = %s",
-      mxf_ul_to_string (&essence_container_data->instance_uid, str));
-  GST_DEBUG ("  generation uid = %s",
-      mxf_ul_to_string (&essence_container_data->generation_uid, str));
-  GST_DEBUG ("  linked package = %s",
-      mxf_umid_to_string (&essence_container_data->linked_package_uid, str));
-  GST_DEBUG ("  index sid = %u", essence_container_data->index_sid);
-  GST_DEBUG ("  body sid = %u", essence_container_data->body_sid);
-
   return TRUE;
 
 error:
@@ -1254,56 +1234,78 @@ mxf_metadata_generic_package_parse (const MXFUL * key,
   guint16 tag, tag_size;
   const guint8 *tag_data;
   gchar str[96];
-  guint i;
 
   g_return_val_if_fail (data != NULL, FALSE);
 
   memset (generic_package, 0, sizeof (MXFMetadataGenericPackage));
 
+  GST_DEBUG ("Parsing generic package:");
+
   while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
     if (tag_size == 0 || tag == 0x0000)
       goto next;
 
     switch (tag) {
       case 0x3c0a:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&generic_package->instance_uid, tag_data, 16);
+        GST_DEBUG ("  instance uid = %s",
+            mxf_ul_to_string (&generic_package->instance_uid, str));
         break;
       case 0x4401:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 32)
           goto error;
         memcpy (&generic_package->package_uid, tag_data, 32);
+        GST_DEBUG ("  UMID = %s",
+            mxf_umid_to_string (&generic_package->package_uid, str));
         break;
       case 0x0102:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&generic_package->generation_uid, tag_data, 16);
+        GST_DEBUG ("  generation uid = %s",
+            mxf_ul_to_string (&generic_package->generation_uid, str));
         break;
       case 0x4402:
         generic_package->name = mxf_utf16_to_utf8 (tag_data, tag_size);
+        GST_DEBUG ("  name = %s", GST_STR_NULL (generic_package->name));
         break;
       case 0x4405:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (!mxf_timestamp_parse (&generic_package->package_creation_date,
                 tag_data, tag_size))
           goto error;
+        GST_DEBUG ("  creation date = %d/%u/%u %u:%u:%u.%u",
+            generic_package->package_creation_date.year,
+            generic_package->package_creation_date.month,
+            generic_package->package_creation_date.day,
+            generic_package->package_creation_date.hour,
+            generic_package->package_creation_date.minute,
+            generic_package->package_creation_date.second,
+            (generic_package->package_creation_date.quarter_msecond * 1000) /
+            256);
         break;
       case 0x4404:
         if (!mxf_timestamp_parse (&generic_package->package_modified_date,
                 tag_data, tag_size))
           goto error;
+        GST_DEBUG ("  modification date = %d/%u/%u %u:%u:%u.%u",
+            generic_package->package_modified_date.year,
+            generic_package->package_modified_date.month,
+            generic_package->package_modified_date.day,
+            generic_package->package_modified_date.hour,
+            generic_package->package_modified_date.minute,
+            generic_package->package_modified_date.second,
+            (generic_package->package_modified_date.quarter_msecond * 1000) /
+            256);
         break;
       case 0x4403:{
         guint32 len;
         guint i;
 
-        GST_WRITE_UINT16_BE (data, 0x0000);
 
         len = GST_READ_UINT32_BE (tag_data);
+        GST_DEBUG ("  number of tracks = %u", len);
         if (len == 0)
           break;
         if (GST_READ_UINT32_BE (tag_data + 4) != 16)
@@ -1313,20 +1315,23 @@ mxf_metadata_generic_package_parse (const MXFUL * key,
 
         generic_package->tracks_uids = g_new (MXFUL, len);
         generic_package->n_tracks = len;
-        for (i = 0; i < len; i++)
+        for (i = 0; i < len; i++) {
           memcpy (&generic_package->tracks_uids[i], tag_data + 8 + i * 16, 16);
+          GST_DEBUG ("  track %u = %s", i,
+              mxf_ul_to_string (&generic_package->tracks_uids[i], str));
+        }
         break;
       }
       case 0x4701:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
 
         generic_package->n_descriptors = 1;
         memcpy (&generic_package->descriptors_uid, tag_data, 16);
+        GST_DEBUG ("  descriptor = %s",
+            mxf_ul_to_string (&generic_package->descriptors_uid, str));
         break;
       default:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size,
                 &generic_package->other_tags))
           goto error;
@@ -1338,38 +1343,6 @@ mxf_metadata_generic_package_parse (const MXFUL * key,
     size -= 4 + tag_size;
   }
 
-  GST_DEBUG ("Parsed package:");
-  GST_DEBUG ("  instance uid = %s",
-      mxf_ul_to_string (&generic_package->instance_uid, str));
-  GST_DEBUG ("  generation uid = %s",
-      mxf_ul_to_string (&generic_package->generation_uid, str));
-  GST_DEBUG ("  UMID = %s", mxf_umid_to_string (&generic_package->package_uid,
-          str));
-  GST_DEBUG ("  name = %s", GST_STR_NULL (generic_package->name));
-  GST_DEBUG ("  creation date = %d/%u/%u %u:%u:%u.%u",
-      generic_package->package_creation_date.year,
-      generic_package->package_creation_date.month,
-      generic_package->package_creation_date.day,
-      generic_package->package_creation_date.hour,
-      generic_package->package_creation_date.minute,
-      generic_package->package_creation_date.second,
-      (generic_package->package_creation_date.quarter_msecond * 1000) / 256);
-  GST_DEBUG ("  modification date = %d/%u/%u %u:%u:%u.%u",
-      generic_package->package_modified_date.year,
-      generic_package->package_modified_date.month,
-      generic_package->package_modified_date.day,
-      generic_package->package_modified_date.hour,
-      generic_package->package_modified_date.minute,
-      generic_package->package_modified_date.second,
-      (generic_package->package_modified_date.quarter_msecond * 1000) / 256);
-  GST_DEBUG ("  descriptor = %s",
-      mxf_ul_to_string (&generic_package->descriptors_uid, str));
-  GST_DEBUG ("  number of tracks = %u", generic_package->n_tracks);
-
-  for (i = 0; i < generic_package->n_tracks; i++)
-    GST_DEBUG ("  track %u = %s", i,
-        mxf_ul_to_string (&generic_package->tracks_uids[i], str));
-
   return TRUE;
 
 error:
@@ -1410,58 +1383,63 @@ mxf_metadata_track_parse (const MXFUL * key,
 
   memset (track, 0, sizeof (MXFMetadataTrack));
 
+  GST_DEBUG ("Parsing track:");
+
   while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
     if (tag_size == 0 || tag == 0x0000)
       goto next;
 
     switch (tag) {
       case 0x3c0a:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&track->instance_uid, tag_data, 16);
+        GST_DEBUG ("  instance uid = %s",
+            mxf_ul_to_string (&track->instance_uid, str));
         break;
       case 0x0102:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&track->generation_uid, tag_data, 16);
+        GST_DEBUG ("  generation uid = %s",
+            mxf_ul_to_string (&track->generation_uid, str));
         break;
       case 0x4801:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 4)
           goto error;
         track->track_id = GST_READ_UINT32_BE (tag_data);
+        GST_DEBUG ("  track id = %u", track->track_id);
         break;
       case 0x4804:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 4)
           goto error;
         track->track_number = GST_READ_UINT32_BE (tag_data);
+        GST_DEBUG ("  track number = %u", track->track_number);
         break;
       case 0x4802:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         track->track_name = mxf_utf16_to_utf8 (tag_data, tag_size);
+        GST_DEBUG ("  track name = %s", GST_STR_NULL (track->track_name));
         break;
       case 0x4b01:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (!mxf_fraction_parse (&track->edit_rate, tag_data, tag_size))
           goto error;
+        GST_DEBUG ("  edit rate = %d/%d", track->edit_rate.n,
+            track->edit_rate.d);
         break;
       case 0x4b02:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 8)
           goto error;
         track->origin = GST_READ_UINT64_BE (tag_data);
+        GST_DEBUG ("  origin = %" G_GINT64_FORMAT, track->origin);
         break;
       case 0x4803:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&track->sequence_uid, tag_data, 16);
+        GST_DEBUG ("  sequence uid = %s",
+            mxf_ul_to_string (&track->sequence_uid, str));
         break;
       default:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size,
                 &track->other_tags))
           goto error;
@@ -1473,19 +1451,6 @@ mxf_metadata_track_parse (const MXFUL * key,
     size -= 4 + tag_size;
   }
 
-  GST_DEBUG ("Parsed track:");
-  GST_DEBUG ("  instance uid = %s", mxf_ul_to_string (&track->instance_uid,
-          str));
-  GST_DEBUG ("  generation uid = %s", mxf_ul_to_string (&track->generation_uid,
-          str));
-  GST_DEBUG ("  track id = %u", track->track_id);
-  GST_DEBUG ("  track number = %u", track->track_number);
-  GST_DEBUG ("  track name = %s", GST_STR_NULL (track->track_name));
-  GST_DEBUG ("  edit rate = %d/%d", track->edit_rate.n, track->edit_rate.d);
-  GST_DEBUG ("  origin = %" G_GINT64_FORMAT, track->origin);
-  GST_DEBUG ("  sequence uid = %s", mxf_ul_to_string (&track->sequence_uid,
-          str));
-
   return TRUE;
 
 error:
@@ -1560,48 +1525,52 @@ mxf_metadata_sequence_parse (const MXFUL * key,
   guint16 tag, tag_size;
   const guint8 *tag_data;
   gchar str[48];
-  guint i;
 
   g_return_val_if_fail (data != NULL, FALSE);
 
   memset (sequence, 0, sizeof (MXFMetadataSequence));
 
+  GST_DEBUG ("Parsing sequence:");
+
   while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
     if (tag_size == 0 || tag == 0x0000)
       goto next;
 
     switch (tag) {
       case 0x3c0a:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&sequence->instance_uid, tag_data, 16);
+        GST_DEBUG ("  instance uid = %s",
+            mxf_ul_to_string (&sequence->instance_uid, str));
         break;
       case 0x0102:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&sequence->generation_uid, tag_data, 16);
+        GST_DEBUG ("  generation uid = %s",
+            mxf_ul_to_string (&sequence->generation_uid, str));
         break;
       case 0x0201:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&sequence->data_definition, tag_data, 16);
+        GST_DEBUG ("  data definition = %s",
+            mxf_ul_to_string (&sequence->data_definition, str));
         break;
       case 0x0202:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 8)
           goto error;
         sequence->duration = GST_READ_UINT64_BE (tag_data);
+        GST_DEBUG ("  duration = %" G_GINT64_FORMAT, sequence->duration);
         break;
       case 0x1001:{
         guint32 len;
         guint i;
 
-        GST_WRITE_UINT16_BE (data, 0x0000);
 
         len = GST_READ_UINT32_BE (tag_data);
+        GST_DEBUG ("  number of structural components = %u", len);
         if (len == 0)
           break;
         if (GST_READ_UINT32_BE (tag_data + 4) != 16)
@@ -1611,13 +1580,15 @@ mxf_metadata_sequence_parse (const MXFUL * key,
 
         sequence->structural_components_uids = g_new (MXFUL, len);
         sequence->n_structural_components = len;
-        for (i = 0; i < len; i++)
+        for (i = 0; i < len; i++) {
           memcpy (&sequence->structural_components_uids[i],
               tag_data + 8 + i * 16, 16);
+          GST_DEBUG ("  structural component %u = %s", i,
+              mxf_ul_to_string (&sequence->structural_components_uids[i], str));
+        }
         break;
       }
       default:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size,
                 &sequence->other_tags))
           goto error;
@@ -1629,22 +1600,6 @@ mxf_metadata_sequence_parse (const MXFUL * key,
     size -= 4 + tag_size;
   }
 
-  GST_DEBUG ("Parsed sequence:");
-  GST_DEBUG ("  instance uid = %s", mxf_ul_to_string (&sequence->instance_uid,
-          str));
-  GST_DEBUG ("  generation uid = %s",
-      mxf_ul_to_string (&sequence->generation_uid, str));
-  GST_DEBUG ("  data definition = %s",
-      mxf_ul_to_string (&sequence->data_definition, str));
-  GST_DEBUG ("  duration = %" G_GINT64_FORMAT, sequence->duration);
-  GST_DEBUG ("  number of structural components = %u",
-      sequence->n_structural_components);
-
-  for (i = 0; i < sequence->n_structural_components; i++)
-    GST_DEBUG ("  structural component %u = %s", i,
-        mxf_ul_to_string (&sequence->structural_components_uids[i], str));
-
-
   return TRUE;
 
 error:
@@ -1681,7 +1636,13 @@ mxf_metadata_structural_component_parse (const MXFUL * key,
 
   memset (component, 0, sizeof (MXFMetadataStructuralComponent));
 
+  GST_DEBUG ("Parsing structural component:");
+
   component->type = type;
+  GST_DEBUG ("  type = %s",
+      (component->type ==
+          MXF_METADATA_TIMECODE_COMPONENT) ? "timecode component" :
+      "source clip");
 
   while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
     if (tag_size == 0 || tag == 0x0000)
@@ -1689,85 +1650,94 @@ mxf_metadata_structural_component_parse (const MXFUL * key,
 
     switch (tag) {
       case 0x3c0a:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&component->instance_uid, tag_data, 16);
+        GST_DEBUG ("  instance uid = %s",
+            mxf_ul_to_string (&component->instance_uid, str));
         break;
       case 0x0102:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&component->generation_uid, tag_data, 16);
+        GST_DEBUG ("  generation uid = %s",
+            mxf_ul_to_string (&component->generation_uid, str));
         break;
       case 0x0201:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&component->data_definition, tag_data, 16);
+        GST_DEBUG ("  data definition = %s",
+            mxf_ul_to_string (&component->data_definition, str));
         break;
       case 0x0202:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 8)
           goto error;
         component->duration = GST_READ_UINT64_BE (tag_data);
+        GST_DEBUG ("  duration = %" G_GINT64_FORMAT, component->duration);
         break;
         /* Timecode component specifics */
       case 0x1502:
         if (type != MXF_METADATA_TIMECODE_COMPONENT)
           goto DFLT;
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 2)
           goto error;
         component->timecode_component.rounded_timecode_base =
             GST_READ_UINT16_BE (tag_data);
+        GST_DEBUG ("  rounded timecode base = %u",
+            component->timecode_component.rounded_timecode_base);
         break;
       case 0x1501:
         if (type != MXF_METADATA_TIMECODE_COMPONENT)
           goto DFLT;
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 8)
           goto error;
         component->timecode_component.start_timecode =
             GST_READ_UINT64_BE (tag_data);
+        GST_DEBUG ("  start timecode = %" G_GINT64_FORMAT,
+            component->timecode_component.start_timecode);
         break;
       case 0x1503:
         if (type != MXF_METADATA_TIMECODE_COMPONENT)
           goto DFLT;
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 1)
           goto error;
         component->timecode_component.drop_frame =
             (GST_READ_UINT8 (tag_data) != 0);
+        GST_DEBUG ("  drop frame = %s",
+            (component->timecode_component.drop_frame) ? "yes" : "no");
         break;
         /* Source clip specifics */
       case 0x1201:
         if (type != MXF_METADATA_SOURCE_CLIP)
           goto DFLT;
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 8)
           goto error;
         component->source_clip.start_position = GST_READ_UINT64_BE (tag_data);
+        GST_DEBUG ("  start position = %" G_GINT64_FORMAT,
+            component->source_clip.start_position);
         break;
       case 0x1101:
         if (type != MXF_METADATA_SOURCE_CLIP)
           goto DFLT;
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 32)
           goto error;
         memcpy (&component->source_clip.source_package_id, tag_data, 32);
+        GST_DEBUG ("  source package id = %s",
+            mxf_umid_to_string (&component->source_clip.source_package_id,
+                str));
         break;
       case 0x1102:
         if (type != MXF_METADATA_SOURCE_CLIP)
           goto DFLT;
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 4)
           goto error;
         component->source_clip.source_track_id = GST_READ_UINT32_BE (tag_data);
+        GST_DEBUG ("  source track id = %u",
+            component->source_clip.source_track_id);
         break;
       DFLT:
       default:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size,
                 &component->other_tags))
           goto error;
@@ -1779,35 +1749,6 @@ mxf_metadata_structural_component_parse (const MXFUL * key,
     size -= 4 + tag_size;
   }
 
-  GST_DEBUG ("Parsed structural component:");
-  GST_DEBUG ("  instance uid = %s", mxf_ul_to_string (&component->instance_uid,
-          str));
-  GST_DEBUG ("  generation uid = %s",
-      mxf_ul_to_string (&component->generation_uid, str));
-  GST_DEBUG ("  type = %s",
-      (component->type ==
-          MXF_METADATA_TIMECODE_COMPONENT) ? "timecode component" :
-      "source clip");
-  GST_DEBUG ("  data definition = %s",
-      mxf_ul_to_string (&component->data_definition, str));
-  GST_DEBUG ("  duration = %" G_GINT64_FORMAT, component->duration);
-
-  if (component->type == MXF_METADATA_TIMECODE_COMPONENT) {
-    GST_DEBUG ("  start timecode = %" G_GINT64_FORMAT,
-        component->timecode_component.start_timecode);
-    GST_DEBUG ("  rounded timecode base = %u",
-        component->timecode_component.rounded_timecode_base);
-    GST_DEBUG ("  drop frame = %s",
-        (component->timecode_component.drop_frame) ? "yes" : "no");
-  } else {
-    GST_DEBUG ("  start position = %" G_GINT64_FORMAT,
-        component->source_clip.start_position);
-    GST_DEBUG ("  source package id = %s",
-        mxf_umid_to_string (&component->source_clip.source_package_id, str));
-    GST_DEBUG ("  source track id = %u",
-        component->source_clip.source_track_id);
-  }
-
   return TRUE;
 
 error:
@@ -1829,85 +1770,102 @@ void mxf_metadata_structural_component_reset
 }
 
 gboolean
-mxf_metadata_generic_descriptor_parse (const MXFUL * key,
+mxf_metadata_descriptor_parse (const MXFUL * key,
     MXFMetadataGenericDescriptor * descriptor,
-    const MXFPrimerPack * primer, guint16 type, const guint8 * data, guint size)
+    const MXFPrimerPack * primer, guint16 type,
+    const guint8 * data, guint size,
+    MXFMetadataDescriptorHandleTag handle_tag, MXFMetadataDescriptorReset reset)
 {
   guint16 tag, tag_size;
   const guint8 *tag_data;
-  gchar str[48];
-  guint i;
 
   g_return_val_if_fail (data != NULL, FALSE);
+  g_return_val_if_fail (key != NULL, FALSE);
+  g_return_val_if_fail (primer != NULL, FALSE);
+  g_return_val_if_fail (descriptor != NULL, FALSE);
+  g_return_val_if_fail (handle_tag != NULL, FALSE);
+  g_return_val_if_fail (reset != NULL, FALSE);
 
-  memset (descriptor, 0, sizeof (MXFMetadataGenericDescriptor));
+  reset (descriptor);
 
   descriptor->type = type;
 
+  GST_DEBUG ("Parsing descriptor of type 0x%04x:", type);
+
   while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
     if (tag_size == 0 || tag == 0x0000)
       goto next;
 
-    switch (tag) {
-      case 0x3c0a:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 16)
-          goto error;
-        memcpy (&descriptor->instance_uid, tag_data, 16);
-        break;
-      case 0x0102:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 16)
-          goto error;
-        memcpy (&descriptor->generation_uid, tag_data, 16);
-        break;
-      case 0x2f01:{
-        guint32 len;
-        guint i;
-
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size < 8)
-          goto error;
-
-        len = GST_READ_UINT32_BE (tag_data);
-        if (len == 0)
-          goto next;
+    if (!handle_tag (descriptor, primer, tag, tag_data, tag_size))
+      if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size,
+              &((MXFMetadataGenericDescriptor *) descriptor)->other_tags))
+        goto next;
 
-        if (GST_READ_UINT32_BE (tag_data + 4) != 16)
-          goto error;
-
-        descriptor->locators_uids = g_new (MXFUL, len);
-        descriptor->n_locators = len;
-        for (i = 0; i < len; i++)
-          memcpy (&descriptor->locators_uids[i], tag_data + 8 + i * 16, 16);
-        break;
-      }
-    }
   next:
-
     data += 4 + tag_size;
     size -= 4 + tag_size;
   }
+  return TRUE;
+}
 
-  GST_DEBUG ("Parsed generic descriptor:");
-  GST_DEBUG ("  instance uid = %s", mxf_ul_to_string (&descriptor->instance_uid,
-          str));
-  GST_DEBUG ("  generation uid = %s",
-      mxf_ul_to_string (&descriptor->generation_uid, str));
-  GST_DEBUG ("  type = %u", descriptor->type);
-  GST_DEBUG ("  number of locators = %u", descriptor->n_locators);
+gboolean
+mxf_metadata_generic_descriptor_handle_tag (MXFMetadataGenericDescriptor *
+    descriptor, const MXFPrimerPack * primer, guint16 tag,
+    const guint8 * tag_data, guint16 tag_size)
+{
+  gboolean ret = FALSE;
+  gchar str[48];
 
-  for (i = 0; i < descriptor->n_locators; i++)
-    GST_DEBUG ("  locator %u = %s", i,
-        mxf_ul_to_string (&descriptor->locators_uids[i], str));
+  switch (tag) {
+    case 0x3c0a:
+      if (tag_size != 16)
+        goto error;
+      memcpy (&descriptor->instance_uid, tag_data, 16);
+      GST_DEBUG ("  instance uid = %s",
+          mxf_ul_to_string (&descriptor->instance_uid, str));
+      ret = TRUE;
+      break;
+    case 0x0102:
+      if (tag_size != 16)
+        goto error;
+      memcpy (&descriptor->generation_uid, tag_data, 16);
+      GST_DEBUG ("  generation uid = %s",
+          mxf_ul_to_string (&descriptor->generation_uid, str));
+      ret = TRUE;
+      break;
+    case 0x2f01:{
+      guint32 len;
+      guint i;
+
+      if (tag_size < 8)
+        goto error;
+
+      len = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  number of locators = %u", len);
+      if (len == 0)
+        return TRUE;
+
+      if (GST_READ_UINT32_BE (tag_data + 4) != 16)
+        goto error;
+
+      descriptor->locators_uids = g_new (MXFUL, len);
+      descriptor->n_locators = len;
+      for (i = 0; i < len; i++) {
+        memcpy (&descriptor->locators_uids[i], tag_data + 8 + i * 16, 16);
+        GST_DEBUG ("  locator %u = %s", i,
+            mxf_ul_to_string (&descriptor->locators_uids[i], str));
+      }
+      ret = TRUE;
+      break;
+    }
+  }
 
-  return TRUE;
+  return ret;
 
 error:
-  GST_ERROR ("Invalid generic descriptor");
-  mxf_metadata_generic_descriptor_reset (descriptor);
+  GST_ERROR ("Invalid generic descriptor tag 0x%04x of size %u", tag, tag_size);
 
-  return FALSE;
+  return TRUE;
 }
 
 void mxf_metadata_generic_descriptor_reset
@@ -1915,11 +1873,6 @@ void mxf_metadata_generic_descriptor_reset
 {
   g_return_if_fail (descriptor != NULL);
 
-  switch (descriptor->type) {
-    case MXF_METADATA_FILE_DESCRIPTOR:
-      break;
-  }
-
   if (descriptor->locators_uids)
     g_free (descriptor->locators_uids);
 
@@ -1933,91 +1886,67 @@ void mxf_metadata_generic_descriptor_reset
 }
 
 gboolean
-mxf_metadata_file_descriptor_parse (const MXFUL * key,
-    MXFMetadataFileDescriptor * descriptor,
-    const MXFPrimerPack * primer, guint16 type, const guint8 * data, guint size)
+mxf_metadata_file_descriptor_handle_tag (MXFMetadataGenericDescriptor * d,
+    const MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
+    guint16 tag_size)
 {
-  guint16 tag, tag_size;
-  const guint8 *tag_data;
+  MXFMetadataFileDescriptor *descriptor = (MXFMetadataFileDescriptor *) d;
+  gboolean ret = FALSE;
   gchar str[48];
 
-  g_return_val_if_fail (data != NULL, FALSE);
-
-  memset (descriptor, 0, sizeof (MXFMetadataFileDescriptor));
-
-  if (!mxf_metadata_generic_descriptor_parse (key,
-          (MXFMetadataGenericDescriptor *) descriptor, primer, type, data,
-          size))
-    goto error;
-
   descriptor->parent.is_file_descriptor = TRUE;
 
-  while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
-    if (tag_size == 0 || tag == 0x0000)
-      goto next;
-
-    switch (tag) {
-      case 0x3006:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->linked_track_id = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3001:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (!mxf_fraction_parse (&descriptor->sample_rate, tag_data, tag_size))
-          goto error;
-        break;
-      case 0x3002:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 8)
-          goto error;
-        descriptor->container_duration = GST_READ_UINT64_BE (tag_data);
-        break;
-      case 0x3004:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 16)
-          goto error;
-        memcpy (&descriptor->essence_container, tag_data, 16);
-        break;
-      case 0x3005:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 16)
-          goto error;
-        memcpy (&descriptor->codec, tag_data, 16);
-        break;
-      default:
-        if (type != MXF_METADATA_FILE_DESCRIPTOR)
-          goto next;
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size,
-                &((MXFMetadataGenericDescriptor *) descriptor)->other_tags))
-          goto error;
-        break;
-    }
-
-  next:
-    data += 4 + tag_size;
-    size -= 4 + tag_size;
+  switch (tag) {
+    case 0x3006:
+      if (tag_size != 4)
+        goto error;
+      descriptor->linked_track_id = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  linked track id = %u", descriptor->linked_track_id);
+      ret = TRUE;
+      break;
+    case 0x3001:
+      if (!mxf_fraction_parse (&descriptor->sample_rate, tag_data, tag_size))
+        goto error;
+      GST_DEBUG ("  sample rate = %d/%d", descriptor->sample_rate.n,
+          descriptor->sample_rate.d);
+      ret = TRUE;
+      break;
+    case 0x3002:
+      if (tag_size != 8)
+        goto error;
+      descriptor->container_duration = GST_READ_UINT64_BE (tag_data);
+      GST_DEBUG ("  container duration = %" G_GINT64_FORMAT,
+          descriptor->container_duration);
+      ret = TRUE;
+      break;
+    case 0x3004:
+      if (tag_size != 16)
+        goto error;
+      memcpy (&descriptor->essence_container, tag_data, 16);
+      GST_DEBUG ("  essence container = %s",
+          mxf_ul_to_string (&descriptor->essence_container, str));
+      ret = TRUE;
+      break;
+    case 0x3005:
+      if (tag_size != 16)
+        goto error;
+      memcpy (&descriptor->codec, tag_data, 16);
+      GST_DEBUG ("  codec = %s", mxf_ul_to_string (&descriptor->codec, str));
+      ret = TRUE;
+      break;
+    default:
+      ret =
+          mxf_metadata_generic_descriptor_handle_tag (d, primer, tag, tag_data,
+          tag_size);
+      break;
   }
 
-  GST_DEBUG ("Parsed file descriptor:");
-  GST_DEBUG ("  linked track id = %u", descriptor->linked_track_id);
-  GST_DEBUG ("  sample rate = %d/%d", descriptor->sample_rate.n,
-      descriptor->sample_rate.d);
-  GST_DEBUG ("  container duration = %" G_GINT64_FORMAT,
-      descriptor->container_duration);
-  GST_DEBUG ("  essence container = %s",
-      mxf_ul_to_string (&descriptor->essence_container, str));
-  GST_DEBUG ("  codec = %s", mxf_ul_to_string (&descriptor->codec, str));
-
-  return TRUE;
+  return ret;
 
 error:
-  GST_ERROR ("Invalid file descriptor");
-  mxf_metadata_file_descriptor_reset (descriptor);
+  GST_ERROR ("Invalid file descriptor tag 0x%04x of size %u", tag, tag_size);
 
-  return FALSE;
+  return TRUE;
 }
 
 void
@@ -2032,110 +1961,89 @@ mxf_metadata_file_descriptor_reset (MXFMetadataFileDescriptor * descriptor)
 }
 
 gboolean
-mxf_metadata_generic_sound_essence_descriptor_parse (const MXFUL * key,
-    MXFMetadataGenericSoundEssenceDescriptor * descriptor,
-    const MXFPrimerPack * primer, guint16 type, const guint8 * data, guint size)
+    mxf_metadata_generic_sound_essence_descriptor_handle_tag
+    (MXFMetadataGenericDescriptor * d, const MXFPrimerPack * primer,
+    guint16 tag, const guint8 * tag_data, guint16 tag_size)
 {
-  guint16 tag, tag_size;
-  const guint8 *tag_data;
+  MXFMetadataGenericSoundEssenceDescriptor *descriptor =
+      (MXFMetadataGenericSoundEssenceDescriptor *) d;
+  gboolean ret = FALSE;
   gchar str[48];
 
-  g_return_val_if_fail (data != NULL, FALSE);
-
-  memset (descriptor, 0, sizeof (MXFMetadataGenericSoundEssenceDescriptor));
-
-  if (!mxf_metadata_file_descriptor_parse (key,
-          (MXFMetadataFileDescriptor *) descriptor, primer, type, data, size))
-    goto error;
-
-  while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
-    if (tag_size == 0 || tag == 0x0000)
-      goto next;
-
-    switch (tag) {
-      case 0x3d03:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (!mxf_fraction_parse (&descriptor->audio_sampling_rate, tag_data,
-                tag_size))
-          goto error;
-        break;
-      case 0x3d02:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 1)
-          goto error;
-        descriptor->locked = (GST_READ_UINT8 (tag_data) != 0);
-        break;
-      case 0x3d04:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 1)
-          goto error;
-        descriptor->audio_ref_level = GST_READ_UINT8 (tag_data);
-        break;
-      case 0x3d05:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 1)
-          goto error;
-        descriptor->electro_spatial_formulation = GST_READ_UINT8 (tag_data);
-        break;
-      case 0x3d07:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->channel_count = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3d01:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->quantization_bits = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3d0c:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 1)
-          goto error;
-        descriptor->dial_norm = GST_READ_UINT8 (tag_data);
-        break;
-      case 0x3d06:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 16)
-          goto error;
-        memcpy (&descriptor->sound_essence_compression, tag_data, 16);
-        break;
-      default:
-        if (type != MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR)
-          goto next;
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size,
-                &((MXFMetadataGenericDescriptor *) descriptor)->other_tags))
-          goto error;
-        break;
-    }
-
-  next:
-    data += 4 + tag_size;
-    size -= 4 + tag_size;
+  switch (tag) {
+    case 0x3d03:
+      if (!mxf_fraction_parse (&descriptor->audio_sampling_rate, tag_data,
+              tag_size))
+        goto error;
+      GST_DEBUG ("  audio sampling rate = %d/%d",
+          descriptor->audio_sampling_rate.n, descriptor->audio_sampling_rate.d);
+      ret = TRUE;
+      break;
+    case 0x3d02:
+      if (tag_size != 1)
+        goto error;
+      descriptor->locked = (GST_READ_UINT8 (tag_data) != 0);
+      GST_DEBUG ("  locked = %s", (descriptor->locked) ? "yes" : "no");
+      ret = TRUE;
+      break;
+    case 0x3d04:
+      if (tag_size != 1)
+        goto error;
+      descriptor->audio_ref_level = GST_READ_UINT8 (tag_data);
+      GST_DEBUG ("  audio ref level = %d", descriptor->audio_ref_level);
+      ret = TRUE;
+      break;
+    case 0x3d05:
+      if (tag_size != 1)
+        goto error;
+      descriptor->electro_spatial_formulation = GST_READ_UINT8 (tag_data);
+      GST_DEBUG ("  electro spatial formulation = %u",
+          descriptor->electro_spatial_formulation);
+      ret = TRUE;
+      break;
+    case 0x3d07:
+      if (tag_size != 4)
+        goto error;
+      descriptor->channel_count = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  channel count = %u", descriptor->channel_count);
+      ret = TRUE;
+      break;
+    case 0x3d01:
+      if (tag_size != 4)
+        goto error;
+      descriptor->quantization_bits = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  quantization bits = %u", descriptor->quantization_bits);
+      ret = TRUE;
+      break;
+    case 0x3d0c:
+      if (tag_size != 1)
+        goto error;
+      descriptor->dial_norm = GST_READ_UINT8 (tag_data);
+      GST_DEBUG ("  dial norm = %d", descriptor->dial_norm);
+      ret = TRUE;
+      break;
+    case 0x3d06:
+      if (tag_size != 16)
+        goto error;
+      memcpy (&descriptor->sound_essence_compression, tag_data, 16);
+      GST_DEBUG ("  sound essence compression = %s",
+          mxf_ul_to_string (&descriptor->sound_essence_compression, str));
+      ret = TRUE;
+      break;
+    default:
+      ret =
+          mxf_metadata_file_descriptor_handle_tag (d, primer, tag, tag_data,
+          tag_size);
+      break;
   }
 
-  GST_DEBUG ("Parsed generic sound essence descriptor:");
-  GST_DEBUG ("  audio sampling rate = %d/%d", descriptor->audio_sampling_rate.n,
-      descriptor->audio_sampling_rate.d);
-  GST_DEBUG ("  locked = %s", (descriptor->locked) ? "yes" : "no");
-  GST_DEBUG ("  audio ref level = %d", descriptor->audio_ref_level);
-  GST_DEBUG ("  electro spatial formulation = %u",
-      descriptor->electro_spatial_formulation);
-  GST_DEBUG ("  channel count = %u", descriptor->channel_count);
-  GST_DEBUG ("  quantization bits = %u", descriptor->quantization_bits);
-  GST_DEBUG ("  dial norm = %d", descriptor->dial_norm);
-  GST_DEBUG ("  sound essence compression = %s",
-      mxf_ul_to_string (&descriptor->sound_essence_compression, str));
-
-  return TRUE;
+  return ret;
 
 error:
-  GST_ERROR ("Invalid generic sound essence descriptor");
-  mxf_metadata_generic_sound_essence_descriptor_reset (descriptor);
+  GST_ERROR ("Invalid generic sound essence descriptor tag 0x%04x of size %u",
+      tag, tag_size);
 
-  return FALSE;
+  return TRUE;
 }
 
 void mxf_metadata_generic_sound_essence_descriptor_reset
@@ -2149,233 +2057,215 @@ void mxf_metadata_generic_sound_essence_descriptor_reset
 }
 
 gboolean
-mxf_metadata_generic_picture_essence_descriptor_parse (const MXFUL * key,
-    MXFMetadataGenericPictureEssenceDescriptor * descriptor,
-    const MXFPrimerPack * primer, guint16 type, const guint8 * data, guint size)
+    mxf_metadata_generic_picture_essence_descriptor_handle_tag
+    (MXFMetadataGenericDescriptor * d, const MXFPrimerPack * primer,
+    guint16 tag, const guint8 * tag_data, guint16 tag_size)
 {
-  guint16 tag, tag_size;
-  const guint8 *tag_data;
+  MXFMetadataGenericPictureEssenceDescriptor *descriptor =
+      (MXFMetadataGenericPictureEssenceDescriptor *) d;
+  gboolean ret = FALSE;
   gchar str[48];
 
-  g_return_val_if_fail (data != NULL, FALSE);
-
-  memset (descriptor, 0, sizeof (MXFMetadataGenericPictureEssenceDescriptor));
-
-  if (!mxf_metadata_file_descriptor_parse (key,
-          (MXFMetadataFileDescriptor *) descriptor, primer, type, data, size))
-    goto error;
-
-  while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
-    if (tag_size == 0 || tag == 0x0000)
-      goto next;
-
-    switch (tag) {
-      case 0x3215:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 1)
-          goto error;
-        descriptor->signal_standard = GST_READ_UINT8 (tag_data);
-        break;
-      case 0x320c:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 1)
-          goto error;
-        descriptor->frame_layout = GST_READ_UINT8 (tag_data);
-        break;
-      case 0x3203:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->stored_width = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3202:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->stored_height = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3216:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->stored_f2_offset = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3205:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->sampled_width = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3204:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->sampled_height = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3206:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->sampled_x_offset = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3207:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->sampled_y_offset = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3208:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->display_height = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3209:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->display_width = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x320a:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->display_x_offset = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x320b:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->display_y_offset = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3217:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->display_f2_offset = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x320e:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (!mxf_fraction_parse (&descriptor->aspect_ratio, tag_data, tag_size))
-          goto error;
-        break;
-      case 0x3218:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 1)
-          goto error;
-        descriptor->active_format_descriptor = GST_READ_UINT8 (tag_data);
-        break;
-      case 0x320d:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size < 8)
-          goto error;
-
-        if (GST_READ_UINT32_BE (tag_data) == 0)
-          goto next;
+  switch (tag) {
+    case 0x3215:
+      if (tag_size != 1)
+        goto error;
+      descriptor->signal_standard = GST_READ_UINT8 (tag_data);
+      GST_DEBUG ("  signal standard = %u", descriptor->signal_standard);
+      ret = TRUE;
+      break;
+    case 0x320c:
+      if (tag_size != 1)
+        goto error;
+      descriptor->frame_layout = GST_READ_UINT8 (tag_data);
+      GST_DEBUG ("  frame layout = %u", descriptor->frame_layout);
+      ret = TRUE;
+      break;
+    case 0x3203:
+      if (tag_size != 4)
+        goto error;
+      descriptor->stored_width = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  stored width = %u", descriptor->stored_width);
+      ret = TRUE;
+      break;
+    case 0x3202:
+      if (tag_size != 4)
+        goto error;
+      descriptor->stored_height = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  stored height = %u", descriptor->stored_height);
+      ret = TRUE;
+      break;
+    case 0x3216:
+      if (tag_size != 4)
+        goto error;
+      descriptor->stored_f2_offset = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  stored f2 offset = %d", descriptor->stored_f2_offset);
+      ret = TRUE;
+      break;
+    case 0x3205:
+      if (tag_size != 4)
+        goto error;
+      descriptor->sampled_width = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  sampled width = %u", descriptor->sampled_width);
+      ret = TRUE;
+      break;
+    case 0x3204:
+      if (tag_size != 4)
+        goto error;
+      descriptor->sampled_height = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  sampled height = %u", descriptor->sampled_height);
+      ret = TRUE;
+      break;
+    case 0x3206:
+      if (tag_size != 4)
+        goto error;
+      descriptor->sampled_x_offset = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  sampled x offset = %d", descriptor->sampled_x_offset);
+      ret = TRUE;
+      break;
+    case 0x3207:
+      if (tag_size != 4)
+        goto error;
+      descriptor->sampled_y_offset = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  sampled y offset = %d", descriptor->sampled_y_offset);
+      ret = TRUE;
+      break;
+    case 0x3208:
+      if (tag_size != 4)
+        goto error;
+      descriptor->display_height = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  display height = %u", descriptor->display_height);
+      ret = TRUE;
+      break;
+    case 0x3209:
+      if (tag_size != 4)
+        goto error;
+      descriptor->display_width = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  display width = %u", descriptor->display_width);
+      ret = TRUE;
+      break;
+    case 0x320a:
+      if (tag_size != 4)
+        goto error;
+      descriptor->display_x_offset = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  display x offset = %d", descriptor->display_x_offset);
+      ret = TRUE;
+      break;
+    case 0x320b:
+      if (tag_size != 4)
+        goto error;
+      descriptor->display_y_offset = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  display y offset = %d", descriptor->display_y_offset);
+      ret = TRUE;
+      break;
+    case 0x3217:
+      if (tag_size != 4)
+        goto error;
+      descriptor->display_f2_offset = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  display f2 offset = %d", descriptor->display_f2_offset);
+      ret = TRUE;
+      break;
+    case 0x320e:
+      if (!mxf_fraction_parse (&descriptor->aspect_ratio, tag_data, tag_size))
+        goto error;
+      GST_DEBUG ("  aspect ratio = %d/%d", descriptor->aspect_ratio.n,
+          descriptor->aspect_ratio.d);
+      ret = TRUE;
+      break;
+    case 0x3218:
+      if (tag_size != 1)
+        goto error;
+      descriptor->active_format_descriptor = GST_READ_UINT8 (tag_data);
+      GST_DEBUG ("  active format descriptor = %u",
+          descriptor->active_format_descriptor);
+      ret = TRUE;
+      break;
+    case 0x320d:
+      if (tag_size < 8)
+        goto error;
 
-        if (GST_READ_UINT32_BE (tag_data) != 2 &&
-            GST_READ_UINT32_BE (tag_data + 4) != 4)
-          goto error;
+      if (GST_READ_UINT32_BE (tag_data) == 0)
+        return TRUE;
 
-        if (tag_size != 16)
-          goto error;
+      if (GST_READ_UINT32_BE (tag_data) != 2 &&
+          GST_READ_UINT32_BE (tag_data + 4) != 4)
+        goto error;
 
-        descriptor->video_line_map[0] = GST_READ_UINT32_BE (tag_data + 8);
-        descriptor->video_line_map[1] = GST_READ_UINT32_BE (tag_data + 12);
-        break;
-      case 0x320f:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 1)
-          goto error;
-        descriptor->alpha_transparency = GST_READ_UINT8 (tag_data);
-        break;
-      case 0x3210:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 16)
-          goto error;
-        memcpy (&descriptor->capture_gamma, tag_data, 16);
-        break;
-      case 0x3211:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->image_alignment_offset = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3213:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->image_start_offset = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3214:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->image_end_offset = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3212:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 1)
-          goto error;
-        descriptor->field_dominance = GST_READ_UINT8 (tag_data);
-        break;
-      case 0x3201:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 16)
-          goto error;
-        memcpy (&descriptor->picture_essence_coding, tag_data, 16);
-        break;
-      default:
-        if (type != MXF_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR)
-          goto next;
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size,
-                &((MXFMetadataGenericDescriptor *) descriptor)->other_tags))
-          goto error;
-        break;
-    }
+      if (tag_size != 16)
+        goto error;
 
-  next:
-    data += 4 + tag_size;
-    size -= 4 + tag_size;
+      descriptor->video_line_map[0] = GST_READ_UINT32_BE (tag_data + 8);
+      descriptor->video_line_map[1] = GST_READ_UINT32_BE (tag_data + 12);
+      GST_DEBUG ("  video line map = {%i, %i}", descriptor->video_line_map[0],
+          descriptor->video_line_map[1]);
+      ret = TRUE;
+      break;
+    case 0x320f:
+      if (tag_size != 1)
+        goto error;
+      descriptor->alpha_transparency = GST_READ_UINT8 (tag_data);
+      GST_DEBUG ("  alpha transparency = %u", descriptor->alpha_transparency);
+      ret = TRUE;
+      break;
+    case 0x3210:
+      if (tag_size != 16)
+        goto error;
+      memcpy (&descriptor->capture_gamma, tag_data, 16);
+      GST_DEBUG ("  capture gamma = %s",
+          mxf_ul_to_string (&descriptor->capture_gamma, str));
+      ret = TRUE;
+      break;
+    case 0x3211:
+      if (tag_size != 4)
+        goto error;
+      descriptor->image_alignment_offset = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  image alignment offset = %u",
+          descriptor->image_alignment_offset);
+      ret = TRUE;
+      break;
+    case 0x3213:
+      if (tag_size != 4)
+        goto error;
+      descriptor->image_start_offset = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  image start offset = %u", descriptor->image_start_offset);
+      ret = TRUE;
+      break;
+    case 0x3214:
+      if (tag_size != 4)
+        goto error;
+      descriptor->image_end_offset = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  image end offset = %u", descriptor->image_end_offset);
+      ret = TRUE;
+      break;
+    case 0x3212:
+      if (tag_size != 1)
+        goto error;
+      descriptor->field_dominance = GST_READ_UINT8 (tag_data);
+      GST_DEBUG ("  field dominance = %u", descriptor->field_dominance);
+      ret = TRUE;
+      break;
+    case 0x3201:
+      if (tag_size != 16)
+        goto error;
+      memcpy (&descriptor->picture_essence_coding, tag_data, 16);
+      GST_DEBUG ("  picture essence coding = %s",
+          mxf_ul_to_string (&descriptor->picture_essence_coding, str));
+      ret = TRUE;
+      break;
+    default:
+      ret =
+          mxf_metadata_file_descriptor_handle_tag (d, primer, tag, tag_data,
+          tag_size);
+      break;
   }
 
-  GST_DEBUG ("Parsed generic picture essence descriptor:");
-  GST_DEBUG ("  signal standard = %u", descriptor->signal_standard);
-  GST_DEBUG ("  frame layout = %u", descriptor->frame_layout);
-  GST_DEBUG ("  stored size = %ux%u (f2 = %d)", descriptor->stored_width,
-      descriptor->stored_height, descriptor->stored_f2_offset);
-  GST_DEBUG ("  sampled size = %ux%u (offset = %d x %d)",
-      descriptor->sampled_width, descriptor->sampled_height,
-      descriptor->sampled_x_offset, descriptor->sampled_y_offset);
-  GST_DEBUG ("  display size = %ux%u (f2 = %d, offset = %d x %d)",
-      descriptor->display_height, descriptor->display_width,
-      descriptor->display_x_offset, descriptor->display_y_offset,
-      descriptor->display_f2_offset);
-  GST_DEBUG ("  aspect ratio = %d/%d", descriptor->aspect_ratio.n,
-      descriptor->aspect_ratio.d);
-  GST_DEBUG ("  active format descriptor = %u",
-      descriptor->active_format_descriptor);
-  GST_DEBUG ("  video line map = {%i, %i}", descriptor->video_line_map[0],
-      descriptor->video_line_map[1]);
-  GST_DEBUG ("  alpha transparency = %u", descriptor->alpha_transparency);
-  GST_DEBUG ("  capture gamma = %s",
-      mxf_ul_to_string (&descriptor->capture_gamma, str));
-  GST_DEBUG ("  image alignment offset = %u",
-      descriptor->image_alignment_offset);
-  GST_DEBUG ("  image start offset = %u", descriptor->image_start_offset);
-  GST_DEBUG ("  image end offset = %u", descriptor->image_end_offset);
-  GST_DEBUG ("  field dominance = %u", descriptor->field_dominance);
-  GST_DEBUG ("  picture essence coding = %s",
-      mxf_ul_to_string (&descriptor->picture_essence_coding, str));
-
-  return TRUE;
+  return ret;
 
 error:
-  GST_ERROR ("Invalid generic picture essence descriptor");
-  mxf_metadata_generic_picture_essence_descriptor_reset (descriptor);
+  GST_ERROR ("Invalid generic picture essence descriptor tag 0x%04x of size %u",
+      tag, tag_size);
 
-  return FALSE;
+  return TRUE;
 }
 
 void mxf_metadata_generic_picture_essence_descriptor_reset
@@ -2389,123 +2279,102 @@ void mxf_metadata_generic_picture_essence_descriptor_reset
 }
 
 gboolean
-mxf_metadata_cdci_picture_essence_descriptor_parse (const MXFUL * key,
-    MXFMetadataCDCIPictureEssenceDescriptor * descriptor,
-    const MXFPrimerPack * primer, guint16 type, const guint8 * data, guint size)
-{
-  guint16 tag, tag_size;
-  const guint8 *tag_data;
-
-  g_return_val_if_fail (data != NULL, FALSE);
-
-  memset (descriptor, 0, sizeof (MXFMetadataCDCIPictureEssenceDescriptor));
-
-  if (!mxf_metadata_generic_picture_essence_descriptor_parse (key,
-          (MXFMetadataGenericPictureEssenceDescriptor *) descriptor, primer,
-          type, data, size))
-    goto error;
-
-  while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
-    if (tag_size == 0 || tag == 0x0000)
-      goto next;
-
-    switch (tag) {
-      case 0x3301:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->component_depth = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3302:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->horizontal_subsampling = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3308:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->vertical_subsampling = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3303:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 1)
-          goto error;
-        descriptor->color_siting = GST_READ_UINT8 (tag_data);
-        break;
-      case 0x330b:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 1)
-          goto error;
-        descriptor->reversed_byte_order = GST_READ_UINT8 (tag_data);
-        break;
-      case 0x3307:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 2)
-          goto error;
-        descriptor->padding_bits = GST_READ_UINT16_BE (tag_data);
-        break;
-      case 0x3309:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->alpha_sample_depth = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3304:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->black_ref_level = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3305:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->white_ref_level = GST_READ_UINT32_BE (tag_data);
-        break;
-      case 0x3306:
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (tag_size != 4)
-          goto error;
-        descriptor->color_range = GST_READ_UINT32_BE (tag_data);
-        break;
-      default:
-        if (type != MXF_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR)
-          goto next;
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size,
-                &((MXFMetadataGenericDescriptor *) descriptor)->other_tags))
-          goto error;
-        break;
-    }
-
-  next:
-    data += 4 + tag_size;
-    size -= 4 + tag_size;
+    mxf_metadata_cdci_picture_essence_descriptor_handle_tag
+    (MXFMetadataGenericDescriptor * d, const MXFPrimerPack * primer,
+    guint16 tag, const guint8 * tag_data, guint16 tag_size)
+{
+  MXFMetadataCDCIPictureEssenceDescriptor *descriptor =
+      (MXFMetadataCDCIPictureEssenceDescriptor *) d;
+  gboolean ret = FALSE;
+
+  switch (tag) {
+    case 0x3301:
+      if (tag_size != 4)
+        goto error;
+      descriptor->component_depth = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  component depth = %u", descriptor->component_depth);
+      ret = TRUE;
+      break;
+    case 0x3302:
+      if (tag_size != 4)
+        goto error;
+      descriptor->horizontal_subsampling = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  horizontal subsampling = %u",
+          descriptor->horizontal_subsampling);
+      ret = TRUE;
+      break;
+    case 0x3308:
+      if (tag_size != 4)
+        goto error;
+      descriptor->vertical_subsampling = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  vertical subsampling = %u",
+          descriptor->vertical_subsampling);
+      ret = TRUE;
+      break;
+    case 0x3303:
+      if (tag_size != 1)
+        goto error;
+      descriptor->color_siting = GST_READ_UINT8 (tag_data);
+      GST_DEBUG ("  color siting = %u", descriptor->color_siting);
+      ret = TRUE;
+      break;
+    case 0x330b:
+      if (tag_size != 1)
+        goto error;
+      descriptor->reversed_byte_order = GST_READ_UINT8 (tag_data);
+      GST_DEBUG ("  reversed byte order = %s",
+          (descriptor->reversed_byte_order) ? "yes" : "no");
+      ret = TRUE;
+      break;
+    case 0x3307:
+      if (tag_size != 2)
+        goto error;
+      descriptor->padding_bits = GST_READ_UINT16_BE (tag_data);
+      GST_DEBUG ("  padding bits = %d", descriptor->padding_bits);
+      ret = TRUE;
+      break;
+    case 0x3309:
+      if (tag_size != 4)
+        goto error;
+      descriptor->alpha_sample_depth = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  alpha sample depth = %u", descriptor->alpha_sample_depth);
+      ret = TRUE;
+      break;
+    case 0x3304:
+      if (tag_size != 4)
+        goto error;
+      descriptor->black_ref_level = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  black ref level = %u", descriptor->black_ref_level);
+      ret = TRUE;
+      break;
+    case 0x3305:
+      if (tag_size != 4)
+        goto error;
+      descriptor->white_ref_level = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  white ref level = %u", descriptor->white_ref_level);
+      ret = TRUE;
+      break;
+    case 0x3306:
+      if (tag_size != 4)
+        goto error;
+      descriptor->color_range = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  color range = %u", descriptor->color_range);
+      ret = TRUE;
+      break;
+    default:
+      ret =
+          mxf_metadata_generic_picture_essence_descriptor_handle_tag (d, primer,
+          tag, tag_data, tag_size);
+      break;
   }
 
-  GST_DEBUG ("Parsed CDCI picture essence descriptor:");
-  GST_DEBUG ("  component depth = %u", descriptor->component_depth);
-  GST_DEBUG ("  horizontal subsampling = %u",
-      descriptor->horizontal_subsampling);
-  GST_DEBUG ("  vertical subsampling = %u", descriptor->vertical_subsampling);
-  GST_DEBUG ("  color siting = %u", descriptor->color_siting);
-  GST_DEBUG ("  reversed byte order = %s",
-      (descriptor->reversed_byte_order) ? "yes" : "no");
-  GST_DEBUG ("  padding bits = %d", descriptor->padding_bits);
-  GST_DEBUG ("  alpha sample depth = %u", descriptor->alpha_sample_depth);
-  GST_DEBUG ("  black ref level = %u", descriptor->black_ref_level);
-  GST_DEBUG ("  white ref level = %u", descriptor->white_ref_level);
-  GST_DEBUG ("  color range = %u", descriptor->color_range);
-
-  return TRUE;
+  return ret;
 
 error:
-  GST_ERROR ("Invalid CDCI picture essence descriptor");
-  mxf_metadata_cdci_picture_essence_descriptor_reset (descriptor);
+  GST_ERROR ("Invalid CDCI picture essence descriptor tag 0x%04x of size %u",
+      tag, tag_size);
 
-  return FALSE;
+  return TRUE;
 }
 
 void mxf_metadata_cdci_picture_essence_descriptor_reset
@@ -2520,78 +2389,55 @@ void mxf_metadata_cdci_picture_essence_descriptor_reset
 }
 
 gboolean
-mxf_metadata_multiple_descriptor_parse (const MXFUL * key,
-    MXFMetadataMultipleDescriptor * descriptor,
-    const MXFPrimerPack * primer, guint16 type, const guint8 * data, guint size)
+mxf_metadata_multiple_descriptor_handle_tag (MXFMetadataGenericDescriptor * d,
+    const MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
+    guint16 tag_size)
 {
-  guint16 tag, tag_size;
-  const guint8 *tag_data;
+  MXFMetadataMultipleDescriptor *descriptor =
+      (MXFMetadataMultipleDescriptor *) d;
+  gboolean ret = FALSE;
   gchar str[48];
-  guint i;
-
-  g_return_val_if_fail (data != NULL, FALSE);
-
-  memset (descriptor, 0, sizeof (MXFMetadataMultipleDescriptor));
-
-  if (!mxf_metadata_file_descriptor_parse (key,
-          (MXFMetadataFileDescriptor *) descriptor, primer, type, data, size))
-    goto error;
-
-  while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
-    if (tag_size == 0 || tag == 0x0000)
-      goto next;
-
-    switch (tag) {
-      case 0x3f01:{
-        guint32 len;
-        guint i;
 
-        GST_WRITE_UINT16_BE (data, 0x0000);
-
-        if (tag_size < 8)
-          goto error;
-        len = GST_READ_UINT32_BE (tag_data);
-        if (len == 0)
-          goto next;
-
-        if (GST_READ_UINT32_BE (tag_data + 4) != 16)
-          goto error;
-
-        descriptor->n_sub_descriptors = len;
-        descriptor->sub_descriptors_uids = g_new0 (MXFUL, len);
-        for (i = 0; i < len; i++)
-          memcpy (&descriptor->sub_descriptors_uids[i], tag_data + 8 + i * 16,
-              16);
-        break;
+  switch (tag) {
+    case 0x3f01:{
+      guint32 len;
+      guint i;
+
+      if (tag_size < 8)
+        goto error;
+      len = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  number of sub descriptors = %u", len);
+      if (len == 0)
+        return TRUE;
+
+      if (GST_READ_UINT32_BE (tag_data + 4) != 16)
+        goto error;
+
+      descriptor->n_sub_descriptors = len;
+      descriptor->sub_descriptors_uids = g_new0 (MXFUL, len);
+      for (i = 0; i < len; i++) {
+        memcpy (&descriptor->sub_descriptors_uids[i], tag_data + 8 + i * 16,
+            16);
+        GST_DEBUG ("  sub descriptor %u = %s", i,
+            mxf_ul_to_string (&descriptor->sub_descriptors_uids[i], str));
       }
-      default:
-        if (type != MXF_METADATA_MULTIPLE_DESCRIPTOR)
-          goto next;
-        GST_WRITE_UINT16_BE (data, 0x0000);
-        if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size,
-                &((MXFMetadataGenericDescriptor *) descriptor)->other_tags))
-          goto error;
-        break;
+      ret = TRUE;
+      break;
     }
-
-  next:
-    data += 4 + tag_size;
-    size -= 4 + tag_size;
+    default:
+      ret =
+          mxf_metadata_file_descriptor_handle_tag (d, primer, tag, tag_data,
+          tag_size);
+      break;
   }
 
-  GST_DEBUG ("Parsed multiple descriptor:");
-  GST_DEBUG ("  number of sub descriptors = %u", descriptor->n_sub_descriptors);
-  for (i = 0; i < descriptor->n_sub_descriptors; i++)
-    GST_DEBUG ("  sub descriptor %u = %s", i,
-        mxf_ul_to_string (&descriptor->sub_descriptors_uids[i], str));
-
-  return TRUE;
+  return ret;
 
 error:
-  GST_ERROR ("Invalid multiple descriptor");
-  mxf_metadata_multiple_descriptor_reset (descriptor);
+  GST_ERROR ("Invalid multiple descriptor tag 0x%04x of size %u", tag,
+      tag_size);
 
-  return FALSE;
+  return TRUE;
 }
 
 void mxf_metadata_multiple_descriptor_reset
@@ -2622,33 +2468,36 @@ mxf_metadata_locator_parse (const MXFUL * key,
 
   locator->type = type;
 
+  GST_DEBUG ("Parsing locator of type 0x%04x:", type);
+
   while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
     if (tag_size == 0 || tag == 0x0000)
       goto next;
 
     switch (tag) {
       case 0x3c0a:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&locator->instance_uid, tag_data, 16);
+        GST_DEBUG ("  instance uid = %s",
+            mxf_ul_to_string (&locator->instance_uid, str));
         break;
       case 0x0102:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (tag_size != 16)
           goto error;
         memcpy (&locator->generation_uid, tag_data, 16);
+        GST_DEBUG ("  generation uid = %s",
+            mxf_ul_to_string (&locator->generation_uid, str));
         break;
       case 0x4101:
         if (type != MXF_METADATA_TEXT_LOCATOR
             && type != MXF_METADATA_NETWORK_LOCATOR)
           goto DFLT;
-        GST_WRITE_UINT16_BE (data, 0x0000);
         locator->location = mxf_utf16_to_utf8 (tag_data, tag_size);
+        GST_DEBUG ("  location = %s", GST_STR_NULL (locator->location));
         break;
       DFLT:
       default:
-        GST_WRITE_UINT16_BE (data, 0x0000);
         if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size,
                 &locator->other_tags))
           goto error;
@@ -2660,13 +2509,6 @@ mxf_metadata_locator_parse (const MXFUL * key,
     size -= 4 + tag_size;
   }
 
-  GST_DEBUG ("Parsed locator:");
-  GST_DEBUG ("  instance uid = %s", mxf_ul_to_string (&locator->instance_uid,
-          str));
-  GST_DEBUG ("  generation uid = %s",
-      mxf_ul_to_string (&locator->generation_uid, str));
-  GST_DEBUG ("  location = %s", GST_STR_NULL (locator->location));
-
   return TRUE;
 
 error:
index a39915d3e6c4c0a961b95c938babd8882231cb63..790bc3969bbbf904553a1a0c15f8a79b334ad76b 100644 (file)
 
 typedef GstFlowReturn (*MXFEssenceElementHandler) (const MXFUL *key, GstBuffer *buffer, GstCaps *caps, MXFMetadataGenericPackage *package, MXFMetadataTrack *track, MXFMetadataStructuralComponent *component, gpointer mapping_data, GstBuffer **outbuf);
 
+typedef gboolean (*MXFMetadataDescriptorHandleTag) (MXFMetadataGenericDescriptor *descriptor,
+    const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size);
+typedef void (*MXFMetadataDescriptorReset) (MXFMetadataGenericDescriptor *descriptor);
+
 gchar * mxf_ul_to_string (const MXFUL *ul, gchar str[48]);
 gboolean mxf_ul_is_equal (const MXFUL *a, const MXFUL *b);
 gboolean mxf_ul_is_zero (const MXFUL *ul);
@@ -104,22 +108,31 @@ void mxf_metadata_sequence_reset (MXFMetadataSequence *sequence);
 gboolean mxf_metadata_structural_component_parse (const MXFUL *key, MXFMetadataStructuralComponent *component, const MXFPrimerPack *primer, guint16 type, const guint8 *data, guint size);
 void mxf_metadata_structural_component_reset (MXFMetadataStructuralComponent *component);
 
-gboolean mxf_metadata_generic_descriptor_parse (const MXFUL *key, MXFMetadataGenericDescriptor *descriptor, const MXFPrimerPack *primer, guint16 type, const guint8 *data, guint size);
+gboolean
+mxf_metadata_descriptor_parse (const MXFUL * key, MXFMetadataGenericDescriptor * descriptor, const MXFPrimerPack * primer, guint16 type, const guint8 * data, guint size, MXFMetadataDescriptorHandleTag handle_tag, MXFMetadataDescriptorReset reset);
+
+gboolean mxf_metadata_generic_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor,
+    const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size);
 void mxf_metadata_generic_descriptor_reset (MXFMetadataGenericDescriptor *descriptor);
 
-gboolean mxf_metadata_file_descriptor_parse (const MXFUL *key, MXFMetadataFileDescriptor *descriptor, const MXFPrimerPack *primer, guint16 type, const guint8 *data, guint size);
+gboolean mxf_metadata_file_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor,
+    const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size);
 void mxf_metadata_file_descriptor_reset (MXFMetadataFileDescriptor *descriptor);
 
-gboolean mxf_metadata_generic_sound_essence_descriptor_parse (const MXFUL *key, MXFMetadataGenericSoundEssenceDescriptor *descriptor, const MXFPrimerPack *primer, guint16 type, const guint8 *data, guint size);
+gboolean mxf_metadata_generic_sound_essence_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor,
+    const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size);
 void mxf_metadata_generic_sound_essence_descriptor_reset (MXFMetadataGenericSoundEssenceDescriptor *descriptor);
 
-gboolean mxf_metadata_generic_picture_essence_descriptor_parse (const MXFUL *key, MXFMetadataGenericPictureEssenceDescriptor *descriptor, const MXFPrimerPack *primer, guint16 type, const guint8 *data, guint size);
+gboolean mxf_metadata_generic_picture_essence_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor,
+    const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size);
 void mxf_metadata_generic_picture_essence_descriptor_reset (MXFMetadataGenericPictureEssenceDescriptor *descriptor);
 
-gboolean mxf_metadata_cdci_picture_essence_descriptor_parse (const MXFUL *key, MXFMetadataCDCIPictureEssenceDescriptor *descriptor, const MXFPrimerPack *primer, guint16 type, const guint8 *data, guint size);
+gboolean mxf_metadata_cdci_picture_essence_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor,
+    const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size);
 void mxf_metadata_cdci_picture_essence_descriptor_reset (MXFMetadataCDCIPictureEssenceDescriptor *descriptor);
 
-gboolean mxf_metadata_multiple_descriptor_parse (const MXFUL *key, MXFMetadataMultipleDescriptor *descriptor, const MXFPrimerPack *primer, guint16 type, const guint8 *data, guint size);
+gboolean mxf_metadata_multiple_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor,
+    const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size);
 void mxf_metadata_multiple_descriptor_reset (MXFMetadataMultipleDescriptor *descriptor);
 
 gboolean mxf_metadata_locator_parse (const MXFUL *key, MXFMetadataLocator *locator, const MXFPrimerPack *primer, guint16 type, const guint8 *data, guint size);