diff options
-rw-r--r-- | ChangeLog | 42 | ||||
-rw-r--r-- | gst/mxf/mxfaes-bwf.c | 20 | ||||
-rw-r--r-- | gst/mxf/mxfalaw.c | 10 | ||||
-rw-r--r-- | gst/mxf/mxfd10.c | 20 | ||||
-rw-r--r-- | gst/mxf/mxfdemux.c | 311 | ||||
-rw-r--r-- | gst/mxf/mxfdv-dif.c | 2 | ||||
-rw-r--r-- | gst/mxf/mxfjpeg2000.c | 10 | ||||
-rw-r--r-- | gst/mxf/mxfmetadata.c | 5 | ||||
-rw-r--r-- | gst/mxf/mxfmpeg.c | 20 | ||||
-rw-r--r-- | gst/mxf/mxfparse.h | 2 | ||||
-rw-r--r-- | gst/mxf/mxfup.c | 26 | ||||
-rw-r--r-- | gst/mxf/mxfvc3.c | 10 | ||||
-rw-r--r-- | tests/check/elements/mxfdemux.c | 1 |
13 files changed, 362 insertions, 117 deletions
@@ -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); |