summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog42
-rw-r--r--gst/mxf/mxfaes-bwf.c20
-rw-r--r--gst/mxf/mxfalaw.c10
-rw-r--r--gst/mxf/mxfd10.c20
-rw-r--r--gst/mxf/mxfdemux.c311
-rw-r--r--gst/mxf/mxfdv-dif.c2
-rw-r--r--gst/mxf/mxfjpeg2000.c10
-rw-r--r--gst/mxf/mxfmetadata.c5
-rw-r--r--gst/mxf/mxfmpeg.c20
-rw-r--r--gst/mxf/mxfparse.h2
-rw-r--r--gst/mxf/mxfup.c26
-rw-r--r--gst/mxf/mxfvc3.c10
-rw-r--r--tests/check/elements/mxfdemux.c1
13 files changed, 362 insertions, 117 deletions
diff --git a/ChangeLog b/ChangeLog
index 4cf1968f..3c2fea66 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,45 @@
+2008-12-31 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+
+ * gst/mxf/mxfaes-bwf.c: (mxf_bwf_handle_essence_element),
+ (mxf_aes3_handle_essence_element):
+ * gst/mxf/mxfalaw.c: (mxf_alaw_handle_essence_element):
+ * gst/mxf/mxfd10.c: (mxf_d10_picture_handle_essence_element),
+ (mxf_d10_sound_handle_essence_element):
+ * gst/mxf/mxfdemux.c: (gst_mxf_demux_pad_init),
+ (gst_mxf_demux_choose_package),
+ (gst_mxf_demux_handle_header_metadata_update_streams),
+ (gst_mxf_demux_pad_next_component),
+ (gst_mxf_demux_handle_generic_container_essence_element),
+ (gst_mxf_demux_parse_footer_metadata),
+ (gst_mxf_demux_handle_klv_packet), (gst_mxf_demux_src_query):
+ * gst/mxf/mxfdv-dif.c: (mxf_dv_dif_handle_essence_element):
+ * gst/mxf/mxfjpeg2000.c: (mxf_jpeg2000_handle_essence_element):
+ * gst/mxf/mxfmetadata.c: (mxf_metadata_sequence_init),
+ (mxf_metadata_structural_component_init),
+ (mxf_metadata_generic_picture_essence_descriptor_init):
+ * gst/mxf/mxfmpeg.c: (mxf_mpeg_video_handle_essence_element),
+ (mxf_mpeg_audio_handle_essence_element):
+ * gst/mxf/mxfparse.h:
+ * gst/mxf/mxfup.c: (mxf_up_handle_essence_element):
+ * gst/mxf/mxfvc3.c: (mxf_vc3_handle_essence_element):
+ * tests/check/elements/mxfdemux.c: (_sink_chain):
+ Implement support for OP2a/b/c and OP3a/b/c, i.e. tracks with
+ more than a single component. This currently only works for
+ the case where the components are stored in playback order
+ in the file.
+
+ Set some more default/distinguished values for the structural
+ metadata.
+
+ Make some types more strict by choosing the correct subclasses.
+
+ Set DISCONT flag on buffers after a component switch.
+
+ Take the last partition from the random index pack for the footer
+ partition of the header partition doesn't reference the footer
+ partition. This gives us the final structural metadata for
+ some more files in the beginning.
+
2008-12-29 Wim Taymans <wim.taymans@collabora.co.uk>
* gst/mpegdemux/gstmpegdemux.c: (gst_flups_demux_src_query),
diff --git a/gst/mxf/mxfaes-bwf.c b/gst/mxf/mxfaes-bwf.c
index 9acdf673..27609b69 100644
--- a/gst/mxf/mxfaes-bwf.c
+++ b/gst/mxf/mxfaes-bwf.c
@@ -574,7 +574,7 @@ static GstFlowReturn
mxf_bwf_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
GstCaps * caps,
MXFMetadataTimelineTrack * track,
- MXFMetadataStructuralComponent * component, gpointer mapping_data,
+ MXFMetadataSourceClip * component, gpointer mapping_data,
GstBuffer ** outbuf)
{
*outbuf = buffer;
@@ -593,7 +593,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,
- MXFMetadataStructuralComponent * component, gpointer mapping_data,
+ MXFMetadataSourceClip * component, gpointer mapping_data,
GstBuffer ** outbuf)
{
*outbuf = buffer;
@@ -812,24 +812,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;
}
diff --git a/gst/mxf/mxfalaw.c b/gst/mxf/mxfalaw.c
index 1cea993a..a5ba98fb 100644
--- a/gst/mxf/mxfalaw.c
+++ b/gst/mxf/mxfalaw.c
@@ -65,7 +65,7 @@ static GstFlowReturn
mxf_alaw_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
GstCaps * caps,
MXFMetadataTimelineTrack * track,
- MXFMetadataStructuralComponent * component, gpointer mapping_data,
+ MXFMetadataSourceClip * component, gpointer mapping_data,
GstBuffer ** outbuf)
{
*outbuf = buffer;
@@ -100,10 +100,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;
}
}
diff --git a/gst/mxf/mxfd10.c b/gst/mxf/mxfd10.c
index bbc02ecf..6af96006 100644
--- a/gst/mxf/mxfd10.c
+++ b/gst/mxf/mxfd10.c
@@ -71,7 +71,7 @@ static GstFlowReturn
mxf_d10_picture_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
GstCaps * caps,
MXFMetadataTimelineTrack * track,
- MXFMetadataStructuralComponent * component, gpointer mapping_data,
+ MXFMetadataSourceClip * component, gpointer mapping_data,
GstBuffer ** outbuf)
{
*outbuf = buffer;
@@ -89,7 +89,7 @@ static GstFlowReturn
mxf_d10_sound_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
GstCaps * caps,
MXFMetadataTimelineTrack * track,
- MXFMetadataStructuralComponent * component, gpointer mapping_data,
+ MXFMetadataSourceClip * component, gpointer mapping_data,
GstBuffer ** outbuf)
{
guint i, j, nsamples;
@@ -173,15 +173,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;
}
}
diff --git a/gst/mxf/mxfdemux.c b/gst/mxf/mxfdemux.c
index 88048bf0..be6ff40e 100644
--- a/gst/mxf/mxfdemux.c
+++ b/gst/mxf/mxfdemux.c
@@ -35,10 +35,10 @@
* - Differentiate UL and UUIDs, the former can define an object system
* (i.e. mxf_ul_is_a() and friends could be implemented), see SMPTE S336M.
* The latter are just 16 byte unique identifiers
+ * - Differentiate between "Generation UID" and "This Generation UID" and move
+ * them from MXFMetadataBase to MXFMetadata*.
* - Check everything for correctness vs. SMPTE S336M, some things can probably
* be generalized/simplified
- * - Correctly timestamp essence streams and start/stop at the correct positions.
- * Also switch between different structural components after one has ended.
* - Seeking support: IndexTableSegments and skip-to-position seeks, needs correct
* timestamp calculation, etc.
* - Handle timecode tracks correctly (where is this documented?)
@@ -98,19 +98,23 @@ typedef struct
guint32 track_id;
gboolean need_segment;
+ GstClockTime last_stop;
GstFlowReturn last_flow;
+ gboolean eos, discont;
- guint64 essence_element_count;
gpointer mapping_data;
const MXFEssenceElementHandler *handler;
MXFEssenceElementHandleFunc handle_func;
GstTagList *tags;
- guint current_material_component;
MXFMetadataGenericPackage *material_package;
MXFMetadataTimelineTrack *material_track;
- MXFMetadataStructuralComponent *component;
+ MXFMetadataSourceClip *component;
+
+ guint current_component;
+ gint64 current_component_position;
+ gint64 current_component_drop;
MXFMetadataSourcePackage *source_package;
MXFMetadataTimelineTrack *source_track;
@@ -156,6 +160,7 @@ static void
gst_mxf_demux_pad_init (GstMXFDemuxPad * pad)
{
pad->last_flow = GST_FLOW_OK;
+ pad->last_stop = 0;
}
enum
@@ -583,6 +588,7 @@ gst_mxf_demux_handle_header_metadata_update_streams (GstMXFDemux * demux)
MXFMetadataGenericPackage *current_package = NULL;
guint i, j, k;
gboolean first_run;
+ guint component_index;
GST_DEBUG_OBJECT (demux, "Updating streams");
@@ -605,7 +611,7 @@ gst_mxf_demux_handle_header_metadata_update_streams (GstMXFDemux * demux)
for (i = 0; i < current_package->n_tracks; i++) {
MXFMetadataTimelineTrack *track = NULL;
MXFMetadataSequence *sequence;
- MXFMetadataStructuralComponent *component = NULL;
+ MXFMetadataSourceClip *component = NULL;
MXFMetadataSourcePackage *source_package = NULL;
MXFMetadataTimelineTrack *source_track = NULL;
GstMXFDemuxPad *pad = NULL;
@@ -625,6 +631,23 @@ gst_mxf_demux_handle_header_metadata_update_streams (GstMXFDemux * demux)
track = MXF_METADATA_TIMELINE_TRACK (current_package->tracks[i]);
+ if (demux->src && demux->src->len > 0) {
+ /* Find pad from track_id */
+ for (j = 0; j < demux->src->len; j++) {
+ GstMXFDemuxPad *tmp = g_ptr_array_index (demux->src, j);
+
+ if (tmp->track_id == track->parent.track_id) {
+ pad = tmp;
+ break;
+ }
+ }
+ }
+
+ if (pad)
+ component_index = pad->current_component;
+ else
+ component_index = 0;
+
if (!track->parent.sequence) {
GST_WARNING_OBJECT (demux, "Track with no sequence");
continue;
@@ -633,31 +656,34 @@ gst_mxf_demux_handle_header_metadata_update_streams (GstMXFDemux * demux)
sequence = track->parent.sequence;
if (MXF_IS_METADATA_SOURCE_PACKAGE (current_package)) {
+ GST_DEBUG_OBJECT (demux, "Playing source package");
+
+ component = NULL;
source_package = MXF_METADATA_SOURCE_PACKAGE (current_package);
source_track = track;
- }
+ } else if (sequence->structural_components
+ &&
+ MXF_IS_METADATA_SOURCE_CLIP (sequence->structural_components
+ [component_index])) {
+ GST_DEBUG_OBJECT (demux, "Playing material package");
- /* TODO: handle multiple components, see SMPTE 377M page 37 */
- if (sequence->structural_components && sequence->structural_components[0]) {
- component = sequence->structural_components[0];
+ component =
+ MXF_METADATA_SOURCE_CLIP (sequence->structural_components
+ [component_index]);
- if (!source_package && MXF_IS_METADATA_SOURCE_CLIP (component)) {
- MXFMetadataSourceClip *clip = MXF_METADATA_SOURCE_CLIP (component);
+ if (component->source_package && component->source_package->top_level &&
+ MXF_METADATA_GENERIC_PACKAGE (component->source_package)->tracks) {
+ MXFMetadataGenericPackage *tmp_pkg =
+ MXF_METADATA_GENERIC_PACKAGE (component->source_package);
- if (clip->source_package && clip->source_package->top_level &&
- MXF_METADATA_GENERIC_PACKAGE (clip->source_package)->tracks) {
- MXFMetadataGenericPackage *tmp_pkg =
- MXF_METADATA_GENERIC_PACKAGE (clip->source_package);
+ source_package = component->source_package;
- source_package = clip->source_package;
+ for (k = 0; k < tmp_pkg->n_tracks; k++) {
+ MXFMetadataTrack *tmp = tmp_pkg->tracks[k];
- for (k = 0; k < tmp_pkg->n_tracks; k++) {
- MXFMetadataTrack *tmp = tmp_pkg->tracks[k];
-
- if (tmp->track_id == clip->source_track_id) {
- source_track = MXF_METADATA_TIMELINE_TRACK (tmp);
- break;
- }
+ if (tmp->track_id == component->source_track_id) {
+ source_track = MXF_METADATA_TIMELINE_TRACK (tmp);
+ break;
}
}
}
@@ -669,12 +695,18 @@ gst_mxf_demux_handle_header_metadata_update_streams (GstMXFDemux * demux)
}
if (!source_package || track->parent.type == MXF_METADATA_TRACK_UNKNOWN
- || !source_track || !component) {
+ || !source_track) {
GST_WARNING_OBJECT (demux,
"No source package or track type for track found");
continue;
}
+ if (MXF_IS_METADATA_MATERIAL_PACKAGE (current_package) && !component) {
+ GST_WARNING_OBJECT (demux,
+ "Playing material package but found no component for track");
+ continue;
+ }
+
if (!source_package->descriptors) {
GST_WARNING_OBJECT (demux, "Source package has no descriptors");
continue;
@@ -685,18 +717,6 @@ gst_mxf_demux_handle_header_metadata_update_streams (GstMXFDemux * demux)
continue;
}
- if (demux->src && demux->src->len > 0) {
- /* Find pad from track_id */
- for (j = 0; j < demux->src->len; j++) {
- GstMXFDemuxPad *tmp = g_ptr_array_index (demux->src, j);
-
- if (tmp->track_id == track->parent.track_id) {
- pad = tmp;
- break;
- }
- }
- }
-
if (!pad && first_run) {
GstPadTemplate *templ;
gchar *pad_name;
@@ -712,6 +732,7 @@ gst_mxf_demux_handle_header_metadata_update_streams (GstMXFDemux * demux)
pad = (GstMXFDemuxPad *) g_object_new (GST_TYPE_MXF_DEMUX_PAD,
"name", pad_name, "direction", GST_PAD_SRC, "template", templ, NULL);
pad->need_segment = TRUE;
+ pad->eos = FALSE;
g_free (pad_name);
}
@@ -726,7 +747,25 @@ gst_mxf_demux_handle_header_metadata_update_streams (GstMXFDemux * demux)
pad->material_package = current_package;
pad->material_track = track;
- pad->current_material_component = 0;
+
+ /* If we just added the pad initialize for the current component */
+ if (first_run && MXF_IS_METADATA_MATERIAL_PACKAGE (current_package)) {
+ pad->current_component = 0;
+ pad->current_component_position = 0;
+ pad->current_component_drop = source_track->origin;
+ if (track->edit_rate.n != source_track->edit_rate.n ||
+ track->edit_rate.n != source_track->edit_rate.n) {
+
+ pad->current_component_drop +=
+ gst_util_uint64_scale (component->start_position,
+ source_track->edit_rate.n * track->edit_rate.d,
+ source_track->edit_rate.d * track->edit_rate.n);
+ } else {
+ pad->current_component_drop += component->start_position;
+ }
+ }
+
+ /* NULL iff playing a source package */
pad->component = component;
pad->source_package = source_package;
@@ -780,6 +819,7 @@ gst_mxf_demux_handle_header_metadata_update_streams (GstMXFDemux * demux)
if (!demux->src)
demux->src = g_ptr_array_new ();
g_ptr_array_add (demux->src, pad);
+ pad->discont = TRUE;
}
gst_caps_unref (caps);
}
@@ -913,6 +953,113 @@ gst_mxf_demux_handle_generic_container_system_item (GstMXFDemux * demux,
}
static GstFlowReturn
+gst_mxf_demux_pad_next_component (GstMXFDemux * demux, GstMXFDemuxPad * pad)
+{
+ MXFMetadataSequence *sequence;
+ guint k;
+ GstCaps *caps = NULL;
+
+ pad->current_component++;
+
+ sequence = pad->material_track->parent.sequence;
+
+ if (pad->current_component >= sequence->n_structural_components) {
+ GST_DEBUG_OBJECT (demux, "After last structural component");
+ return GST_FLOW_UNEXPECTED;
+ }
+
+ pad->component =
+ MXF_METADATA_SOURCE_CLIP (sequence->
+ structural_components[pad->current_component]);
+ if (pad->component == NULL) {
+ GST_ERROR_OBJECT (demux, "No such structural component");
+ return GST_FLOW_ERROR;
+ }
+
+ if (!pad->component->source_package
+ || !pad->component->source_package->top_level
+ || !MXF_METADATA_GENERIC_PACKAGE (pad->component->source_package)->
+ tracks) {
+ GST_ERROR_OBJECT (demux, "Invalid component");
+ return GST_FLOW_ERROR;
+ }
+
+ pad->source_package = pad->component->source_package;
+ pad->source_track = NULL;
+
+ for (k = 0; k < pad->source_package->parent.n_tracks; k++) {
+ MXFMetadataTrack *tmp = pad->source_package->parent.tracks[k];
+
+ if (tmp->track_id == pad->component->source_track_id) {
+ pad->source_track = MXF_METADATA_TIMELINE_TRACK (tmp);
+ break;
+ }
+ }
+
+ if (!pad->source_track) {
+ GST_ERROR_OBJECT (demux, "No source track found");
+ return GST_FLOW_ERROR;
+ }
+
+ if (!pad->source_package->descriptors) {
+ GST_ERROR_OBJECT (demux, "Source package has no descriptors");
+ return GST_FLOW_ERROR;
+ }
+
+ if (!pad->source_track->parent.descriptor) {
+ GST_ERROR_OBJECT (demux, "No descriptor found for track");
+ return GST_FLOW_ERROR;
+ }
+
+
+ pad->current_component_position = 0;
+ pad->current_component_drop = pad->source_track->origin;
+ if (pad->material_track->edit_rate.n != pad->source_track->edit_rate.n ||
+ pad->material_track->edit_rate.n != pad->source_track->edit_rate.n) {
+
+ pad->current_component_drop +=
+ gst_util_uint64_scale (pad->component->start_position,
+ pad->source_track->edit_rate.n * pad->material_track->edit_rate.d,
+ pad->source_track->edit_rate.d * pad->material_track->edit_rate.n);
+ } else {
+ pad->current_component_drop += pad->component->start_position;
+ }
+
+
+ pad->handler = NULL;
+ g_free (pad->mapping_data);
+ pad->handle_func = NULL;
+ pad->mapping_data = NULL;
+
+ pad->handler = mxf_essence_element_handler_find (pad->source_track);
+
+ if (!pad->handler) {
+ GST_ERROR_OBJECT (demux, "No essence element handler for track found");
+ return GST_FLOW_ERROR;
+ }
+
+ caps =
+ pad->handler->create_caps (pad->source_track, &pad->tags,
+ &pad->handle_func, &pad->mapping_data);
+
+ if (!caps) {
+ GST_ERROR_OBJECT (demux, "No caps created");
+ return GST_FLOW_ERROR;
+ }
+
+ GST_DEBUG_OBJECT (demux, "Created caps %" GST_PTR_FORMAT, caps);
+
+ if (!gst_caps_is_equal (pad->caps, caps)) {
+ gst_pad_set_caps (GST_PAD_CAST (pad), caps);
+ gst_caps_replace (&pad->caps, gst_caps_ref (caps));
+ }
+
+ gst_caps_unref (caps);
+
+ return GST_FLOW_OK;
+}
+
+static GstFlowReturn
gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
const MXFUL * key, GstBuffer * buffer)
{
@@ -983,6 +1130,12 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
return GST_FLOW_OK;
}
+ if (pad->component && pad->current_component_drop > 0) {
+ GST_DEBUG_OBJECT (demux, "Before component start, dropping");
+ pad->current_component_drop--;
+ return GST_FLOW_OK;
+ }
+
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));
@@ -998,15 +1151,12 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
/* Create subbuffer to be able to change metadata */
inbuf = gst_buffer_create_sub (buffer, 0, GST_BUFFER_SIZE (buffer));
- GST_BUFFER_TIMESTAMP (inbuf) =
- gst_util_uint64_scale (pad->essence_element_count +
- pad->material_track->origin,
- GST_SECOND * pad->material_track->edit_rate.d,
- pad->material_track->edit_rate.n);
+ //FIXME broken!
+ 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) = pad->essence_element_count;
+ GST_BUFFER_OFFSET (inbuf) = GST_BUFFER_OFFSET_NONE;
GST_BUFFER_OFFSET_END (inbuf) = GST_BUFFER_OFFSET_NONE;
gst_buffer_set_caps (inbuf, pad->caps);
@@ -1022,8 +1172,6 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
ret = GST_FLOW_OK;
}
- pad->essence_element_count++;
-
if (ret != GST_FLOW_OK) {
GST_ERROR_OBJECT (demux, "Failed to handle essence element");
if (outbuf) {
@@ -1032,6 +1180,9 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
}
}
+ if (outbuf)
+ pad->last_stop += GST_BUFFER_DURATION (outbuf);
+
if (outbuf) {
/* TODO: handle timestamp gaps */
GST_DEBUG_OBJECT (demux,
@@ -1040,6 +1191,12 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
pad->material_track->parent.track_id,
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
+
+ if (pad->discont) {
+ GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
+ pad->discont = FALSE;
+ }
+
ret = gst_pad_push (GST_PAD_CAST (pad), outbuf);
ret = gst_mxf_demux_combine_flows (demux, pad, ret);
} else {
@@ -1047,6 +1204,42 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
pad->material_track->parent.track_id);
}
+ if (ret != GST_FLOW_OK)
+ return ret;
+
+ if (pad->component) {
+ pad->current_component_position++;
+ if (pad->component->parent.duration != -1 &&
+ pad->current_component_position >= pad->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");
+ return GST_FLOW_UNEXPECTED;
+ } else {
+ return GST_FLOW_OK;
+ }
+ } else {
+ GST_ERROR_OBJECT (demux, "Switching component failed");
+ return ret;
+ }
+ }
+ }
+ }
+
return ret;
}
@@ -1271,8 +1464,17 @@ gst_mxf_demux_parse_footer_metadata (GstMXFDemux * demux)
memset (&demux->primer, 0, sizeof (MXFPrimerPack));
gst_mxf_demux_reset_metadata (demux);
- offset =
- demux->header_partition_pack_offset + demux->footer_partition_pack_offset;
+
+ if (demux->footer_partition_pack_offset != 0) {
+ offset =
+ demux->header_partition_pack_offset +
+ demux->footer_partition_pack_offset;
+ } else {
+ MXFRandomIndexPackEntry *entry =
+ &g_array_index (demux->partition_index, MXFRandomIndexPackEntry,
+ demux->partition_index->len - 1);
+ offset = entry->offset;
+ }
next_try:
mxf_partition_pack_reset (&demux->partition);
@@ -1465,7 +1667,8 @@ gst_mxf_demux_handle_klv_packet (GstMXFDemux * demux, const MXFUL * key,
&& demux->random_access && demux->partition.valid
&& demux->partition.type == MXF_PARTITION_PACK_HEADER
&& (!demux->partition.closed || !demux->partition.complete)
- && demux->footer_partition_pack_offset != 0) {
+ && (demux->footer_partition_pack_offset != 0 ||
+ demux->partition_index->len > 0)) {
GST_DEBUG_OBJECT (demux,
"Open or incomplete header partition, trying to get final metadata from the last partitions");
gst_mxf_demux_parse_footer_metadata (demux);
@@ -1809,16 +2012,16 @@ gst_mxf_demux_src_query (GstPad * pad, GstQuery * query)
if (format != GST_FORMAT_TIME && format != GST_FORMAT_DEFAULT)
goto error;
- pos = mxfpad->essence_element_count;
- if (format == GST_FORMAT_TIME) {
+ pos = mxfpad->last_stop;
+ if (format == GST_FORMAT_DEFAULT && pos != GST_CLOCK_TIME_NONE) {
if (!mxfpad->material_track || mxfpad->material_track->edit_rate.n == 0
|| mxfpad->material_track->edit_rate.d == 0)
goto error;
pos =
- gst_util_uint64_scale (pos + mxfpad->material_track->origin,
- GST_SECOND * mxfpad->material_track->edit_rate.d,
- mxfpad->material_track->edit_rate.n);
+ gst_util_uint64_scale (pos,
+ mxfpad->material_track->edit_rate.n,
+ mxfpad->material_track->edit_rate.d * GST_SECOND);
}
GST_DEBUG_OBJECT (pad,
diff --git a/gst/mxf/mxfdv-dif.c b/gst/mxf/mxfdv-dif.c
index 4cae16b4..2d5f4ba4 100644
--- a/gst/mxf/mxfdv-dif.c
+++ b/gst/mxf/mxfdv-dif.c
@@ -70,7 +70,7 @@ static GstFlowReturn
mxf_dv_dif_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
GstCaps * caps,
MXFMetadataTimelineTrack * track,
- MXFMetadataStructuralComponent * component, gpointer mapping_data,
+ MXFMetadataSourceClip * component, gpointer mapping_data,
GstBuffer ** outbuf)
{
*outbuf = buffer;
diff --git a/gst/mxf/mxfjpeg2000.c b/gst/mxf/mxfjpeg2000.c
index 1bc54c12..a08c426f 100644
--- a/gst/mxf/mxfjpeg2000.c
+++ b/gst/mxf/mxfjpeg2000.c
@@ -70,7 +70,7 @@ static GstFlowReturn
mxf_jpeg2000_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
GstCaps * caps,
MXFMetadataTimelineTrack * track,
- MXFMetadataStructuralComponent * component, gpointer mapping_data,
+ MXFMetadataSourceClip * component, gpointer mapping_data,
GstBuffer ** outbuf)
{
*outbuf = buffer;
@@ -106,10 +106,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]) &&
diff --git a/gst/mxf/mxfmetadata.c b/gst/mxf/mxfmetadata.c
index b360eaf5..e924ba69 100644
--- a/gst/mxf/mxfmetadata.c
+++ b/gst/mxf/mxfmetadata.c
@@ -1748,7 +1748,7 @@ mxf_metadata_sequence_resolve (MXFMetadataBase * m, MXFMetadataBase ** metadata)
static void
mxf_metadata_sequence_init (MXFMetadataSequence * self)
{
-
+ self->duration = -1;
}
static void
@@ -1810,7 +1810,7 @@ error:
static void
mxf_metadata_structural_component_init (MXFMetadataStructuralComponent * self)
{
-
+ self->duration = -1;
}
static void
@@ -2617,6 +2617,7 @@ static void
(MXFMetadataGenericPictureEssenceDescriptor * self)
{
self->signal_standard = 1;
+ self->frame_layout = 255;
}
static void
diff --git a/gst/mxf/mxfmpeg.c b/gst/mxf/mxfmpeg.c
index a836d7d0..574cc5a8 100644
--- a/gst/mxf/mxfmpeg.c
+++ b/gst/mxf/mxfmpeg.c
@@ -256,7 +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,
- MXFMetadataStructuralComponent * component, gpointer mapping_data,
+ MXFMetadataSourceClip * component, gpointer mapping_data,
GstBuffer ** outbuf)
{
*outbuf = buffer;
@@ -274,7 +274,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,
- MXFMetadataStructuralComponent * component, gpointer mapping_data,
+ MXFMetadataSourceClip * component, gpointer mapping_data,
GstBuffer ** outbuf)
{
*outbuf = buffer;
@@ -478,17 +478,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;
}
}
diff --git a/gst/mxf/mxfparse.h b/gst/mxf/mxfparse.h
index 831dabce..c0a617b2 100644
--- a/gst/mxf/mxfparse.h
+++ b/gst/mxf/mxfparse.h
@@ -27,7 +27,7 @@
#include "mxftypes.h"
#include "mxfmetadata.h"
-typedef GstFlowReturn (*MXFEssenceElementHandleFunc) (const MXFUL *key, GstBuffer *buffer, GstCaps *caps, MXFMetadataTimelineTrack *track, MXFMetadataStructuralComponent *component, gpointer mapping_data, GstBuffer **outbuf);
+typedef GstFlowReturn (*MXFEssenceElementHandleFunc) (const MXFUL *key, GstBuffer *buffer, GstCaps *caps, MXFMetadataTimelineTrack *track, MXFMetadataSourceClip *component, gpointer mapping_data, GstBuffer **outbuf);
typedef struct {
gboolean (*handles_track) (const MXFMetadataTimelineTrack *track);
diff --git a/gst/mxf/mxfup.c b/gst/mxf/mxfup.c
index c18a481f..afd8e2a1 100644
--- a/gst/mxf/mxfup.c
+++ b/gst/mxf/mxfup.c
@@ -80,7 +80,7 @@ static GstFlowReturn
mxf_up_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
GstCaps * caps,
MXFMetadataTimelineTrack * track,
- MXFMetadataStructuralComponent * component, gpointer mapping_data,
+ MXFMetadataSourceClip * component, gpointer mapping_data,
GstBuffer ** outbuf)
{
MXFUPMappingData *data = mapping_data;
@@ -222,19 +222,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];
}
}
diff --git a/gst/mxf/mxfvc3.c b/gst/mxf/mxfvc3.c
index 1b449673..1fcb2d7e 100644
--- a/gst/mxf/mxfvc3.c
+++ b/gst/mxf/mxfvc3.c
@@ -65,7 +65,7 @@ static GstFlowReturn
mxf_vc3_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
GstCaps * caps,
MXFMetadataTimelineTrack * track,
- MXFMetadataStructuralComponent * component, gpointer mapping_data,
+ MXFMetadataSourceClip * component, gpointer mapping_data,
GstBuffer ** outbuf)
{
*outbuf = buffer;
@@ -100,10 +100,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]) &&
diff --git a/tests/check/elements/mxfdemux.c b/tests/check/elements/mxfdemux.c
index 9fe84708..8c156deb 100644
--- a/tests/check/elements/mxfdemux.c
+++ b/tests/check/elements/mxfdemux.c
@@ -69,7 +69,6 @@ _sink_chain (GstPad * pad, GstBuffer * buffer)
fail_unless (GST_BUFFER_TIMESTAMP (buffer) == 0);
fail_unless (GST_BUFFER_DURATION (buffer) == 200 * GST_MSECOND);
- fail_unless (GST_BUFFER_OFFSET (buffer) == 0);
gst_buffer_unref (buffer);
gst_caps_unref (caps);