gst/mxf/: Implement parsing of Event Tracks, Static Tracks, DM Segments and DM Source...
authorSebastian Dröge <slomo@circular-chaos.org>
Thu, 11 Dec 2008 14:35:08 +0000 (14:35 +0000)
committerSebastian Dröge <slomo@circular-chaos.org>
Thu, 11 Dec 2008 14:35:08 +0000 (14:35 +0000)
Original commit message from CVS:
* gst/mxf/mxfdemux.c: (gst_mxf_demux_handle_metadata_track),
(gst_mxf_demux_handle_header_metadata_resolve_references),
(gst_mxf_demux_handle_metadata):
* gst/mxf/mxfparse.c: (mxf_metadata_track_parse),
(mxf_metadata_structural_component_parse),
(mxf_metadata_structural_component_reset):
* gst/mxf/mxfparse.h:
* gst/mxf/mxftypes.h:
Implement parsing of Event Tracks, Static Tracks, DM Segments
and DM Source Clips as a preparation for descriptive metadata
support. Next step is to implement SMPTE S380M, "Descriptive
Metadata Scheme-1".

ChangeLog
gst/mxf/mxfdemux.c
gst/mxf/mxfparse.c
gst/mxf/mxfparse.h
gst/mxf/mxftypes.h

index 012eb20..8890cfa 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2008-12-11  Sebastian Dröge  <sebastian.droege@collabora.co.uk>
+
+       * gst/mxf/mxfdemux.c: (gst_mxf_demux_handle_metadata_track),
+       (gst_mxf_demux_handle_header_metadata_resolve_references),
+       (gst_mxf_demux_handle_metadata):
+       * gst/mxf/mxfparse.c: (mxf_metadata_track_parse),
+       (mxf_metadata_structural_component_parse),
+       (mxf_metadata_structural_component_reset):
+       * gst/mxf/mxfparse.h:
+       * gst/mxf/mxftypes.h:
+       Implement parsing of Event Tracks, Static Tracks, DM Segments
+       and DM Source Clips as a preparation for descriptive metadata
+       support. Next step is to implement SMPTE S380M, "Descriptive
+       Metadata Scheme-1".
+
 2008-12-09  Sebastian Dröge  <sebastian.droege@collabora.co.uk>
 
        * gst/mxf/mxfjpeg2000.c: (mxf_jpeg2000_create_caps):
index 6c6e929..9331885 100644 (file)
@@ -720,17 +720,18 @@ gst_mxf_demux_handle_metadata_source_package (GstMXFDemux * demux,
 
 static GstFlowReturn
 gst_mxf_demux_handle_metadata_track (GstMXFDemux * demux,
-    const MXFUL * key, GstBuffer * buffer)
+    const MXFUL * key, guint16 type, GstBuffer * buffer)
 {
   MXFMetadataTrack track;
 
   GST_DEBUG_OBJECT (demux,
-      "Handling metadata track of size %u"
-      " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
+      "Handling metadata track with type 0x%04x of size %u"
+      " at offset %" G_GUINT64_FORMAT, type, GST_BUFFER_SIZE (buffer),
+      demux->offset);
 
   if (!mxf_metadata_track_parse (key, &track, &demux->primer,
-          GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
-    GST_ERROR_OBJECT (demux, "Parsing metadata track timecode failed");
+          type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
+    GST_ERROR_OBJECT (demux, "Parsing metadata track failed");
     return GST_FLOW_ERROR;
   }
 
@@ -1287,8 +1288,6 @@ gst_mxf_demux_handle_header_metadata_resolve_references (GstMXFDemux * demux)
   }
   demux->preface.content_storage = &demux->content_storage;
 
-  /* TODO: dm_schemes */
-
   /* Content storage */
   demux->content_storage.packages =
       g_new0 (MXFMetadataGenericPackage *, demux->content_storage.n_packages);
@@ -1317,8 +1316,9 @@ gst_mxf_demux_handle_header_metadata_resolve_references (GstMXFDemux * demux)
           MXFMetadataEssenceContainerData, i);
 
       for (j = 0; j < demux->content_storage.n_essence_container_data; j++) {
-        if (mxf_ul_is_equal (&demux->content_storage.
-                essence_container_data_uids[j], &data->instance_uid)) {
+        if (mxf_ul_is_equal (&demux->
+                content_storage.essence_container_data_uids[j],
+                &data->instance_uid)) {
           demux->content_storage.essence_container_data[j] = data;
           break;
         }
@@ -1500,7 +1500,8 @@ gst_mxf_demux_handle_header_metadata_resolve_references (GstMXFDemux * demux)
           &g_array_index (demux->structural_component,
           MXFMetadataStructuralComponent, i);
 
-      if (component->type != MXF_METADATA_SOURCE_CLIP)
+      if (component->type != MXF_METADATA_SOURCE_CLIP
+          && component->type != MXF_METADATA_DM_SOURCE_CLIP)
         continue;
 
       for (j = 0; j < demux->source_package->len; j++) {
@@ -1508,10 +1509,16 @@ gst_mxf_demux_handle_header_metadata_resolve_references (GstMXFDemux * demux)
             &g_array_index (demux->source_package, MXFMetadataGenericPackage,
             j);
 
-        if (mxf_umid_is_equal (&component->source_clip.source_package_id,
+        if (component->type == MXF_METADATA_SOURCE_CLIP &&
+            mxf_umid_is_equal (&component->source_clip.source_package_id,
                 &package->package_uid)) {
           component->source_clip.source_package = package;
           break;
+        } else if (component->type == MXF_METADATA_DM_SOURCE_CLIP &&
+            mxf_umid_is_equal (&component->dm_source_clip.source_package_id,
+                &package->package_uid)) {
+          component->dm_source_clip.source_package = package;
+          break;
         }
       }
     }
@@ -1986,7 +1993,7 @@ gst_mxf_demux_handle_metadata (GstMXFDemux * demux, const MXFUL * key,
 
   GST_DEBUG_OBJECT (demux,
       "Handling metadata of size %u at offset %"
-      G_GUINT64_FORMAT " of type 0x%04d", GST_BUFFER_SIZE (buffer),
+      G_GUINT64_FORMAT " of type 0x%04x", GST_BUFFER_SIZE (buffer),
       demux->offset, type);
 
   if (G_UNLIKELY (!demux->partition.valid)) {
@@ -2027,13 +2034,17 @@ gst_mxf_demux_handle_metadata (GstMXFDemux * demux, const MXFUL * key,
       ret = gst_mxf_demux_handle_metadata_source_package (demux, key, buffer);
       break;
     case MXF_METADATA_TRACK:
-      ret = gst_mxf_demux_handle_metadata_track (demux, key, buffer);
+    case MXF_METADATA_EVENT_TRACK:
+    case MXF_METADATA_STATIC_TRACK:
+      ret = gst_mxf_demux_handle_metadata_track (demux, key, type, buffer);
       break;
     case MXF_METADATA_SEQUENCE:
       ret = gst_mxf_demux_handle_metadata_sequence (demux, key, buffer);
       break;
     case MXF_METADATA_TIMECODE_COMPONENT:
     case MXF_METADATA_SOURCE_CLIP:
+    case MXF_METADATA_DM_SEGMENT:
+    case MXF_METADATA_DM_SOURCE_CLIP:
       ret =
           gst_mxf_demux_handle_metadata_structural_component (demux,
           key, type, buffer);
index 334c719..9ee44e6 100644 (file)
@@ -1694,7 +1694,7 @@ void mxf_metadata_generic_package_reset
 gboolean
 mxf_metadata_track_parse (const MXFUL * key,
     MXFMetadataTrack * track, const MXFPrimerPack * primer,
-    const guint8 * data, guint size)
+    guint16 type, const guint8 * data, guint size)
 {
   guint16 tag, tag_size;
   const guint8 *tag_data;
@@ -1704,7 +1704,15 @@ mxf_metadata_track_parse (const MXFUL * key,
 
   memset (track, 0, sizeof (MXFMetadataTrack));
 
-  GST_DEBUG ("Parsing track:");
+  if (type == MXF_METADATA_TRACK)
+    track->variant = MXF_METADATA_TRACK_VARIANT_TIMELINE;
+  else if (type == MXF_METADATA_EVENT_TRACK)
+    track->variant = MXF_METADATA_TRACK_VARIANT_EVENT;
+  else
+    track->variant = MXF_METADATA_TRACK_VARIANT_STATIC;
+
+
+  GST_DEBUG ("Parsing track of type 0x%04x:", type);
 
   while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
     if (tag_size == 0 || tag == 0x0000)
@@ -1742,12 +1750,14 @@ mxf_metadata_track_parse (const MXFUL * key,
         GST_DEBUG ("  track name = %s", GST_STR_NULL (track->track_name));
         break;
       case 0x4b01:
+      case 0x4901:
         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:
+      case 0x4902:
         if (tag_size != 8)
           goto error;
         track->origin = GST_READ_UINT64_BE (tag_data);
@@ -1960,10 +1970,14 @@ mxf_metadata_structural_component_parse (const MXFUL * key,
   GST_DEBUG ("Parsing structural component:");
 
   component->type = type;
-  GST_DEBUG ("  type = %s",
-      (component->type ==
-          MXF_METADATA_TIMECODE_COMPONENT) ? "timecode component" :
-      "source clip");
+  if (type == MXF_METADATA_TIMECODE_COMPONENT)
+    GST_DEBUG ("  type = timecode component");
+  else if (type == MXF_METADATA_SOURCE_CLIP)
+    GST_DEBUG ("  type = source clip");
+  else if (type == MXF_METADATA_DM_SEGMENT)
+    GST_DEBUG ("  type = DM segment");
+  else
+    GST_DEBUG ("  type = DM source clip");
 
   while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
     if (tag_size == 0 || tag == 0x0000)
@@ -2030,33 +2044,164 @@ mxf_metadata_structural_component_parse (const MXFUL * key,
         break;
         /* Source clip specifics */
       case 0x1201:
-        if (type != MXF_METADATA_SOURCE_CLIP)
+        if (type != MXF_METADATA_SOURCE_CLIP
+            && type != MXF_METADATA_DM_SOURCE_CLIP)
           goto DFLT;
         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);
+
+        if (type == MXF_METADATA_SOURCE_CLIP) {
+          component->source_clip.start_position = GST_READ_UINT64_BE (tag_data);
+          GST_DEBUG ("  start position = %" G_GINT64_FORMAT,
+              component->source_clip.start_position);
+        } else {
+          component->dm_source_clip.start_position =
+              GST_READ_UINT64_BE (tag_data);
+          GST_DEBUG ("  start position = %" G_GINT64_FORMAT,
+              component->dm_source_clip.start_position);
+        }
         break;
       case 0x1101:
-        if (type != MXF_METADATA_SOURCE_CLIP)
+        if (type != MXF_METADATA_SOURCE_CLIP
+            && type != MXF_METADATA_DM_SOURCE_CLIP)
           goto DFLT;
         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));
+
+        if (type == MXF_METADATA_SOURCE_CLIP) {
+          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));
+        } else {
+          memcpy (&component->dm_source_clip.source_package_id, tag_data, 32);
+          GST_DEBUG ("  source package id = %s",
+              mxf_umid_to_string (&component->dm_source_clip.source_package_id,
+                  str));
+        }
         break;
       case 0x1102:
-        if (type != MXF_METADATA_SOURCE_CLIP)
+        if (type != MXF_METADATA_SOURCE_CLIP
+            && type != MXF_METADATA_DM_SOURCE_CLIP)
           goto DFLT;
         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);
+
+        if (type == MXF_METADATA_SOURCE_CLIP) {
+          component->source_clip.source_track_id =
+              GST_READ_UINT32_BE (tag_data);
+          GST_DEBUG ("  source track id = %u",
+              component->source_clip.source_track_id);
+        } else {
+          component->dm_source_clip.source_track_id =
+              GST_READ_UINT32_BE (tag_data);
+          GST_DEBUG ("  source track id = %u",
+              component->dm_source_clip.source_track_id);
+        }
         break;
+        /* DM Segment specifics */
+      case 0x0601:
+        if (type != MXF_METADATA_DM_SEGMENT)
+          goto DFLT;
+        if (tag_size != 8)
+          goto error;
+        component->dm_segment.event_start_position =
+            GST_READ_UINT64_BE (tag_data);
+        GST_DEBUG ("  event start position = %" G_GINT64_FORMAT,
+            component->dm_segment.event_start_position);
+        break;
+      case 0x0602:
+        if (type != MXF_METADATA_DM_SEGMENT)
+          goto DFLT;
+        component->dm_segment.event_comment =
+            mxf_utf16_to_utf8 (tag_data, tag_size);
+        GST_DEBUG ("  event comment = %s",
+            GST_STR_NULL (component->dm_segment.event_comment));
+        break;
+      case 0x6102:
+      {
+        guint32 len;
+        guint i;
+
+        if (type != MXF_METADATA_DM_SEGMENT)
+          goto DFLT;
+
+        if (tag_size < 8)
+          goto error;
+        len = GST_READ_UINT32_BE (tag_data);
+        GST_DEBUG ("  number of track ids = %u", len);
+        if (len == 0)
+          goto next;
+
+        if (GST_READ_UINT32_BE (tag_data + 4) != 4)
+          goto error;
+
+        if (len * 4 + 8 < tag_size)
+          goto error;
+
+        component->dm_segment.n_track_ids = len;
+        component->dm_segment.track_ids = g_new0 (guint32, len);
+
+        tag_data += 8;
+        tag_size -= 8;
+
+        for (i = 0; i < len; i++) {
+          component->dm_segment.track_ids[i] = GST_READ_UINT32_BE (tag_data);
+          GST_DEBUG ("    track id %u = %u", i,
+              component->dm_segment.track_ids[i]);
+          tag_data += 4;
+          tag_size -= 4;
+        }
+        break;
+      }
+      case 0x6101:
+        if (type != MXF_METADATA_DM_SEGMENT)
+          goto DFLT;
+        if (tag_size != 16)
+          goto error;
+
+        memcpy (&component->dm_segment.dm_framework, tag_data, 16);
+        GST_DEBUG ("  DM framework = %s",
+            mxf_ul_to_string (&component->dm_segment.dm_framework, str));
+        break;
+        /* DM Source Clip specifics */
+      case 0x6103:
+      {
+        guint32 len;
+        guint i;
+
+        if (type != MXF_METADATA_DM_SOURCE_CLIP)
+          goto DFLT;
+        if (tag_size < 8)
+          goto error;
+
+        len = GST_READ_UINT32_BE (tag_data);
+        GST_DEBUG ("  number of track ids = %u", len);
+        if (len == 0)
+          goto next;
+
+        if (GST_READ_UINT32_BE (tag_data + 4) != 4)
+          goto error;
+
+        if (tag_size < 8 + 4 * len)
+          goto error;
+
+        tag_data += 8;
+        tag_size -= 8;
+
+        component->dm_source_clip.n_track_ids = len;
+        component->dm_source_clip.track_ids = g_new0 (guint32, len);
+
+        for (i = 0; i < len; i++) {
+          component->dm_source_clip.track_ids[i] =
+              GST_READ_UINT32_BE (tag_data);
+          GST_DEBUG ("    track id %u = %u", i,
+              component->dm_source_clip.track_ids[i]);
+          tag_data += 4;
+          tag_size -= 4;
+        }
+        break;
+      }
       DFLT:
       default:
         if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size,
@@ -2084,6 +2229,13 @@ void mxf_metadata_structural_component_reset
 {
   g_return_if_fail (component != NULL);
 
+  if (component->type == MXF_METADATA_DM_SEGMENT) {
+    g_free (component->dm_segment.event_comment);
+    g_free (component->dm_segment.track_ids);
+  } else if (component->type == MXF_METADATA_DM_SOURCE_CLIP) {
+    g_free (component->dm_source_clip.track_ids);
+  }
+
   if (component->other_tags)
     g_hash_table_destroy (component->other_tags);
 
index 6ea0ddd..200fc78 100644 (file)
@@ -106,7 +106,7 @@ void mxf_metadata_essence_container_data_reset (MXFMetadataEssenceContainerData
 gboolean mxf_metadata_generic_package_parse (const MXFUL *key, MXFMetadataGenericPackage *generic_package, const MXFPrimerPack *primer, const guint8 *data, guint size);
 void mxf_metadata_generic_package_reset (MXFMetadataGenericPackage *generic_package);
 
-gboolean mxf_metadata_track_parse (const MXFUL *key, MXFMetadataTrack *track, const MXFPrimerPack *primer, const guint8 *data, guint size);
+gboolean mxf_metadata_track_parse (const MXFUL *key, MXFMetadataTrack *track, const MXFPrimerPack *primer, guint16 type, const guint8 *data, guint size);
 void mxf_metadata_track_reset (MXFMetadataTrack *track);
 
 MXFMetadataTrackType mxf_metadata_track_identifier_parse (const MXFUL *track_identifier);
index fe39174..241efd4 100644 (file)
@@ -327,6 +327,12 @@ typedef enum {
   MXF_METADATA_TRACK_PARSED_TEXT           = 0x41
 } MXFMetadataTrackType;
 
+typedef enum {
+  MXF_METADATA_TRACK_VARIANT_TIMELINE,
+  MXF_METADATA_TRACK_VARIANT_EVENT,
+  MXF_METADATA_TRACK_VARIANT_STATIC
+} MXFMetadataTrackVariant;
+
 struct _MXFMetadataTrack {
   MXFUL instance_uid;
   MXFUL generation_uid;
@@ -335,6 +341,7 @@ struct _MXFMetadataTrack {
   guint32 track_number;
 
   MXFMetadataTrackType type;
+  MXFMetadataTrackVariant variant;
 
   gchar *track_name;
 
@@ -390,6 +397,27 @@ struct _MXFMetadataStructuralComponent {
 
       guint32 source_track_id;
     } source_clip;
+
+    struct {
+      gint64 event_start_position;
+      gchar *event_comment;
+
+      guint32 n_track_ids;
+      guint32 *track_ids;
+      
+      MXFUL dm_framework;
+    } dm_segment;
+
+    struct {
+      gint64 start_position;
+      MXFUMID source_package_id;
+      MXFMetadataGenericPackage *source_package;
+
+      guint32 source_track_id;
+
+      guint32 n_track_ids;
+      guint32 *track_ids;
+    } dm_source_clip;
   };
 
   GHashTable *other_tags;