Generate an index table for essence streams
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Tue, 27 Jan 2009 13:25:26 +0000 (14:25 +0100)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Sat, 31 Jan 2009 10:02:24 +0000 (11:02 +0100)
Generate an index table for essence streams during playback
and make sure that only the correct essence elements are
used for played tracks.

Make it possible to have one essence stream used in multiple
playback tracks.

Fix some minor bugs.

gst/mxf/mxfaes-bwf.c
gst/mxf/mxfalaw.c
gst/mxf/mxfd10.c
gst/mxf/mxfdemux.c
gst/mxf/mxfdemux.h
gst/mxf/mxfdv-dif.c
gst/mxf/mxfjpeg2000.c
gst/mxf/mxfmpeg.c
gst/mxf/mxfparse.h
gst/mxf/mxfup.c
gst/mxf/mxfvc3.c

index 01c8ce0..ca9234f 100644 (file)
@@ -576,8 +576,7 @@ static GstFlowReturn
 mxf_bwf_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
     GstCaps * caps,
     MXFMetadataTimelineTrack * track,
-    MXFMetadataSourceClip * component, gpointer mapping_data,
-    GstBuffer ** outbuf)
+    gpointer mapping_data, GstBuffer ** outbuf)
 {
   *outbuf = buffer;
 
@@ -595,8 +594,7 @@ mxf_bwf_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
 static GstFlowReturn
 mxf_aes3_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
     GstCaps * caps, MXFMetadataTimelineTrack * track,
-    MXFMetadataSourceClip * component, gpointer mapping_data,
-    GstBuffer ** outbuf)
+    gpointer mapping_data, GstBuffer ** outbuf)
 {
   *outbuf = buffer;
 
@@ -816,24 +814,24 @@ mxf_aes_bwf_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
     if (!track->parent.descriptor[i])
       continue;
 
-    if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->parent.
-            descriptor[i])
+    if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->
+            parent.descriptor[i])
         && (track->parent.descriptor[i]->essence_container.u[14] == 0x01
             || track->parent.descriptor[i]->essence_container.u[14] == 0x02
             || track->parent.descriptor[i]->essence_container.u[14] == 0x08)) {
-      s = (MXFMetadataGenericSoundEssenceDescriptor *) track->parent.
-          descriptor[i];
+      s = (MXFMetadataGenericSoundEssenceDescriptor *) track->
+          parent.descriptor[i];
       bwf = TRUE;
       break;
     } else
-        if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->parent.
-            descriptor[i])
+        if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->
+            parent.descriptor[i])
         && (track->parent.descriptor[i]->essence_container.u[14] == 0x03
             || track->parent.descriptor[i]->essence_container.u[14] == 0x04
             || track->parent.descriptor[i]->essence_container.u[14] == 0x09)) {
 
-      s = (MXFMetadataGenericSoundEssenceDescriptor *) track->parent.
-          descriptor[i];
+      s = (MXFMetadataGenericSoundEssenceDescriptor *) track->
+          parent.descriptor[i];
       bwf = FALSE;
       break;
     }
index b14f5b7..074f1a4 100644 (file)
@@ -65,8 +65,7 @@ static GstFlowReturn
 mxf_alaw_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
     GstCaps * caps,
     MXFMetadataTimelineTrack * track,
-    MXFMetadataSourceClip * component, gpointer mapping_data,
-    GstBuffer ** outbuf)
+    gpointer mapping_data, GstBuffer ** outbuf)
 {
   *outbuf = buffer;
 
@@ -100,10 +99,10 @@ mxf_alaw_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
     if (!track->parent.descriptor[i])
       continue;
 
-    if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->
-            parent.descriptor[i])) {
-      s = (MXFMetadataGenericSoundEssenceDescriptor *) track->
-          parent.descriptor[i];
+    if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->parent.
+            descriptor[i])) {
+      s = (MXFMetadataGenericSoundEssenceDescriptor *) track->parent.
+          descriptor[i];
       break;
     }
   }
index b37fc56..c24d163 100644 (file)
@@ -71,8 +71,7 @@ static GstFlowReturn
 mxf_d10_picture_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
     GstCaps * caps,
     MXFMetadataTimelineTrack * track,
-    MXFMetadataSourceClip * component, gpointer mapping_data,
-    GstBuffer ** outbuf)
+    gpointer mapping_data, GstBuffer ** outbuf)
 {
   *outbuf = buffer;
 
@@ -89,8 +88,7 @@ static GstFlowReturn
 mxf_d10_sound_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
     GstCaps * caps,
     MXFMetadataTimelineTrack * track,
-    MXFMetadataSourceClip * component, gpointer mapping_data,
-    GstBuffer ** outbuf)
+    gpointer mapping_data, GstBuffer ** outbuf)
 {
   guint i, j, nsamples;
   const guint8 *indata;
@@ -173,15 +171,15 @@ mxf_d10_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
     if (!track->parent.descriptor[i])
       continue;
 
-    if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track->
-            parent.descriptor[i])) {
-      p = (MXFMetadataGenericPictureEssenceDescriptor *) track->parent.
-          descriptor[i];
+    if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track->parent.
+            descriptor[i])) {
+      p = (MXFMetadataGenericPictureEssenceDescriptor *) track->
+          parent.descriptor[i];
       break;
-    } else if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->
-            parent.descriptor[i])) {
-      s = (MXFMetadataGenericSoundEssenceDescriptor *) track->parent.
-          descriptor[i];
+    } else if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->parent.
+            descriptor[i])) {
+      s = (MXFMetadataGenericSoundEssenceDescriptor *) track->
+          parent.descriptor[i];
       break;
     }
   }
index 0473b69..b3ba872 100644 (file)
@@ -188,7 +188,9 @@ gst_mxf_demux_reset_mxf_state (GstMXFDemux * demux)
       GstMXFDemuxEssenceTrack *t =
           &g_array_index (demux->essence_tracks, GstMXFDemuxEssenceTrack, i);
 
-      g_free (t->offsets);
+      if (t->offsets)
+        g_array_free (t->offsets, TRUE);
+
       g_free (t->mapping_data);
 
       if (t->tags)
@@ -384,6 +386,13 @@ gst_mxf_demux_push_src_event (GstMXFDemux * demux, GstEvent * event)
   return ret;
 }
 
+static gint
+gst_mxf_demux_partition_compare (GstMXFDemuxPartition * a,
+    GstMXFDemuxPartition * b)
+{
+  return (a->partition.this_partition - b->partition.this_partition);
+}
+
 static GstFlowReturn
 gst_mxf_demux_handle_partition_pack (GstMXFDemux * demux, const MXFUL * key,
     GstBuffer * buffer)
@@ -402,6 +411,7 @@ gst_mxf_demux_handle_partition_pack (GstMXFDemux * demux, const MXFUL * key,
     if (tmp->partition.this_partition + demux->run_in == demux->offset &&
         tmp->partition.major_version == 0x0001) {
       GST_DEBUG_OBJECT (demux, "Partition already parsed");
+      p = tmp;
       goto out;
     }
   }
@@ -436,7 +446,21 @@ gst_mxf_demux_handle_partition_pack (GstMXFDemux * demux, const MXFUL * key,
   } else {
     p = g_new0 (GstMXFDemuxPartition, 1);
     memcpy (&p->partition, &partition, sizeof (MXFPartitionPack));
-    demux->partitions = g_list_prepend (demux->partitions, p);
+    demux->partitions =
+        g_list_insert_sorted (demux->partitions, p,
+        (GCompareFunc) gst_mxf_demux_partition_compare);
+  }
+
+  for (l = demux->partitions; l; l = l->next) {
+    GstMXFDemuxPartition *a, *b;
+
+    if (l->next == NULL);
+    break;
+
+    a = l->data;
+    b = l->next->data;
+
+    b->partition.prev_partition = a->partition.this_partition;
   }
 
 out:
@@ -692,22 +716,9 @@ gst_mxf_demux_update_essence_tracks (GstMXFDemux * demux)
         goto next;
       }
 
-      if (track->parent.sequence->duration > etrack->duration) {
-        guint64 old_duration = etrack->duration;
-
+      if (track->parent.sequence->duration > etrack->duration)
         etrack->duration = track->parent.sequence->duration;
 
-        if (etrack->offsets) {
-          etrack->offsets =
-              g_realloc (etrack->offsets,
-              etrack->duration * sizeof (GstMXFDemuxIndex));
-          memset (&etrack->offsets[old_duration - 1], 0,
-              etrack->duration - old_duration);
-        } else {
-          etrack->offsets = g_new0 (GstMXFDemuxIndex, etrack->duration);
-        }
-      }
-
       g_free (etrack->mapping_data);
       etrack->mapping_data = NULL;
       etrack->handler = NULL;
@@ -740,7 +751,12 @@ gst_mxf_demux_update_essence_tracks (GstMXFDemux * demux)
       } else if (!caps) {
         GST_WARNING_OBJECT (demux, "Couldn't create updated caps for stream");
       } else if (!etrack->caps || !gst_caps_is_equal (etrack->caps, caps)) {
-        gst_caps_replace (&etrack->caps, caps);
+        if (etrack->caps)
+          gst_caps_unref (etrack->caps);
+        etrack->caps = caps;
+      } else {
+        gst_caps_unref (caps);
+        caps = NULL;
       }
 
       etrack->source_package = package;
@@ -975,7 +991,6 @@ gst_mxf_demux_update_tracks (GstMXFDemux * demux)
     /* If we just added the pad initialize for the current component */
     if (first_run && MXF_IS_METADATA_MATERIAL_PACKAGE (current_package)) {
       pad->current_component_index = 0;
-      pad->current_component_position = 0;
       pad->current_component_start = source_track->origin;
       if (track->edit_rate.n != source_track->edit_rate.n ||
           track->edit_rate.n != source_track->edit_rate.n) {
@@ -987,6 +1002,7 @@ gst_mxf_demux_update_tracks (GstMXFDemux * demux)
       } else {
         pad->current_component_start += component->start_position;
       }
+      pad->current_component_position = pad->current_component_start;
     }
 
     /* NULL iff playing a source package */
@@ -1212,6 +1228,11 @@ gst_mxf_demux_handle_generic_container_system_item (GstMXFDemux * demux,
       "Handling generic container system item of size %u"
       " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
 
+  if (demux->current_partition->essence_container_offset == 0)
+    demux->current_partition->essence_container_offset =
+        demux->offset - demux->current_partition->partition.this_partition -
+        demux->run_in;
+
   /* TODO: parse this */
   return GST_FLOW_OK;
 }
@@ -1301,7 +1322,6 @@ gst_mxf_demux_pad_next_component (GstMXFDemux * demux, GstMXFDemuxPad * pad)
     return GST_FLOW_ERROR;
   }
 
-  pad->current_component_position = 0;
   pad->current_component_start = source_track->origin;
   if (pad->material_track->edit_rate.n != source_track->edit_rate.n ||
       pad->material_track->edit_rate.n != source_track->edit_rate.n) {
@@ -1313,6 +1333,7 @@ gst_mxf_demux_pad_next_component (GstMXFDemux * demux, GstMXFDemuxPad * pad)
   } else {
     pad->current_component_start += pad->current_component->start_position;
   }
+  pad->current_component_position = pad->current_component_start;
 
 
   if (!gst_caps_is_equal (GST_PAD_CAPS (pad), pad->current_essence_track->caps)) {
@@ -1331,7 +1352,6 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
   guint i;
   GstBuffer *inbuf;
   GstBuffer *outbuf = NULL;
-  GstMXFDemuxPad *pad = NULL;
   GstMXFDemuxEssenceTrack *etrack = NULL;
 
   GST_DEBUG_OBJECT (demux,
@@ -1343,6 +1363,12 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
   GST_DEBUG_OBJECT (demux, "  essence element type = 0x%02x", key->u[14]);
   GST_DEBUG_OBJECT (demux, "  essence element number = 0x%02x", key->u[15]);
 
+  if (demux->current_partition->essence_container_offset == 0)
+    demux->current_partition->essence_container_offset =
+        demux->offset - demux->current_partition->partition.this_partition -
+        demux->run_in;
+
+
   if (!demux->current_package) {
     GST_ERROR_OBJECT (demux, "No package selected yet");
     return GST_FLOW_ERROR;
@@ -1358,11 +1384,6 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
     return GST_FLOW_ERROR;
   }
 
-  if (GST_BUFFER_SIZE (buffer) == 0) {
-    GST_DEBUG_OBJECT (demux, "Zero sized essence element, ignoring");
-    return GST_FLOW_OK;
-  }
-
   track_number = GST_READ_UINT32_BE (&key->u[12]);
 
   for (i = 0; i < demux->essence_tracks->len; i++) {
@@ -1382,51 +1403,44 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
     return GST_FLOW_OK;
   }
 
-  /* TODO update essence tracks offsets, position, etc... */
-
-  for (i = 0; i < demux->src->len; i++) {
-    GstMXFDemuxPad *tmp = g_ptr_array_index (demux->src, i);
-
-    if (tmp->current_essence_track == etrack) {
-      pad = tmp;
-      break;
+  if (etrack->position == -1) {
+    GST_DEBUG_OBJECT (demux,
+        "Unknown essence track position, looking into index");
+    if (etrack->offsets) {
+      for (i = 0; i < etrack->offsets->len; i++) {
+        GstMXFDemuxIndex *idx =
+            &g_array_index (etrack->offsets, GstMXFDemuxIndex, i);
+
+        if (idx->offset != 0 && idx->offset == demux->offset - demux->run_in) {
+          etrack->position = i;
+          break;
+        }
+      }
     }
-  }
-
-  if (!pad) {
-    GST_DEBUG_OBJECT (demux, "No pad for essence track found");
-    return GST_FLOW_OK;
-  }
 
-  if (pad->eos) {
-    GST_DEBUG_OBJECT (demux, "Pad is already EOS");
-    return GST_FLOW_OK;
-  }
-
-  if (pad->current_component &&
-      pad->current_component_position < pad->current_component_start) {
-    GST_DEBUG_OBJECT (demux, "Before current component's start position");
-    pad->current_component_position++;
-    return GST_FLOW_OK;
+    if (etrack->position == -1) {
+      GST_WARNING_OBJECT (demux, "Essence track position not in index");
+      return GST_FLOW_OK;
+    }
   }
 
   /* Create subbuffer to be able to change metadata */
   inbuf = gst_buffer_create_sub (buffer, 0, GST_BUFFER_SIZE (buffer));
 
-  GST_BUFFER_TIMESTAMP (inbuf) = pad->last_stop;
-  GST_BUFFER_DURATION (inbuf) =
-      gst_util_uint64_scale (GST_SECOND, pad->material_track->edit_rate.d,
-      pad->material_track->edit_rate.n);
-  GST_BUFFER_OFFSET (inbuf) = GST_BUFFER_OFFSET_NONE;
-  GST_BUFFER_OFFSET_END (inbuf) = GST_BUFFER_OFFSET_NONE;
-  gst_buffer_set_caps (inbuf, etrack->caps);
+  if (etrack->offsets && etrack->offsets->len > etrack->position) {
+    if (!g_array_index (etrack->offsets, GstMXFDemuxIndex,
+            etrack->position).keyframe)
+      GST_BUFFER_FLAG_SET (inbuf, GST_BUFFER_FLAG_DELTA_UNIT);
+  }
+
+  if (etrack->duration <= etrack->position)
+    etrack->duration = etrack->position + 1;
 
   if (etrack->handle_func) {
     /* Takes ownership of inbuf */
     ret =
         etrack->handle_func (key, inbuf, etrack->caps,
-        etrack->source_track, pad->current_component, etrack->mapping_data,
-        &outbuf);
+        etrack->source_track, etrack->mapping_data, &outbuf);
     inbuf = NULL;
   } else {
     outbuf = inbuf;
@@ -1440,25 +1454,87 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
       gst_buffer_unref (outbuf);
       outbuf = NULL;
     }
+    return ret;
   }
 
-  if (pad->need_segment) {
-    gst_pad_push_event (GST_PAD_CAST (pad),
-        gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1, 0));
-    pad->need_segment = FALSE;
+  if (!etrack->offsets)
+    etrack->offsets = g_array_new (FALSE, TRUE, sizeof (GstMXFDemuxIndex));
+
+  {
+    if (etrack->offsets->len > etrack->position) {
+      GstMXFDemuxIndex *index =
+          &g_array_index (etrack->offsets, GstMXFDemuxIndex, etrack->position);
+
+      index->offset = demux->offset - demux->run_in;
+      index->keyframe =
+          (outbuf) ? !GST_BUFFER_FLAG_IS_SET (outbuf,
+          GST_BUFFER_FLAG_DELTA_UNIT) : TRUE;
+    } else {
+      GstMXFDemuxIndex index;
+
+      index.offset = demux->offset - demux->run_in;
+      index.keyframe =
+          (outbuf) ? !GST_BUFFER_FLAG_IS_SET (outbuf,
+          GST_BUFFER_FLAG_DELTA_UNIT) : TRUE;
+      g_array_insert_val (etrack->offsets, etrack->position, index);
+    }
   }
 
-  if (pad->tags) {
-    gst_element_found_tags_for_pad (GST_ELEMENT_CAST (demux),
-        GST_PAD_CAST (pad), pad->tags);
-    pad->tags = NULL;
+  if (!outbuf) {
+    GST_DEBUG_OBJECT (demux, "No output buffer created");
+    goto out;
   }
 
+  inbuf = outbuf;
+  outbuf = NULL;
+
+  gst_buffer_set_caps (inbuf, etrack->caps);
+
+  for (i = 0; i < demux->src->len; i++) {
+    GstMXFDemuxPad *pad = g_ptr_array_index (demux->src, i);
+
+    if (pad->current_essence_track != etrack)
+      continue;
+
+    if (pad->eos) {
+      GST_DEBUG_OBJECT (demux, "Pad is already EOS");
+      continue;
+    }
+    if (pad->current_component &&
+        etrack->position < pad->current_component_position) {
+      GST_DEBUG_OBJECT (demux, "Before current component's position");
+      continue;
+    }
+
+    /* Create another subbuffer to have writable metadata */
+    outbuf = gst_buffer_create_sub (inbuf, 0, GST_BUFFER_SIZE (inbuf));
+
+    GST_BUFFER_TIMESTAMP (outbuf) = pad->last_stop;
+    /* FIXME: What about tracks with source track edit rate != material
+     *        track edit rate? Use one of them and set the relative rate
+     *        to the other one as "rate" for the segment?
+     */
+    GST_BUFFER_DURATION (outbuf) =
+        gst_util_uint64_scale (GST_SECOND, pad->material_track->edit_rate.d,
+        pad->material_track->edit_rate.n);
+    GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET_NONE;
+    GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_NONE;
+
+    if (pad->need_segment) {
+      gst_pad_push_event (GST_PAD_CAST (pad),
+          gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1,
+              GST_BUFFER_TIMESTAMP (outbuf)));
+      pad->need_segment = FALSE;
+    }
+
+    if (pad->tags) {
+      gst_element_found_tags_for_pad (GST_ELEMENT_CAST (demux),
+          GST_PAD_CAST (pad), pad->tags);
+      pad->tags = NULL;
+    }
 
-  if (outbuf)
     pad->last_stop += GST_BUFFER_DURATION (outbuf);
 
-  if (outbuf) {
     GST_DEBUG_OBJECT (demux,
         "Pushing buffer of size %u for track %u: timestamp %" GST_TIME_FORMAT
         " duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (outbuf),
@@ -1473,48 +1549,52 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
 
     ret = gst_pad_push (GST_PAD_CAST (pad), outbuf);
     ret = gst_mxf_demux_combine_flows (demux, pad, ret);
-  } else {
-    GST_DEBUG_OBJECT (demux, "Dropping buffer for track %u",
-        pad->material_track->parent.track_id);
-  }
-
-  if (ret != GST_FLOW_OK)
-    return ret;
-
-  if (pad->current_component) {
-    pad->current_component_position++;
-    if (pad->current_component->parent.duration != -1 &&
-        pad->current_component_position - pad->current_component_start
-        >= pad->current_component->parent.duration) {
-      GST_DEBUG_OBJECT (demux, "Switching to next component");
 
-      if ((ret = gst_mxf_demux_pad_next_component (demux, pad)) != GST_FLOW_OK) {
-        if (ret == GST_FLOW_UNEXPECTED) {
-          gboolean eos = TRUE;
-
-          GST_DEBUG_OBJECT (demux, "EOS for track");
-          pad->eos = TRUE;
-
-          for (i = 0; i < demux->src->len; i++) {
-            GstMXFDemuxPad *opad = g_ptr_array_index (demux->src, i);
-
-            eos &= opad->eos;
-          }
+    if (ret != GST_FLOW_OK)
+      break;
 
-          if (eos) {
-            GST_DEBUG_OBJECT (demux, "All tracks are EOS");
-            return GST_FLOW_UNEXPECTED;
+    if (pad->current_component) {
+      pad->current_component_position++;
+      if (pad->current_component->parent.duration != -1 &&
+          pad->current_component_position - pad->current_component_start
+          >= pad->current_component->parent.duration) {
+        GST_DEBUG_OBJECT (demux, "Switching to next component");
+
+        if ((ret =
+                gst_mxf_demux_pad_next_component (demux, pad)) != GST_FLOW_OK) {
+          if (ret == GST_FLOW_UNEXPECTED) {
+            gboolean eos = TRUE;
+
+            GST_DEBUG_OBJECT (demux, "EOS for track");
+            pad->eos = TRUE;
+
+            for (i = 0; i < demux->src->len; i++) {
+              GstMXFDemuxPad *opad = g_ptr_array_index (demux->src, i);
+
+              eos &= opad->eos;
+            }
+
+            if (eos) {
+              GST_DEBUG_OBJECT (demux, "All tracks are EOS");
+              ret = GST_FLOW_UNEXPECTED;
+              break;
+            } else {
+              ret = GST_FLOW_OK;
+            }
           } else {
-            return GST_FLOW_OK;
+            GST_ERROR_OBJECT (demux, "Switching component failed");
+            break;
           }
-        } else {
-          GST_ERROR_OBJECT (demux, "Switching component failed");
-          return ret;
         }
       }
     }
   }
 
+out:
+  gst_buffer_unref (inbuf);
+
+  etrack->position++;
+
   return ret;
 }
 
@@ -1523,6 +1603,7 @@ gst_mxf_demux_handle_random_index_pack (GstMXFDemux * demux, const MXFUL * key,
     GstBuffer * buffer)
 {
   guint i;
+  GList *l;
 
   GST_DEBUG_OBJECT (demux,
       "Handling random index pack of size %u at offset %"
@@ -1540,7 +1621,6 @@ gst_mxf_demux_handle_random_index_pack (GstMXFDemux * demux, const MXFUL * key,
   }
 
   for (i = 0; i < demux->random_index_pack->len; i++) {
-    GList *l;
     GstMXFDemuxPartition *p = NULL;
     MXFRandomIndexPackEntry *e =
         &g_array_index (demux->random_index_pack, MXFRandomIndexPackEntry, i);
@@ -1563,10 +1643,24 @@ gst_mxf_demux_handle_random_index_pack (GstMXFDemux * demux, const MXFUL * key,
       p = g_new0 (GstMXFDemuxPartition, 1);
       p->partition.this_partition = e->offset - demux->run_in;
       p->partition.body_sid = e->body_sid;
-      demux->partitions = g_list_prepend (demux->partitions, p);
+      demux->partitions =
+          g_list_insert_sorted (demux->partitions, p,
+          (GCompareFunc) gst_mxf_demux_partition_compare);
     }
   }
 
+  for (l = demux->partitions; l; l = l->next) {
+    GstMXFDemuxPartition *a, *b;
+
+    if (l->next == NULL);
+    break;
+
+    a = l->data;
+    b = l->next->data;
+
+    b->partition.prev_partition = a->partition.this_partition;
+  }
+
   return GST_FLOW_OK;
 }
 
@@ -1884,6 +1978,12 @@ next_try:
       demux->offset += read;
       gst_buffer_unref (buffer);
       buffer = NULL;
+    } else if (mxf_is_generic_container_system_item (&key) ||
+        mxf_is_generic_container_essence_element (&key)) {
+      demux->offset += read;
+      gst_buffer_unref (buffer);
+      buffer = NULL;
+      break;
     } else {
       demux->offset += read;
       gst_buffer_unref (buffer);
@@ -1921,9 +2021,11 @@ gst_mxf_demux_handle_klv_packet (GstMXFDemux * demux, const MXFUL * key,
 
   if (demux->update_metadata
       && demux->preface
-      && demux->offset >=
-      demux->run_in + demux->current_partition->primer.offset +
-      demux->current_partition->partition.header_byte_count) {
+      && (demux->offset >=
+          demux->run_in + demux->current_partition->primer.offset +
+          demux->current_partition->partition.header_byte_count ||
+          mxf_is_generic_container_system_item (key) ||
+          mxf_is_generic_container_essence_element (key))) {
     demux->current_partition->parsed_metadata = TRUE;
     if ((ret = gst_mxf_demux_resolve_references (demux)) != GST_FLOW_OK)
       goto beach;
index e76f5e1..e431e30 100644 (file)
@@ -54,6 +54,7 @@ typedef struct
   MXFPartitionPack partition;
   MXFPrimerPack primer;
   gboolean parsed_metadata;
+  guint64 essence_container_offset;
 } GstMXFDemuxPartition;
 
 typedef struct
@@ -67,13 +68,10 @@ typedef struct
   guint32 body_sid;
   guint32 track_number;
 
-  guint64 position;
-  guint64 duration;
+  gint64 position;
+  gint64 duration;
 
-  GstMXFDemuxIndex *offsets;
-
-  guint64 last_offset;
-  guint64 last_indexed_offset;
+  GArray *offsets;
 
   MXFMetadataSourcePackage *source_package;
   MXFMetadataTimelineTrack *source_track;
index 67610e3..256bdda 100644 (file)
@@ -70,8 +70,7 @@ static GstFlowReturn
 mxf_dv_dif_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
     GstCaps * caps,
     MXFMetadataTimelineTrack * track,
-    MXFMetadataSourceClip * component, gpointer mapping_data,
-    GstBuffer ** outbuf)
+    gpointer mapping_data, GstBuffer ** outbuf)
 {
   *outbuf = buffer;
 
index 84680bc..c9d7b2a 100644 (file)
@@ -70,8 +70,7 @@ static GstFlowReturn
 mxf_jpeg2000_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
     GstCaps * caps,
     MXFMetadataTimelineTrack * track,
-    MXFMetadataSourceClip * component, gpointer mapping_data,
-    GstBuffer ** outbuf)
+    gpointer mapping_data, GstBuffer ** outbuf)
 {
   *outbuf = buffer;
 
@@ -106,10 +105,10 @@ mxf_jpeg2000_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
     if (!track->parent.descriptor[i])
       continue;
 
-    if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track->
-            parent.descriptor[i])) {
-      p = (MXFMetadataGenericPictureEssenceDescriptor *) track->parent.
-          descriptor[i];
+    if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track->parent.
+            descriptor[i])) {
+      p = (MXFMetadataGenericPictureEssenceDescriptor *) track->
+          parent.descriptor[i];
       f = track->parent.descriptor[i];
       break;
     } else if (MXF_IS_METADATA_FILE_DESCRIPTOR (track->parent.descriptor[i]) &&
index 86a5b1f..5bfa456 100644 (file)
@@ -256,8 +256,7 @@ mxf_is_mpeg_essence_track (const MXFMetadataTimelineTrack * track)
 static GstFlowReturn
 mxf_mpeg_video_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
     GstCaps * caps, MXFMetadataTimelineTrack * track,
-    MXFMetadataSourceClip * component, gpointer mapping_data,
-    GstBuffer ** outbuf)
+    gpointer mapping_data, GstBuffer ** outbuf)
 {
   *outbuf = buffer;
 
@@ -274,8 +273,7 @@ mxf_mpeg_video_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
 static GstFlowReturn
 mxf_mpeg_audio_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
     GstCaps * caps, MXFMetadataTimelineTrack * track,
-    MXFMetadataSourceClip * component, gpointer mapping_data,
-    GstBuffer ** outbuf)
+    gpointer mapping_data, GstBuffer ** outbuf)
 {
   *outbuf = buffer;
 
@@ -488,17 +486,17 @@ mxf_mpeg_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
     if (!track->parent.descriptor[i])
       continue;
 
-    if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track->
-            parent.descriptor[i])) {
+    if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track->parent.
+            descriptor[i])) {
       f = track->parent.descriptor[i];
-      p = (MXFMetadataGenericPictureEssenceDescriptor *) track->parent.
-          descriptor[i];
+      p = (MXFMetadataGenericPictureEssenceDescriptor *) track->
+          parent.descriptor[i];
       break;
-    } else if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->
-            parent.descriptor[i])) {
+    } else if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->parent.
+            descriptor[i])) {
       f = track->parent.descriptor[i];
-      s = (MXFMetadataGenericSoundEssenceDescriptor *) track->parent.
-          descriptor[i];
+      s = (MXFMetadataGenericSoundEssenceDescriptor *) track->
+          parent.descriptor[i];
       break;
     }
   }
index 3e6e91b..9c02480 100644 (file)
@@ -27,7 +27,7 @@
 #include "mxftypes.h"
 #include "mxfmetadata.h"
 
-typedef GstFlowReturn (*MXFEssenceElementHandleFunc) (const MXFUL *key, GstBuffer *buffer, GstCaps *caps, MXFMetadataTimelineTrack *track, MXFMetadataSourceClip *component, gpointer mapping_data, GstBuffer **outbuf);
+typedef GstFlowReturn (*MXFEssenceElementHandleFunc) (const MXFUL *key, GstBuffer *buffer, GstCaps *caps, MXFMetadataTimelineTrack *track, gpointer mapping_data, GstBuffer **outbuf);
 
 typedef struct {
   gboolean (*handles_track) (const MXFMetadataTimelineTrack *track);
index 7ab8659..d109b9e 100644 (file)
@@ -80,8 +80,7 @@ static GstFlowReturn
 mxf_up_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
     GstCaps * caps,
     MXFMetadataTimelineTrack * track,
-    MXFMetadataSourceClip * component, gpointer mapping_data,
-    GstBuffer ** outbuf)
+    gpointer mapping_data, GstBuffer ** outbuf)
 {
   MXFUPMappingData *data = mapping_data;
 
@@ -222,19 +221,19 @@ mxf_up_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
     if (!track->parent.descriptor[i])
       continue;
 
-    if (MXF_IS_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (track->parent.
-            descriptor[i])) {
-      p = (MXFMetadataGenericPictureEssenceDescriptor *) track->parent.
-          descriptor[i];
-      r = (MXFMetadataRGBAPictureEssenceDescriptor *) track->parent.
-          descriptor[i];
-      break;
-    } else if (MXF_IS_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (track->
+    if (MXF_IS_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (track->
             parent.descriptor[i])) {
-      p = (MXFMetadataGenericPictureEssenceDescriptor *) track->parent.
-          descriptor[i];
-      c = (MXFMetadataCDCIPictureEssenceDescriptor *) track->parent.
-          descriptor[i];
+      p = (MXFMetadataGenericPictureEssenceDescriptor *) track->
+          parent.descriptor[i];
+      r = (MXFMetadataRGBAPictureEssenceDescriptor *) track->
+          parent.descriptor[i];
+      break;
+    } else if (MXF_IS_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (track->parent.
+            descriptor[i])) {
+      p = (MXFMetadataGenericPictureEssenceDescriptor *) track->
+          parent.descriptor[i];
+      c = (MXFMetadataCDCIPictureEssenceDescriptor *) track->
+          parent.descriptor[i];
     }
   }
 
index 48cf50a..497355e 100644 (file)
@@ -65,8 +65,7 @@ static GstFlowReturn
 mxf_vc3_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
     GstCaps * caps,
     MXFMetadataTimelineTrack * track,
-    MXFMetadataSourceClip * component, gpointer mapping_data,
-    GstBuffer ** outbuf)
+    gpointer mapping_data, GstBuffer ** outbuf)
 {
   *outbuf = buffer;
 
@@ -100,10 +99,10 @@ mxf_vc3_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
     if (!track->parent.descriptor[i])
       continue;
 
-    if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track->parent.
-            descriptor[i])) {
-      p = (MXFMetadataGenericPictureEssenceDescriptor *) track->
-          parent.descriptor[i];
+    if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track->
+            parent.descriptor[i])) {
+      p = (MXFMetadataGenericPictureEssenceDescriptor *) track->parent.
+          descriptor[i];
       f = track->parent.descriptor[i];
       break;
     } else if (MXF_IS_METADATA_FILE_DESCRIPTOR (track->parent.descriptor[i]) &&