2 * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * - start at correct position of the component, switch components
22 * - RandomIndex / IndexSegment support
24 * - descriptive metadata
25 * - generic container system items
34 #include "mxfaes-bwf.h"
36 #include "mxfdv-dif.h"
40 static GstStaticPadTemplate mxf_sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
43 GST_STATIC_CAPS ("application/mxf")
46 static GstStaticPadTemplate audio_src_template =
47 GST_STATIC_PAD_TEMPLATE ("audio_%u",
52 static GstStaticPadTemplate video_src_template =
53 GST_STATIC_PAD_TEMPLATE ("video_%u",
58 static GstStaticPadTemplate data_src_template =
59 GST_STATIC_PAD_TEMPLATE ("data_%u",
64 GST_DEBUG_CATEGORY_STATIC (mxfdemux_debug);
65 #define GST_CAT_DEFAULT mxfdemux_debug
67 #define GST_TYPE_MXF_PAD (gst_mxf_pad_get_type())
68 #define GST_MXF_PAD(pad) (G_TYPE_CHECK_INSTANCE_CAST((pad),GST_TYPE_MXF_PAD,GstMXFPad))
69 #define GST_MXF_PAD_CAST(pad) ((GstMXFPad *) pad)
70 #define GST_IS_MXF_PAD(pad) (G_TYPE_CHECK_INSTANCE_TYPE((pad),GST_TYPE_MXF_PAD))
77 MXFMetadataTrackType track_type;
78 gboolean need_segment;
80 GstFlowReturn last_flow;
82 guint64 essence_element_count;
83 MXFEssenceElementHandler handle_essence_element;
84 gpointer mapping_data;
88 guint current_material_component;
89 MXFMetadataGenericPackage *material_package;
90 MXFMetadataTrack *material_track;
91 MXFMetadataStructuralComponent *component;
93 MXFMetadataGenericPackage *source_package;
94 MXFMetadataTrack *source_track;
105 G_DEFINE_TYPE (GstMXFPad, gst_mxf_pad, GST_TYPE_PAD);
108 gst_mxf_pad_finalize (GObject * object)
110 GstMXFPad *pad = GST_MXF_PAD (object);
112 gst_caps_replace (&pad->caps, NULL);
114 g_free (pad->mapping_data);
115 pad->mapping_data = NULL;
118 gst_tag_list_free (pad->tags);
122 G_OBJECT_CLASS (gst_mxf_pad_parent_class)->finalize (object);
126 gst_mxf_pad_class_init (GstMXFPadClass * klass)
128 GObjectClass *gobject_class = (GObjectClass *) klass;
130 gobject_class->finalize = gst_mxf_pad_finalize;
134 gst_mxf_pad_init (GstMXFPad * pad)
136 pad->last_flow = GST_FLOW_OK;
139 static gboolean gst_mxf_demux_sink_event (GstPad * pad, GstEvent * event);
140 static gboolean gst_mxf_demux_src_event (GstPad * pad, GstEvent * event);
141 static const GstQueryType *gst_mxf_demux_src_query_type (GstPad * pad);
142 static gboolean gst_mxf_demux_src_query (GstPad * pad, GstQuery * query);
144 GST_BOILERPLATE (GstMXFDemux, gst_mxf_demux, GstElement, GST_TYPE_ELEMENT);
147 gst_mxf_demux_flush (GstMXFDemux * demux, gboolean discont)
149 GST_DEBUG_OBJECT (demux, "flushing queued data in the MXF demuxer");
151 gst_adapter_clear (demux->adapter);
153 demux->flushing = FALSE;
155 /* Only in push mode */
156 if (!demux->random_access) {
157 /* We reset the offset and will get one from first push */
163 gst_mxf_demux_remove_pad (GstMXFPad * pad, GstMXFDemux * demux)
165 gst_element_remove_pad (GST_ELEMENT (demux), GST_PAD (pad));
169 gst_mxf_demux_reset_mxf_state (GstMXFDemux * demux)
171 GST_DEBUG_OBJECT (demux, "Resetting MXF state");
172 mxf_partition_pack_reset (&demux->partition);
173 mxf_primer_pack_reset (&demux->primer);
177 gst_mxf_demux_reset_metadata (GstMXFDemux * demux)
181 GST_DEBUG_OBJECT (demux, "Resetting metadata");
183 demux->update_metadata = TRUE;
184 demux->final_metadata = FALSE;
186 demux->current_package = NULL;
189 for (i = 0; i < demux->src->len; i++) {
190 GstMXFPad *pad = g_ptr_array_index (demux->src, i);
192 pad->material_track = NULL;
193 pad->material_package = NULL;
194 pad->component = NULL;
195 pad->source_track = NULL;
196 pad->source_package = NULL;
200 mxf_metadata_preface_reset (&demux->preface);
202 if (demux->identification) {
203 for (i = 0; i < demux->identification->len; i++)
204 mxf_metadata_identification_reset (&g_array_index (demux->identification,
205 MXFMetadataIdentification, i));
206 g_array_free (demux->identification, TRUE);
207 demux->identification = NULL;
210 mxf_metadata_content_storage_reset (&demux->content_storage);
212 if (demux->essence_container_data) {
213 for (i = 0; i < demux->essence_container_data->len; i++)
214 mxf_metadata_essence_container_data_reset (&g_array_index
215 (demux->essence_container_data, MXFMetadataEssenceContainerData, i));
216 g_array_free (demux->essence_container_data, TRUE);
217 demux->essence_container_data = NULL;
220 if (demux->material_package) {
221 for (i = 0; i < demux->material_package->len; i++)
222 mxf_metadata_generic_package_reset (&g_array_index
223 (demux->material_package, MXFMetadataGenericPackage, i));
224 g_array_free (demux->material_package, TRUE);
225 demux->material_package = NULL;
228 if (demux->source_package) {
229 for (i = 0; i < demux->source_package->len; i++)
230 mxf_metadata_generic_package_reset (&g_array_index (demux->source_package,
231 MXFMetadataGenericPackage, i));
232 g_array_free (demux->source_package, TRUE);
233 demux->source_package = NULL;
236 if (demux->package) {
237 g_ptr_array_free (demux->package, TRUE);
238 demux->package = NULL;
242 for (i = 0; i < demux->track->len; i++)
243 mxf_metadata_track_reset (&g_array_index (demux->track,
244 MXFMetadataTrack, i));
245 g_array_free (demux->track, TRUE);
249 if (demux->sequence) {
250 for (i = 0; i < demux->sequence->len; i++)
251 mxf_metadata_sequence_reset (&g_array_index (demux->sequence,
252 MXFMetadataSequence, i));
253 g_array_free (demux->sequence, TRUE);
254 demux->sequence = NULL;
257 if (demux->structural_component) {
258 for (i = 0; i < demux->structural_component->len; i++)
259 mxf_metadata_structural_component_reset (&g_array_index
260 (demux->structural_component, MXFMetadataStructuralComponent, i));
261 g_array_free (demux->structural_component, TRUE);
262 demux->structural_component = NULL;
265 if (demux->generic_descriptor) {
266 for (i = 0; i < demux->generic_descriptor->len; i++)
267 mxf_metadata_generic_descriptor_reset (&g_array_index
268 (demux->generic_descriptor, MXFMetadataGenericDescriptor, i));
269 g_array_free (demux->generic_descriptor, TRUE);
270 demux->generic_descriptor = NULL;
273 if (demux->file_descriptor) {
274 for (i = 0; i < demux->file_descriptor->len; i++)
275 mxf_metadata_file_descriptor_reset (&g_array_index
276 (demux->file_descriptor, MXFMetadataFileDescriptor, i));
277 g_array_free (demux->file_descriptor, TRUE);
278 demux->file_descriptor = NULL;
281 if (demux->multiple_descriptor) {
282 for (i = 0; i < demux->multiple_descriptor->len; i++)
283 mxf_metadata_multiple_descriptor_reset (&g_array_index
284 (demux->multiple_descriptor, MXFMetadataMultipleDescriptor, i));
285 g_array_free (demux->multiple_descriptor, TRUE);
286 demux->multiple_descriptor = NULL;
289 if (demux->generic_picture_essence_descriptor) {
290 for (i = 0; i < demux->generic_picture_essence_descriptor->len; i++)
291 mxf_metadata_generic_picture_essence_descriptor_reset (&g_array_index
292 (demux->generic_picture_essence_descriptor,
293 MXFMetadataGenericPictureEssenceDescriptor, i));
294 g_array_free (demux->generic_picture_essence_descriptor, TRUE);
295 demux->generic_picture_essence_descriptor = NULL;
298 if (demux->cdci_picture_essence_descriptor) {
299 for (i = 0; i < demux->cdci_picture_essence_descriptor->len; i++)
300 mxf_metadata_cdci_picture_essence_descriptor_reset (&g_array_index
301 (demux->cdci_picture_essence_descriptor,
302 MXFMetadataCDCIPictureEssenceDescriptor, i));
303 g_array_free (demux->cdci_picture_essence_descriptor, TRUE);
304 demux->cdci_picture_essence_descriptor = NULL;
307 if (demux->rgba_picture_essence_descriptor) {
308 for (i = 0; i < demux->rgba_picture_essence_descriptor->len; i++)
309 mxf_metadata_rgba_picture_essence_descriptor_reset (&g_array_index
310 (demux->rgba_picture_essence_descriptor,
311 MXFMetadataRGBAPictureEssenceDescriptor, i));
312 g_array_free (demux->rgba_picture_essence_descriptor, TRUE);
313 demux->rgba_picture_essence_descriptor = NULL;
316 if (demux->mpeg_video_descriptor) {
317 for (i = 0; i < demux->mpeg_video_descriptor->len; i++)
318 mxf_metadata_mpeg_video_descriptor_reset (&g_array_index
319 (demux->mpeg_video_descriptor, MXFMetadataMPEGVideoDescriptor, i));
320 g_array_free (demux->mpeg_video_descriptor, TRUE);
321 demux->mpeg_video_descriptor = NULL;
324 if (demux->generic_sound_essence_descriptor) {
325 for (i = 0; i < demux->generic_sound_essence_descriptor->len; i++)
326 mxf_metadata_generic_sound_essence_descriptor_reset (&g_array_index
327 (demux->generic_sound_essence_descriptor,
328 MXFMetadataGenericSoundEssenceDescriptor, i));
329 g_array_free (demux->generic_sound_essence_descriptor, TRUE);
330 demux->generic_sound_essence_descriptor = NULL;
333 if (demux->wave_audio_essence_descriptor) {
334 for (i = 0; i < demux->wave_audio_essence_descriptor->len; i++)
335 mxf_metadata_wave_audio_essence_descriptor_reset (&g_array_index
336 (demux->wave_audio_essence_descriptor,
337 MXFMetadataWaveAudioEssenceDescriptor, i));
338 g_array_free (demux->wave_audio_essence_descriptor, TRUE);
339 demux->wave_audio_essence_descriptor = NULL;
342 if (demux->descriptor) {
343 g_ptr_array_free (demux->descriptor, TRUE);
344 demux->descriptor = NULL;
347 if (demux->locator) {
348 for (i = 0; i < demux->locator->len; i++)
349 mxf_metadata_locator_reset (&g_array_index (demux->locator,
350 MXFMetadataLocator, i));
351 g_array_free (demux->locator, TRUE);
352 demux->locator = NULL;
357 gst_mxf_demux_reset (GstMXFDemux * demux)
359 GST_DEBUG_OBJECT (demux, "cleaning up MXF demuxer");
361 demux->flushing = FALSE;
363 demux->header_partition_pack_offset = 0;
364 demux->footer_partition_pack_offset = 0;
367 demux->pull_footer_metadata = TRUE;
371 memset (&demux->current_package_uid, 0, sizeof (MXFUMID));
373 if (demux->new_seg_event) {
374 gst_event_unref (demux->new_seg_event);
375 demux->new_seg_event = NULL;
378 if (demux->close_seg_event) {
379 gst_event_unref (demux->close_seg_event);
380 demux->close_seg_event = NULL;
383 gst_adapter_clear (demux->adapter);
386 g_ptr_array_foreach (demux->src, (GFunc) gst_mxf_demux_remove_pad, demux);
387 g_ptr_array_foreach (demux->src, (GFunc) gst_object_unref, NULL);
388 g_ptr_array_free (demux->src, TRUE);
392 gst_mxf_demux_reset_mxf_state (demux);
393 gst_mxf_demux_reset_metadata (demux);
397 gst_mxf_demux_combine_flows (GstMXFDemux * demux,
398 GstMXFPad * pad, GstFlowReturn ret)
402 /* store the value */
403 pad->last_flow = ret;
405 /* any other error that is not-linked can be returned right away */
406 if (ret != GST_FLOW_NOT_LINKED)
409 /* only return NOT_LINKED if all other pads returned NOT_LINKED */
410 g_assert (demux->src->len != 0);
411 for (i = 0; i < demux->src->len; i++) {
412 GstMXFPad *opad = g_ptr_array_index (demux->src, i);
417 ret = opad->last_flow;
418 /* some other return value (must be SUCCESS but we can return
419 * other values as well) */
420 if (ret != GST_FLOW_NOT_LINKED)
423 /* if we get here, all other pads were unlinked and we return
426 GST_LOG_OBJECT (demux, "combined return %s", gst_flow_get_name (ret));
431 gst_mxf_demux_pull_range (GstMXFDemux * demux, guint64 offset,
432 guint size, GstBuffer ** buffer)
436 ret = gst_pad_pull_range (demux->sinkpad, offset, size, buffer);
437 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
438 GST_WARNING_OBJECT (demux,
439 "failed when pulling %u bytes from offset %" G_GUINT64_FORMAT ": %s",
440 size, offset, gst_flow_get_name (ret));
445 if (G_UNLIKELY (*buffer && GST_BUFFER_SIZE (*buffer) != size)) {
446 GST_WARNING_OBJECT (demux,
447 "partial pull got %u when expecting %u from offset %" G_GUINT64_FORMAT,
448 GST_BUFFER_SIZE (*buffer), size, offset);
449 gst_buffer_unref (*buffer);
450 ret = GST_FLOW_UNEXPECTED;
459 gst_mxf_demux_push_src_event (GstMXFDemux * demux, GstEvent * event)
464 GST_DEBUG_OBJECT (demux, "Pushing '%s' event downstream",
465 GST_EVENT_TYPE_NAME (event));
470 for (i = 0; i < demux->src->len; i++) {
471 GstPad *pad = GST_PAD (g_ptr_array_index (demux->src, i));
473 ret |= gst_pad_push_event (pad, gst_event_ref (event));
476 gst_event_unref (event);
482 gst_mxf_demux_handle_partition_pack (GstMXFDemux * demux, const MXFUL * key,
485 if (demux->partition.valid) {
486 mxf_partition_pack_reset (&demux->partition);
487 mxf_primer_pack_reset (&demux->primer);
490 GST_DEBUG_OBJECT (demux,
491 "Handling partition pack of size %u at offset %"
492 G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
494 if (!mxf_partition_pack_parse (key, &demux->partition,
495 GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
496 GST_ERROR_OBJECT (demux, "Parsing partition pack failed");
497 return GST_FLOW_ERROR;
500 if (demux->partition.type == MXF_PARTITION_PACK_HEADER)
501 demux->footer_partition_pack_offset = demux->partition.footer_partition;
507 gst_mxf_demux_handle_primer_pack (GstMXFDemux * demux, const MXFUL * key,
510 GST_DEBUG_OBJECT (demux,
511 "Handling primer pack of size %u at offset %"
512 G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
514 if (G_UNLIKELY (!demux->partition.valid)) {
515 GST_ERROR_OBJECT (demux, "Primer pack before partition pack");
516 return GST_FLOW_ERROR;
519 if (G_UNLIKELY (demux->primer.valid)) {
520 GST_ERROR_OBJECT (demux, "Primer pack already exists");
521 return GST_FLOW_ERROR;
524 if (!mxf_primer_pack_parse (key, &demux->primer,
525 GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
526 GST_ERROR_OBJECT (demux, "Parsing primer pack failed");
527 return GST_FLOW_ERROR;
534 gst_mxf_demux_handle_metadata_preface (GstMXFDemux * demux,
535 const MXFUL * key, GstBuffer * buffer)
537 MXFMetadataPreface preface;
539 GST_DEBUG_OBJECT (demux,
540 "Handling metadata preface of size %u"
541 " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
543 if (demux->final_metadata) {
544 GST_DEBUG_OBJECT (demux, "Metadata is already final, skipping");
548 if (!mxf_metadata_preface_parse (key, &preface, &demux->primer,
549 GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
550 GST_ERROR_OBJECT (demux, "Parsing metadata preface failed");
551 return GST_FLOW_ERROR;
554 if (mxf_timestamp_is_unknown (&demux->preface.last_modified_date)
555 || (!mxf_timestamp_is_unknown (&preface.last_modified_date)
556 && mxf_timestamp_compare (&demux->preface.last_modified_date,
557 &preface.last_modified_date) < 0)) {
558 GST_DEBUG_OBJECT (demux,
559 "Timestamp of new preface is newer than old, updating metadata");
560 gst_mxf_demux_reset_metadata (demux);
561 memcpy (&demux->preface, &preface, sizeof (MXFMetadataPreface));
568 gst_mxf_demux_handle_metadata_identification (GstMXFDemux * demux,
569 const MXFUL * key, GstBuffer * buffer)
571 MXFMetadataIdentification identification;
573 GST_DEBUG_OBJECT (demux,
574 "Handling metadata identification of size %u"
575 " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
577 if (!mxf_metadata_identification_parse (key, &identification,
578 &demux->primer, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
579 GST_ERROR_OBJECT (demux, "Parsing metadata identification failed");
580 return GST_FLOW_ERROR;
583 if (!demux->identification)
584 demux->identification =
585 g_array_new (FALSE, FALSE, sizeof (MXFMetadataIdentification));
587 g_array_append_val (demux->identification, identification);
593 gst_mxf_demux_handle_metadata_content_storage (GstMXFDemux * demux,
594 const MXFUL * key, GstBuffer * buffer)
596 GST_DEBUG_OBJECT (demux,
597 "Handling metadata content storage of size %u"
598 " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
600 if (!mxf_metadata_content_storage_parse (key,
601 &demux->content_storage, &demux->primer, GST_BUFFER_DATA (buffer),
602 GST_BUFFER_SIZE (buffer))) {
603 GST_ERROR_OBJECT (demux, "Parsing metadata content storage failed");
604 return GST_FLOW_ERROR;
611 gst_mxf_demux_handle_metadata_essence_container_data (GstMXFDemux *
612 demux, const MXFUL * key, GstBuffer * buffer)
614 MXFMetadataEssenceContainerData essence_container_data;
616 GST_DEBUG_OBJECT (demux,
617 "Handling metadata essence container data of size %u"
618 " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
620 if (!mxf_metadata_essence_container_data_parse (key,
621 &essence_container_data, &demux->primer, GST_BUFFER_DATA (buffer),
622 GST_BUFFER_SIZE (buffer))) {
623 GST_ERROR_OBJECT (demux, "Parsing metadata essence container data failed");
624 return GST_FLOW_ERROR;
627 if (!demux->essence_container_data)
628 demux->essence_container_data =
629 g_array_new (FALSE, FALSE, sizeof (MXFMetadataEssenceContainerData));
631 g_array_append_val (demux->essence_container_data, essence_container_data);
637 gst_mxf_demux_handle_metadata_material_package (GstMXFDemux * demux,
638 const MXFUL * key, GstBuffer * buffer)
640 MXFMetadataGenericPackage material_package;
642 GST_DEBUG_OBJECT (demux,
643 "Handling metadata material package of size %u"
644 " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
646 if (!mxf_metadata_generic_package_parse (key, &material_package,
647 &demux->primer, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
648 GST_ERROR_OBJECT (demux, "Parsing metadata material package failed");
649 return GST_FLOW_ERROR;
652 if (!demux->material_package)
653 demux->material_package =
654 g_array_new (FALSE, FALSE, sizeof (MXFMetadataMaterialPackage));
656 g_array_append_val (demux->material_package, material_package);
662 gst_mxf_demux_handle_metadata_source_package (GstMXFDemux * demux,
663 const MXFUL * key, GstBuffer * buffer)
665 MXFMetadataGenericPackage source_package;
667 GST_DEBUG_OBJECT (demux,
668 "Handling metadata source package of size %u"
669 " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
671 if (!mxf_metadata_generic_package_parse (key, &source_package,
672 &demux->primer, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
673 GST_ERROR_OBJECT (demux, "Parsing metadata source package failed");
674 return GST_FLOW_ERROR;
677 if (!demux->source_package)
678 demux->source_package =
679 g_array_new (FALSE, FALSE, sizeof (MXFMetadataSourcePackage));
681 g_array_append_val (demux->source_package, source_package);
687 gst_mxf_demux_handle_metadata_track (GstMXFDemux * demux,
688 const MXFUL * key, GstBuffer * buffer)
690 MXFMetadataTrack track;
692 GST_DEBUG_OBJECT (demux,
693 "Handling metadata track of size %u"
694 " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
696 if (!mxf_metadata_track_parse (key, &track, &demux->primer,
697 GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
698 GST_ERROR_OBJECT (demux, "Parsing metadata track timecode failed");
699 return GST_FLOW_ERROR;
703 demux->track = g_array_new (FALSE, FALSE, sizeof (MXFMetadataTrack));
705 g_array_append_val (demux->track, track);
711 gst_mxf_demux_handle_metadata_sequence (GstMXFDemux * demux,
712 const MXFUL * key, GstBuffer * buffer)
714 MXFMetadataSequence sequence;
716 GST_DEBUG_OBJECT (demux,
717 "Handling metadata sequence of size %u"
718 " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
720 if (!mxf_metadata_sequence_parse (key, &sequence,
721 &demux->primer, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
722 GST_ERROR_OBJECT (demux, "Parsing metadata sequence failed");
723 return GST_FLOW_ERROR;
726 if (!demux->sequence)
727 demux->sequence = g_array_new (FALSE, FALSE, sizeof (MXFMetadataSequence));
729 g_array_append_val (demux->sequence, sequence);
735 gst_mxf_demux_handle_metadata_structural_component (GstMXFDemux * demux,
736 const MXFUL * key, guint16 type, GstBuffer * buffer)
738 MXFMetadataStructuralComponent component;
740 GST_DEBUG_OBJECT (demux,
741 "Handling metadata structural component of size %u"
742 " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
744 if (!mxf_metadata_structural_component_parse (key, &component,
745 &demux->primer, type, GST_BUFFER_DATA (buffer),
746 GST_BUFFER_SIZE (buffer))) {
747 GST_ERROR_OBJECT (demux, "Parsing metadata structural component failed");
748 return GST_FLOW_ERROR;
751 if (!demux->structural_component)
752 demux->structural_component =
753 g_array_new (FALSE, FALSE, sizeof (MXFMetadataStructuralComponent));
755 g_array_append_val (demux->structural_component, component);
761 gst_mxf_demux_handle_metadata_generic_descriptor (GstMXFDemux * demux,
762 const MXFUL * key, guint16 type, GstBuffer * buffer)
764 MXFMetadataGenericDescriptor descriptor;
766 memset (&descriptor, 0, sizeof (descriptor));
768 GST_DEBUG_OBJECT (demux,
769 "Handling metadata generic descriptor of size %u"
770 " at offset %" G_GUINT64_FORMAT " with type 0x%04d",
771 GST_BUFFER_SIZE (buffer), demux->offset, type);
773 if (!mxf_metadata_descriptor_parse (key,
774 (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer,
775 type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer),
776 (MXFMetadataDescriptorHandleTag)
777 mxf_metadata_generic_descriptor_handle_tag,
778 (MXFMetadataDescriptorReset) mxf_metadata_generic_descriptor_reset)) {
779 GST_ERROR_OBJECT (demux, "Parsing metadata generic descriptor failed");
780 return GST_FLOW_ERROR;
783 if (!demux->generic_descriptor)
784 demux->generic_descriptor =
785 g_array_new (FALSE, FALSE, sizeof (MXFMetadataGenericDescriptor));
787 g_array_append_val (demux->generic_descriptor, descriptor);
793 gst_mxf_demux_handle_metadata_file_descriptor (GstMXFDemux * demux,
794 const MXFUL * key, guint16 type, GstBuffer * buffer)
796 MXFMetadataFileDescriptor descriptor;
798 memset (&descriptor, 0, sizeof (descriptor));
800 GST_DEBUG_OBJECT (demux,
801 "Handling metadata file descriptor of size %u"
802 " at offset %" G_GUINT64_FORMAT " with type 0x%04d",
803 GST_BUFFER_SIZE (buffer), demux->offset, type);
805 if (!mxf_metadata_descriptor_parse (key,
806 (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer,
807 type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer),
808 (MXFMetadataDescriptorHandleTag)
809 mxf_metadata_file_descriptor_handle_tag,
810 (MXFMetadataDescriptorReset) mxf_metadata_file_descriptor_reset)) {
811 GST_ERROR_OBJECT (demux, "Parsing metadata file descriptor failed");
812 return GST_FLOW_ERROR;
815 if (!demux->file_descriptor)
816 demux->file_descriptor =
817 g_array_new (FALSE, FALSE, sizeof (MXFMetadataFileDescriptor));
819 g_array_append_val (demux->file_descriptor, descriptor);
825 gst_mxf_demux_handle_metadata_multiple_descriptor (GstMXFDemux * demux,
826 const MXFUL * key, guint16 type, GstBuffer * buffer)
828 MXFMetadataMultipleDescriptor descriptor;
830 memset (&descriptor, 0, sizeof (descriptor));
832 GST_DEBUG_OBJECT (demux,
833 "Handling metadata multiple descriptor of size %u"
834 " at offset %" G_GUINT64_FORMAT " with type 0x%04d",
835 GST_BUFFER_SIZE (buffer), demux->offset, type);
837 if (!mxf_metadata_descriptor_parse (key,
838 (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer,
839 type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer),
840 (MXFMetadataDescriptorHandleTag)
841 mxf_metadata_multiple_descriptor_handle_tag,
842 (MXFMetadataDescriptorReset) mxf_metadata_multiple_descriptor_reset))
844 GST_ERROR_OBJECT (demux, "Parsing metadata multiple descriptor failed");
845 return GST_FLOW_ERROR;
848 if (!demux->multiple_descriptor)
849 demux->multiple_descriptor =
850 g_array_new (FALSE, FALSE, sizeof (MXFMetadataMultipleDescriptor));
852 g_array_append_val (demux->multiple_descriptor, descriptor);
858 gst_mxf_demux_handle_metadata_generic_picture_essence_descriptor (GstMXFDemux *
859 demux, const MXFUL * key, guint16 type, GstBuffer * buffer)
861 MXFMetadataGenericPictureEssenceDescriptor descriptor;
863 memset (&descriptor, 0, sizeof (descriptor));
865 GST_DEBUG_OBJECT (demux,
866 "Handling metadata generic picture essence descriptor of size %u"
867 " at offset %" G_GUINT64_FORMAT " with type 0x%04d",
868 GST_BUFFER_SIZE (buffer), demux->offset, type);
870 if (!mxf_metadata_descriptor_parse (key,
871 (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer,
872 type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer),
873 (MXFMetadataDescriptorHandleTag)
874 mxf_metadata_generic_picture_essence_descriptor_handle_tag,
875 (MXFMetadataDescriptorReset)
876 mxf_metadata_generic_picture_essence_descriptor_reset)) {
877 GST_ERROR_OBJECT (demux,
878 "Parsing metadata generic picture essence descriptor failed");
879 return GST_FLOW_ERROR;
882 if (!demux->generic_picture_essence_descriptor)
883 demux->generic_picture_essence_descriptor =
884 g_array_new (FALSE, FALSE,
885 sizeof (MXFMetadataGenericPictureEssenceDescriptor));
887 g_array_append_val (demux->generic_picture_essence_descriptor, descriptor);
893 gst_mxf_demux_handle_metadata_cdci_picture_essence_descriptor (GstMXFDemux *
894 demux, const MXFUL * key, guint16 type, GstBuffer * buffer)
896 MXFMetadataCDCIPictureEssenceDescriptor descriptor;
898 memset (&descriptor, 0, sizeof (descriptor));
900 GST_DEBUG_OBJECT (demux,
901 "Handling metadata CDCI picture essence descriptor of size %u"
902 " at offset %" G_GUINT64_FORMAT " with type 0x%04d",
903 GST_BUFFER_SIZE (buffer), demux->offset, type);
905 if (!mxf_metadata_descriptor_parse (key,
906 (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer,
907 type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer),
908 (MXFMetadataDescriptorHandleTag)
909 mxf_metadata_cdci_picture_essence_descriptor_handle_tag,
910 (MXFMetadataDescriptorReset)
911 mxf_metadata_cdci_picture_essence_descriptor_reset)) {
912 GST_ERROR_OBJECT (demux,
913 "Parsing metadata CDCI picture essence descriptor failed");
914 return GST_FLOW_ERROR;
917 if (!demux->cdci_picture_essence_descriptor)
918 demux->cdci_picture_essence_descriptor =
919 g_array_new (FALSE, FALSE,
920 sizeof (MXFMetadataCDCIPictureEssenceDescriptor));
922 g_array_append_val (demux->cdci_picture_essence_descriptor, descriptor);
928 gst_mxf_demux_handle_metadata_rgba_picture_essence_descriptor (GstMXFDemux *
929 demux, const MXFUL * key, guint16 type, GstBuffer * buffer)
931 MXFMetadataRGBAPictureEssenceDescriptor descriptor;
933 memset (&descriptor, 0, sizeof (descriptor));
935 GST_DEBUG_OBJECT (demux,
936 "Handling metadata RGBA picture essence descriptor of size %u"
937 " at offset %" G_GUINT64_FORMAT " with type 0x%04d",
938 GST_BUFFER_SIZE (buffer), demux->offset, type);
940 if (!mxf_metadata_descriptor_parse (key,
941 (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer,
942 type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer),
943 (MXFMetadataDescriptorHandleTag)
944 mxf_metadata_rgba_picture_essence_descriptor_handle_tag,
945 (MXFMetadataDescriptorReset)
946 mxf_metadata_rgba_picture_essence_descriptor_reset)) {
947 GST_ERROR_OBJECT (demux,
948 "Parsing metadata RGBA picture essence descriptor failed");
949 return GST_FLOW_ERROR;
952 if (!demux->rgba_picture_essence_descriptor)
953 demux->rgba_picture_essence_descriptor =
954 g_array_new (FALSE, FALSE,
955 sizeof (MXFMetadataRGBAPictureEssenceDescriptor));
957 g_array_append_val (demux->rgba_picture_essence_descriptor, descriptor);
963 gst_mxf_demux_handle_metadata_mpeg_video_descriptor (GstMXFDemux * demux,
964 const MXFUL * key, guint16 type, GstBuffer * buffer)
966 MXFMetadataMPEGVideoDescriptor descriptor;
968 memset (&descriptor, 0, sizeof (descriptor));
970 GST_DEBUG_OBJECT (demux,
971 "Handling metadata MPEG video descriptor of size %u"
972 " at offset %" G_GUINT64_FORMAT " with type 0x%04d",
973 GST_BUFFER_SIZE (buffer), demux->offset, type);
975 if (!mxf_metadata_descriptor_parse (key,
976 (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer,
977 type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer),
978 (MXFMetadataDescriptorHandleTag)
979 mxf_metadata_mpeg_video_descriptor_handle_tag,
980 (MXFMetadataDescriptorReset)
981 mxf_metadata_mpeg_video_descriptor_reset)) {
982 GST_ERROR_OBJECT (demux, "Parsing metadata MPEG video descriptor failed");
983 return GST_FLOW_ERROR;
986 if (!demux->mpeg_video_descriptor)
987 demux->mpeg_video_descriptor =
988 g_array_new (FALSE, FALSE, sizeof (MXFMetadataMPEGVideoDescriptor));
990 g_array_append_val (demux->mpeg_video_descriptor, descriptor);
996 gst_mxf_demux_handle_metadata_generic_sound_essence_descriptor (GstMXFDemux *
997 demux, const MXFUL * key, guint16 type, GstBuffer * buffer)
999 MXFMetadataGenericSoundEssenceDescriptor descriptor;
1001 memset (&descriptor, 0, sizeof (descriptor));
1003 GST_DEBUG_OBJECT (demux,
1004 "Handling metadata generic sound essence descriptor of size %u"
1005 " at offset %" G_GUINT64_FORMAT " with type 0x%04d",
1006 GST_BUFFER_SIZE (buffer), demux->offset, type);
1008 if (!mxf_metadata_descriptor_parse (key,
1009 (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer,
1010 type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer),
1011 (MXFMetadataDescriptorHandleTag)
1012 mxf_metadata_generic_sound_essence_descriptor_handle_tag,
1013 (MXFMetadataDescriptorReset)
1014 mxf_metadata_generic_sound_essence_descriptor_reset)) {
1015 GST_ERROR_OBJECT (demux,
1016 "Parsing metadata generic sound essence descriptor failed");
1017 return GST_FLOW_ERROR;
1020 if (!demux->generic_sound_essence_descriptor)
1021 demux->generic_sound_essence_descriptor =
1022 g_array_new (FALSE, FALSE,
1023 sizeof (MXFMetadataGenericSoundEssenceDescriptor));
1025 g_array_append_val (demux->generic_sound_essence_descriptor, descriptor);
1030 static GstFlowReturn
1031 gst_mxf_demux_handle_metadata_wave_audio_essence_descriptor (GstMXFDemux *
1032 demux, const MXFUL * key, guint16 type, GstBuffer * buffer)
1034 MXFMetadataWaveAudioEssenceDescriptor descriptor;
1036 memset (&descriptor, 0, sizeof (descriptor));
1038 GST_DEBUG_OBJECT (demux,
1039 "Handling metadata wave sound essence descriptor of size %u"
1040 " at offset %" G_GUINT64_FORMAT " with type 0x%04d",
1041 GST_BUFFER_SIZE (buffer), demux->offset, type);
1043 if (!mxf_metadata_descriptor_parse (key,
1044 (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer,
1045 type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer),
1046 (MXFMetadataDescriptorHandleTag)
1047 mxf_metadata_wave_audio_essence_descriptor_handle_tag,
1048 (MXFMetadataDescriptorReset)
1049 mxf_metadata_wave_audio_essence_descriptor_reset)) {
1050 GST_ERROR_OBJECT (demux,
1051 "Parsing metadata wave sound essence descriptor failed");
1052 return GST_FLOW_ERROR;
1055 if (!demux->wave_audio_essence_descriptor)
1056 demux->wave_audio_essence_descriptor =
1057 g_array_new (FALSE, FALSE,
1058 sizeof (MXFMetadataWaveAudioEssenceDescriptor));
1060 g_array_append_val (demux->wave_audio_essence_descriptor, descriptor);
1065 static GstFlowReturn
1066 gst_mxf_demux_handle_metadata_locator (GstMXFDemux * demux,
1067 const MXFUL * key, guint16 type, GstBuffer * buffer)
1069 MXFMetadataLocator locator;
1071 GST_DEBUG_OBJECT (demux,
1072 "Handling metadata locator of size %u"
1073 " at offset %" G_GUINT64_FORMAT " with type 0x%04d",
1074 GST_BUFFER_SIZE (buffer), demux->offset, type);
1076 if (!mxf_metadata_locator_parse (key, &locator, &demux->primer,
1077 type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
1078 GST_ERROR_OBJECT (demux, "Parsing metadata locator failed");
1079 return GST_FLOW_ERROR;
1082 if (!demux->locator)
1083 demux->locator = g_array_new (FALSE, FALSE, sizeof (MXFMetadataLocator));
1085 g_array_append_val (demux->locator, locator);
1090 static GstFlowReturn
1091 gst_mxf_demux_handle_header_metadata_resolve_references (GstMXFDemux * demux)
1094 GstFlowReturn ret = GST_FLOW_OK;
1096 GST_DEBUG_OBJECT (demux, "Resolve metadata references");
1097 demux->update_metadata = FALSE;
1098 if (demux->partition.closed && demux->partition.complete)
1099 demux->final_metadata = TRUE;
1101 /* Fill in demux->descriptor */
1102 demux->descriptor = g_ptr_array_new ();
1103 if (demux->generic_descriptor) {
1104 for (i = 0; i < demux->generic_descriptor->len; i++) {
1105 g_ptr_array_add (demux->descriptor,
1106 &g_array_index (demux->generic_descriptor,
1107 MXFMetadataGenericDescriptor, i));
1110 if (demux->file_descriptor) {
1111 for (i = 0; i < demux->file_descriptor->len; i++) {
1112 g_ptr_array_add (demux->descriptor,
1113 &g_array_index (demux->file_descriptor, MXFMetadataFileDescriptor,
1117 if (demux->generic_picture_essence_descriptor) {
1118 for (i = 0; i < demux->generic_picture_essence_descriptor->len; i++) {
1119 g_ptr_array_add (demux->descriptor,
1120 &g_array_index (demux->generic_picture_essence_descriptor,
1121 MXFMetadataGenericPictureEssenceDescriptor, i));
1124 if (demux->cdci_picture_essence_descriptor) {
1125 for (i = 0; i < demux->cdci_picture_essence_descriptor->len; i++) {
1126 g_ptr_array_add (demux->descriptor,
1127 &g_array_index (demux->cdci_picture_essence_descriptor,
1128 MXFMetadataCDCIPictureEssenceDescriptor, i));
1131 if (demux->rgba_picture_essence_descriptor) {
1132 for (i = 0; i < demux->rgba_picture_essence_descriptor->len; i++) {
1133 g_ptr_array_add (demux->descriptor,
1134 &g_array_index (demux->rgba_picture_essence_descriptor,
1135 MXFMetadataRGBAPictureEssenceDescriptor, i));
1138 if (demux->mpeg_video_descriptor) {
1139 for (i = 0; i < demux->mpeg_video_descriptor->len; i++) {
1140 g_ptr_array_add (demux->descriptor,
1141 &g_array_index (demux->mpeg_video_descriptor,
1142 MXFMetadataMPEGVideoDescriptor, i));
1145 if (demux->generic_sound_essence_descriptor) {
1146 for (i = 0; i < demux->generic_sound_essence_descriptor->len; i++) {
1147 g_ptr_array_add (demux->descriptor,
1148 &g_array_index (demux->generic_sound_essence_descriptor,
1149 MXFMetadataGenericSoundEssenceDescriptor, i));
1152 if (demux->wave_audio_essence_descriptor) {
1153 for (i = 0; i < demux->wave_audio_essence_descriptor->len; i++) {
1154 g_ptr_array_add (demux->descriptor,
1155 &g_array_index (demux->wave_audio_essence_descriptor,
1156 MXFMetadataWaveAudioEssenceDescriptor, i));
1159 if (demux->multiple_descriptor) {
1160 for (i = 0; i < demux->multiple_descriptor->len; i++) {
1161 g_ptr_array_add (demux->descriptor,
1162 &g_array_index (demux->multiple_descriptor,
1163 MXFMetadataMultipleDescriptor, i));
1167 /* Fill in demux->package */
1168 demux->package = g_ptr_array_new ();
1169 if (demux->material_package) {
1170 for (i = 0; i < demux->material_package->len; i++) {
1171 g_ptr_array_add (demux->package, &g_array_index (demux->material_package,
1172 MXFMetadataGenericPackage, i));
1175 if (demux->source_package) {
1176 for (i = 0; i < demux->source_package->len; i++) {
1177 g_ptr_array_add (demux->package, &g_array_index (demux->source_package,
1178 MXFMetadataGenericPackage, i));
1182 /* Multiple descriptor */
1183 if (demux->multiple_descriptor && demux->descriptor) {
1184 for (i = 0; i < demux->multiple_descriptor->len; i++) {
1185 MXFMetadataMultipleDescriptor *d =
1186 &g_array_index (demux->multiple_descriptor,
1187 MXFMetadataMultipleDescriptor, i);
1189 d->sub_descriptors =
1190 g_new0 (MXFMetadataGenericDescriptor *, d->n_sub_descriptors);
1191 for (j = 0; j < d->n_sub_descriptors; j++) {
1192 for (k = 0; k < demux->descriptor->len; k++) {
1193 MXFMetadataGenericDescriptor *e =
1194 g_ptr_array_index (demux->descriptor, k);
1196 if (mxf_ul_is_equal (&d->sub_descriptors_uids[j], &e->instance_uid)) {
1197 d->sub_descriptors[j] = e;
1205 /* See SMPTE 377M 8.4 */
1208 if (demux->package) {
1209 for (i = 0; i < demux->package->len; i++) {
1210 MXFMetadataGenericPackage *package =
1211 g_ptr_array_index (demux->package, i);
1213 if (mxf_ul_is_equal (&demux->preface.primary_package_uid,
1214 &package->instance_uid)) {
1215 demux->preface.primary_package = package;
1221 demux->preface.identifications =
1222 g_new0 (MXFMetadataIdentification *, demux->preface.n_identifications);
1223 if (demux->identification) {
1224 for (i = 0; i < demux->identification->len; i++) {
1225 MXFMetadataIdentification *identification =
1226 &g_array_index (demux->identification,
1227 MXFMetadataIdentification, i);
1229 for (j = 0; j < demux->preface.n_identifications; j++) {
1230 if (mxf_ul_is_equal (&demux->preface.identifications_uids[j],
1231 &identification->instance_uid)) {
1232 demux->preface.identifications[j] = identification;
1239 if (!mxf_ul_is_equal (&demux->preface.content_storage_uid,
1240 &demux->content_storage.instance_uid)) {
1241 GST_ERROR_OBJECT (demux,
1242 "Preface content storage UID not equal to actual content storage instance uid");
1243 ret = GST_FLOW_ERROR;
1246 demux->preface.content_storage = &demux->content_storage;
1248 /* TODO: dm_schemes */
1250 /* Content storage */
1251 demux->content_storage.packages =
1252 g_new0 (MXFMetadataGenericPackage *, demux->content_storage.n_packages);
1253 if (demux->package) {
1254 for (i = 0; i < demux->package->len; i++) {
1255 MXFMetadataGenericPackage *package =
1256 g_ptr_array_index (demux->package, i);
1258 for (j = 0; j < demux->content_storage.n_packages; j++) {
1259 if (mxf_ul_is_equal (&demux->content_storage.packages_uids[j],
1260 &package->instance_uid)) {
1261 demux->content_storage.packages[j] = package;
1268 demux->content_storage.essence_container_data =
1269 g_new0 (MXFMetadataEssenceContainerData *,
1270 demux->content_storage.n_essence_container_data);
1271 if (demux->essence_container_data) {
1272 for (i = 0; i < demux->essence_container_data->len; i++) {
1273 MXFMetadataEssenceContainerData *data =
1274 &g_array_index (demux->essence_container_data,
1275 MXFMetadataEssenceContainerData, i);
1277 for (j = 0; j < demux->content_storage.n_essence_container_data; j++) {
1278 if (mxf_ul_is_equal (&demux->content_storage.
1279 essence_container_data_uids[j], &data->instance_uid)) {
1280 demux->content_storage.essence_container_data[j] = data;
1287 /* Essence container data */
1288 if (demux->package && demux->essence_container_data) {
1289 for (i = 0; i < demux->package->len; i++) {
1290 MXFMetadataGenericPackage *package =
1291 g_ptr_array_index (demux->package, i);
1293 for (j = 0; j < demux->essence_container_data->len; j++) {
1294 MXFMetadataEssenceContainerData *data =
1295 &g_array_index (demux->essence_container_data,
1296 MXFMetadataEssenceContainerData, j);
1298 if (mxf_umid_is_equal (&data->linked_package_uid,
1299 &package->package_uid)) {
1300 data->linked_package = package;
1307 /* Generic package */
1308 if (demux->package) {
1309 for (i = 0; i < demux->package->len; i++) {
1310 MXFMetadataGenericPackage *package =
1311 g_ptr_array_index (demux->package, i);
1313 package->tracks = g_new0 (MXFMetadataTrack *, package->n_tracks);
1315 for (j = 0; j < package->n_tracks; j++) {
1316 for (k = 0; k < demux->track->len; k++) {
1317 MXFMetadataTrack *track =
1318 &g_array_index (demux->track, MXFMetadataTrack, k);
1320 if (mxf_ul_is_equal (&package->tracks_uids[j],
1321 &track->instance_uid)) {
1322 package->tracks[j] = track;
1329 /* Resolve descriptors */
1330 if (package->n_descriptors > 0 && demux->descriptor) {
1331 MXFMetadataGenericDescriptor *d = NULL;
1333 for (j = 0; j < demux->descriptor->len; j++) {
1334 MXFMetadataGenericDescriptor *descriptor =
1335 g_ptr_array_index (demux->descriptor, j);
1337 if (mxf_ul_is_equal (&package->descriptors_uid,
1338 &descriptor->instance_uid)) {
1344 if (d && d->type == MXF_METADATA_MULTIPLE_DESCRIPTOR) {
1345 MXFMetadataMultipleDescriptor *e =
1346 (MXFMetadataMultipleDescriptor *) d;
1348 package->n_descriptors = e->n_sub_descriptors;
1349 package->descriptors =
1350 g_new0 (MXFMetadataGenericDescriptor *, e->n_sub_descriptors);
1352 /* These are already resolved */
1353 for (j = 0; j < e->n_sub_descriptors; j++)
1354 package->descriptors[j] = e->sub_descriptors[j];
1356 package->n_descriptors = 1;
1357 package->descriptors = g_new0 (MXFMetadataGenericDescriptor *, 1);
1358 package->descriptors[0] = d;
1362 if (package->tracks && package->descriptors) {
1363 for (j = 0; j < package->n_tracks; j++) {
1364 MXFMetadataTrack *track = package->tracks[j];
1365 guint n_descriptor = 0;
1370 for (k = 0; k < package->n_descriptors; k++) {
1371 MXFMetadataGenericDescriptor *d = package->descriptors[k];
1372 MXFMetadataFileDescriptor *e;
1374 if (!d || !d->is_file_descriptor)
1377 e = (MXFMetadataFileDescriptor *) d;
1379 if (e->linked_track_id == track->track_id)
1383 track->n_descriptor = n_descriptor;
1385 g_new0 (MXFMetadataFileDescriptor *, n_descriptor);
1388 for (k = 0; k < package->n_descriptors; k++) {
1389 MXFMetadataGenericDescriptor *d = package->descriptors[k];
1390 MXFMetadataFileDescriptor *e;
1392 if (!d || !d->is_file_descriptor)
1395 e = (MXFMetadataFileDescriptor *) d;
1397 if (e->linked_track_id == track->track_id)
1398 track->descriptor[n_descriptor++] = e;
1406 if (demux->track && demux->sequence) {
1407 for (i = 0; i < demux->track->len; i++) {
1408 MXFMetadataTrack *track =
1409 &g_array_index (demux->track, MXFMetadataTrack, i);
1411 for (j = 0; j < demux->sequence->len; j++) {
1412 MXFMetadataSequence *sequence =
1413 &g_array_index (demux->sequence, MXFMetadataSequence,
1416 if (mxf_ul_is_equal (&track->sequence_uid, &sequence->instance_uid)) {
1417 track->sequence = sequence;
1425 if (demux->sequence) {
1426 for (i = 0; i < demux->sequence->len; i++) {
1427 MXFMetadataSequence *sequence =
1428 &g_array_index (demux->sequence, MXFMetadataSequence, i);
1430 sequence->structural_components =
1431 g_new0 (MXFMetadataStructuralComponent *,
1432 sequence->n_structural_components);
1434 if (demux->structural_component) {
1435 for (j = 0; j < sequence->n_structural_components; j++) {
1436 for (k = 0; k < demux->structural_component->len; k++) {
1437 MXFMetadataStructuralComponent *component =
1438 &g_array_index (demux->structural_component,
1439 MXFMetadataStructuralComponent, k);
1441 if (mxf_ul_is_equal (&sequence->structural_components_uids[j],
1442 &component->instance_uid)) {
1443 sequence->structural_components[j] = component;
1453 if (demux->structural_component && demux->source_package) {
1454 for (i = 0; i < demux->structural_component->len; i++) {
1455 MXFMetadataStructuralComponent *component =
1456 &g_array_index (demux->structural_component,
1457 MXFMetadataStructuralComponent, i);
1459 if (component->type != MXF_METADATA_SOURCE_CLIP)
1462 for (j = 0; j < demux->source_package->len; j++) {
1463 MXFMetadataGenericPackage *package =
1464 &g_array_index (demux->source_package, MXFMetadataGenericPackage,
1467 if (mxf_umid_is_equal (&component->source_clip.source_package_id,
1468 &package->package_uid)) {
1469 component->source_clip.source_package = package;
1476 /* Generic descriptors */
1477 if (demux->descriptor) {
1478 for (i = 0; i < demux->descriptor->len; i++) {
1479 MXFMetadataGenericDescriptor *descriptor =
1480 g_ptr_array_index (demux->descriptor, i);
1482 descriptor->locators =
1483 g_new0 (MXFMetadataLocator *, descriptor->n_locators);
1485 if (demux->locator) {
1486 for (j = 0; j < descriptor->n_locators; j++) {
1487 for (k = 0; k < demux->locator->len; k++) {
1488 MXFMetadataLocator *locator =
1489 &g_array_index (demux->locator, MXFMetadataLocator,
1492 if (mxf_ul_is_equal (&descriptor->locators_uids[j],
1493 &locator->instance_uid)) {
1494 descriptor->locators[j] = locator;
1503 /* Mark packages as material, top-level source and source */
1504 if (demux->material_package) {
1505 for (i = 0; i < demux->material_package->len; i++) {
1506 MXFMetadataGenericPackage *package =
1507 &g_array_index (demux->material_package, MXFMetadataGenericPackage,
1510 package->type = MXF_METADATA_GENERIC_PACKAGE_MATERIAL;
1512 for (j = 0; j < package->n_tracks; j++) {
1513 MXFMetadataTrack *track = package->tracks[j];
1514 MXFMetadataSequence *sequence;
1516 if (!track || !track->sequence)
1519 sequence = track->sequence;
1521 for (k = 0; k < sequence->n_structural_components; k++) {
1522 MXFMetadataStructuralComponent *component =
1523 sequence->structural_components[k];
1525 if (!component || component->type != MXF_METADATA_SOURCE_CLIP
1526 || !component->source_clip.source_package)
1529 component->source_clip.source_package->type =
1530 MXF_METADATA_GENERIC_PACKAGE_TOP_LEVEL_SOURCE;
1536 /* Store, for every package, the number of timestamp, metadata, essence and other tracks */
1537 if (demux->package) {
1538 for (i = 0; i < demux->package->len; i++) {
1539 MXFMetadataGenericPackage *package =
1540 g_ptr_array_index (demux->package, i);
1542 if (!package->tracks || package->n_tracks == 0)
1545 for (j = 0; j < package->n_tracks; j++) {
1546 MXFMetadataTrack *track = package->tracks[j];
1547 MXFMetadataSequence *sequence;
1548 MXFMetadataTrackType type = MXF_METADATA_TRACK_UNKNOWN;
1550 if (!track || !track->sequence)
1553 sequence = track->sequence;
1555 if (mxf_ul_is_zero (&sequence->data_definition)
1556 && sequence->structural_components) {
1557 for (k = 0; k < sequence->n_structural_components; k++) {
1558 MXFMetadataStructuralComponent *component =
1559 sequence->structural_components[k];
1560 if (!component || mxf_ul_is_zero (&component->data_definition))
1564 mxf_metadata_track_identifier_parse
1565 (&component->data_definition);
1570 mxf_metadata_track_identifier_parse (&sequence->data_definition);
1573 if (type == MXF_METADATA_TRACK_UNKNOWN)
1575 else if ((type & 0xf0) == 0x10)
1576 package->n_timecode_tracks++;
1577 else if ((type & 0xf0) == 0x20)
1578 package->n_metadata_tracks++;
1579 else if ((type & 0xf0) == 0x30)
1580 package->n_essence_tracks++;
1581 else if ((type & 0xf0) == 0x40)
1582 package->n_other_tracks++;
1593 static GstFlowReturn
1594 gst_mxf_demux_handle_header_metadata_update_streams (GstMXFDemux * demux)
1596 MXFMetadataGenericPackage *current_package = NULL;
1600 GST_DEBUG_OBJECT (demux, "Updating streams");
1603 /* If no package was selected, select the first material package */
1604 if (mxf_umid_is_zero (&demux->current_package_uid)
1605 && !demux->material_package) {
1606 GST_ERROR_OBJECT (demux, "No material package");
1607 return GST_FLOW_ERROR;
1608 } else if (mxf_umid_is_zero (&demux->current_package_uid)) {
1609 MXFMetadataGenericPackage *p =
1610 (MXFMetadataGenericPackage *) demux->material_package->data;
1611 memcpy (&demux->current_package_uid, &p->package_uid, 32);
1612 current_package = p;
1614 for (i = 0; i < demux->src->len; i++) {
1615 GstMXFPad *pad = g_ptr_array_index (demux->src, i);
1616 gst_element_remove_pad (GST_ELEMENT_CAST (demux), GST_PAD_CAST (pad));
1617 gst_object_unref (pad);
1619 g_ptr_array_free (demux->src, TRUE);
1624 if (!current_package && demux->package) {
1625 for (i = 0; i < demux->package->len; i++) {
1626 MXFMetadataGenericPackage *p = g_ptr_array_index (demux->package, i);
1628 if (mxf_umid_is_equal (&p->package_uid, &demux->current_package_uid)) {
1629 current_package = p;
1635 if (!current_package) {
1636 GST_WARNING_OBJECT (demux,
1637 "Selected package not found in header metadata, choosing the first best");
1638 memset (&demux->current_package_uid, 0, sizeof (MXFUMID));
1639 goto choose_package;
1642 if (current_package->type == MXF_METADATA_GENERIC_PACKAGE_SOURCE) {
1643 GST_WARNING_OBJECT (demux,
1644 "Selected package is not a material package or top-level source package, choosing the first best");
1645 memset (&demux->current_package_uid, 0, sizeof (MXFUMID));
1646 goto choose_package;
1649 if (!current_package->tracks) {
1650 GST_ERROR_OBJECT (demux, "Current package has no (resolved) tracks");
1651 return GST_FLOW_ERROR;
1652 } else if (!current_package->n_essence_tracks) {
1653 GST_ERROR_OBJECT (demux, "Current package has no essence tracks");
1654 return GST_FLOW_ERROR;
1657 first_run = (demux->src == NULL);
1658 demux->current_package = current_package;
1660 for (i = 0; i < current_package->n_tracks; i++) {
1661 MXFMetadataTrack *track = current_package->tracks[i];
1662 MXFMetadataTrackType track_type = MXF_METADATA_TRACK_UNKNOWN;
1663 MXFMetadataSequence *sequence;
1664 MXFMetadataStructuralComponent *component = NULL;
1665 MXFMetadataGenericPackage *source_package = NULL;
1666 MXFMetadataTrack *source_track = NULL;
1667 GstMXFPad *pad = NULL;
1668 GstCaps *caps = NULL;
1670 GST_DEBUG_OBJECT (demux, "Handling track %u", i);
1673 GST_WARNING_OBJECT (demux, "Unresolved track");
1675 } else if (!track->sequence) {
1676 GST_WARNING_OBJECT (demux, "Track with no sequence");
1680 sequence = track->sequence;
1682 if (current_package->type == MXF_METADATA_GENERIC_PACKAGE_TOP_LEVEL_SOURCE) {
1683 source_package = current_package;
1684 source_track = track;
1688 mxf_metadata_track_identifier_parse (&sequence->data_definition);
1690 /* TODO: handle multiple components, see SMPTE 377M page 37 */
1691 if (sequence->structural_components && sequence->structural_components[0]) {
1692 component = sequence->structural_components[0];
1694 if (track_type == MXF_METADATA_TRACK_UNKNOWN)
1696 mxf_metadata_track_identifier_parse (&component->data_definition);
1698 if (!source_package && component->type == MXF_METADATA_SOURCE_CLIP
1699 && component->source_clip.source_package
1700 && component->source_clip.source_package->type ==
1701 MXF_METADATA_GENERIC_PACKAGE_TOP_LEVEL_SOURCE
1702 && component->source_clip.source_package->tracks) {
1703 source_package = component->source_clip.source_package;
1705 for (k = 0; k < source_package->n_tracks; k++) {
1706 MXFMetadataTrack *tmp = source_package->tracks[k];
1708 if (tmp->track_id == component->source_clip.source_track_id) {
1716 if (track_type && (track_type & 0xf0) != 0x30) {
1717 GST_DEBUG_OBJECT (demux, "No essence track");
1721 if (!source_package || track_type == MXF_METADATA_TRACK_UNKNOWN
1722 || !source_track || !component) {
1723 GST_WARNING_OBJECT (demux,
1724 "No source package or track type for track found");
1728 if (!source_package->descriptors) {
1729 GST_WARNING_OBJECT (demux, "Source package has no descriptors");
1733 if (!source_track->descriptor) {
1734 GST_WARNING_OBJECT (demux, "No descriptor found for track");
1738 if (demux->src && demux->src->len > 0) {
1739 /* Find pad from track_id */
1740 for (j = 0; j < demux->src->len; j++) {
1741 GstMXFPad *tmp = g_ptr_array_index (demux->src, j);
1743 if (tmp->track_id == track->track_id) {
1750 if (!pad && first_run) {
1751 GstPadTemplate *templ;
1754 switch (track_type) {
1755 case MXF_METADATA_TRACK_PICTURE_ESSENCE:
1757 gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (demux),
1759 pad_name = g_strdup_printf ("video_%u", source_track->track_id);
1761 case MXF_METADATA_TRACK_SOUND_ESSENCE:
1763 gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (demux),
1765 pad_name = g_strdup_printf ("audio_%u", source_track->track_id);
1767 case MXF_METADATA_TRACK_DATA_ESSENCE:
1769 gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (demux),
1771 pad_name = g_strdup_printf ("data_%u", source_track->track_id);
1774 g_assert_not_reached ();
1778 g_assert (templ != NULL);
1781 pad = (GstMXFPad *) g_object_new (GST_TYPE_MXF_PAD,
1782 "name", pad_name, "direction", GST_PAD_SRC, "template", templ, NULL);
1783 pad->need_segment = TRUE;
1788 GST_WARNING_OBJECT (demux,
1789 "Not the first pad addition run, ignoring new track");
1794 pad->track_id = track->track_id;
1795 pad->track_type = track_type;
1797 pad->material_package = current_package;
1798 pad->material_track = track;
1799 pad->current_material_component = 0;
1800 pad->component = component;
1802 pad->source_package = source_package;
1803 pad->source_track = source_track;
1805 pad->handle_essence_element = NULL;
1806 g_free (pad->mapping_data);
1807 pad->mapping_data = NULL;
1809 switch (track_type) {
1810 case MXF_METADATA_TRACK_PICTURE_ESSENCE:
1811 if (mxf_is_mpeg_video_essence_track (source_track))
1813 mxf_mpeg_video_create_caps (source_package, source_track,
1814 &pad->tags, &pad->handle_essence_element, &pad->mapping_data);
1815 else if (mxf_is_dv_dif_essence_track (source_track))
1817 mxf_dv_dif_create_caps (source_package, source_track,
1818 &pad->tags, &pad->handle_essence_element, &pad->mapping_data);
1820 case MXF_METADATA_TRACK_SOUND_ESSENCE:
1821 if (mxf_is_aes_bwf_essence_track (source_track))
1823 mxf_aes_bwf_create_caps (source_package, source_track, &pad->tags,
1824 &pad->handle_essence_element, &pad->mapping_data);
1825 else if (mxf_is_dv_dif_essence_track (source_track))
1827 mxf_dv_dif_create_caps (source_package, source_track,
1828 &pad->tags, &pad->handle_essence_element, &pad->mapping_data);
1830 case MXF_METADATA_TRACK_DATA_ESSENCE:
1831 if (mxf_is_dv_dif_essence_track (source_track))
1833 mxf_dv_dif_create_caps (source_package, source_track,
1834 &pad->tags, &pad->handle_essence_element, &pad->mapping_data);
1837 g_assert_not_reached ();
1842 GST_WARNING_OBJECT (demux, "No caps created, ignoring stream");
1843 gst_object_unref (pad);
1847 GST_DEBUG_OBJECT (demux, "Created caps %" GST_PTR_FORMAT, caps);
1849 if (pad->caps && !gst_caps_is_equal (pad->caps, caps)) {
1850 gst_pad_set_caps (GST_PAD_CAST (pad), caps);
1851 gst_caps_replace (&pad->caps, gst_caps_ref (caps));
1852 } else if (!pad->caps) {
1853 gst_pad_set_caps (GST_PAD_CAST (pad), caps);
1854 pad->caps = gst_caps_ref (caps);
1856 gst_pad_set_event_function (GST_PAD_CAST (pad),
1857 GST_DEBUG_FUNCPTR (gst_mxf_demux_src_event));
1859 gst_pad_set_query_type_function (GST_PAD_CAST (pad),
1860 GST_DEBUG_FUNCPTR (gst_mxf_demux_src_query_type));
1861 gst_pad_set_query_function (GST_PAD_CAST (pad),
1862 GST_DEBUG_FUNCPTR (gst_mxf_demux_src_query));
1864 gst_pad_use_fixed_caps (GST_PAD_CAST (pad));
1865 gst_pad_set_active (GST_PAD_CAST (pad), TRUE);
1867 gst_element_add_pad (GST_ELEMENT_CAST (demux), gst_object_ref (pad));
1870 demux->src = g_ptr_array_new ();
1871 g_ptr_array_add (demux->src, pad);
1873 gst_caps_unref (caps);
1876 gst_element_no_more_pads (GST_ELEMENT_CAST (demux));
1881 static GstFlowReturn
1882 gst_mxf_demux_handle_metadata (GstMXFDemux * demux, const MXFUL * key,
1886 GstFlowReturn ret = GST_FLOW_OK;
1888 type = GST_READ_UINT16_BE (key->u + 13);
1890 GST_DEBUG_OBJECT (demux,
1891 "Handling metadata of size %u at offset %"
1892 G_GUINT64_FORMAT " of type 0x%04d", GST_BUFFER_SIZE (buffer),
1893 demux->offset, type);
1895 if (G_UNLIKELY (!demux->partition.valid)) {
1896 GST_ERROR_OBJECT (demux, "Partition pack doesn't exist");
1897 return GST_FLOW_ERROR;
1900 if (G_UNLIKELY (!demux->primer.valid)) {
1901 GST_ERROR_OBJECT (demux, "Primer pack doesn't exists");
1902 return GST_FLOW_ERROR;
1905 if (type != MXF_METADATA_PREFACE && !demux->update_metadata) {
1906 GST_DEBUG_OBJECT (demux,
1907 "Skipping parsing of metadata because it's older than what we have");
1912 case MXF_METADATA_PREFACE:
1913 ret = gst_mxf_demux_handle_metadata_preface (demux, key, buffer);
1915 case MXF_METADATA_IDENTIFICATION:
1916 ret = gst_mxf_demux_handle_metadata_identification (demux, key, buffer);
1918 case MXF_METADATA_CONTENT_STORAGE:
1919 ret = gst_mxf_demux_handle_metadata_content_storage (demux, key, buffer);
1921 case MXF_METADATA_ESSENCE_CONTAINER_DATA:
1923 gst_mxf_demux_handle_metadata_essence_container_data (demux,
1926 case MXF_METADATA_MATERIAL_PACKAGE:
1927 ret = gst_mxf_demux_handle_metadata_material_package (demux, key, buffer);
1929 case MXF_METADATA_SOURCE_PACKAGE:
1930 ret = gst_mxf_demux_handle_metadata_source_package (demux, key, buffer);
1932 case MXF_METADATA_TRACK:
1933 ret = gst_mxf_demux_handle_metadata_track (demux, key, buffer);
1935 case MXF_METADATA_SEQUENCE:
1936 ret = gst_mxf_demux_handle_metadata_sequence (demux, key, buffer);
1938 case MXF_METADATA_TIMECODE_COMPONENT:
1939 case MXF_METADATA_SOURCE_CLIP:
1941 gst_mxf_demux_handle_metadata_structural_component (demux,
1944 case MXF_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR:
1946 gst_mxf_demux_handle_metadata_generic_descriptor (demux,
1949 case MXF_METADATA_FILE_DESCRIPTOR:
1951 gst_mxf_demux_handle_metadata_file_descriptor (demux,
1954 case MXF_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR:
1956 gst_mxf_demux_handle_metadata_generic_picture_essence_descriptor
1957 (demux, key, type, buffer);
1959 case MXF_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR:
1961 gst_mxf_demux_handle_metadata_cdci_picture_essence_descriptor (demux,
1964 case MXF_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR:
1966 gst_mxf_demux_handle_metadata_rgba_picture_essence_descriptor (demux,
1969 case MXF_METADATA_MPEG_VIDEO_DESCRIPTOR:
1971 gst_mxf_demux_handle_metadata_mpeg_video_descriptor (demux,
1974 case MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR:
1976 gst_mxf_demux_handle_metadata_generic_sound_essence_descriptor (demux,
1979 case MXF_METADATA_MULTIPLE_DESCRIPTOR:
1981 gst_mxf_demux_handle_metadata_multiple_descriptor (demux,
1984 case MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR:
1986 gst_mxf_demux_handle_metadata_wave_audio_essence_descriptor (demux,
1989 case MXF_METADATA_NETWORK_LOCATOR:
1990 case MXF_METADATA_TEXT_LOCATOR:
1991 ret = gst_mxf_demux_handle_metadata_locator (demux, key, type, buffer);
1994 GST_WARNING_OBJECT (demux,
1995 "Unknown or unhandled metadata type 0x%04x", type);
2002 static GstFlowReturn
2003 gst_mxf_demux_handle_generic_container_system_item (GstMXFDemux * demux,
2004 const MXFUL * key, GstBuffer * buffer)
2006 GST_DEBUG_OBJECT (demux,
2007 "Handling generic container system item of size %u"
2008 " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
2010 /* TODO: parse this */
2014 static GstFlowReturn
2015 gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
2016 const MXFUL * key, GstBuffer * buffer)
2018 GstFlowReturn ret = GST_FLOW_OK;
2019 guint32 track_number;
2021 GstMXFPad *pad = NULL;
2023 GstBuffer *outbuf = NULL;
2025 GST_DEBUG_OBJECT (demux,
2026 "Handling generic container essence element of size %u"
2027 " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
2029 GST_DEBUG_OBJECT (demux, " type = 0x%02x", key->u[12]);
2030 GST_DEBUG_OBJECT (demux, " essence element count = 0x%02x", key->u[13]);
2031 GST_DEBUG_OBJECT (demux, " essence element type = 0x%02x", key->u[14]);
2032 GST_DEBUG_OBJECT (demux, " essence element number = 0x%02x", key->u[15]);
2034 if (!demux->current_package) {
2035 GST_ERROR_OBJECT (demux, "No package selected yet");
2036 return GST_FLOW_ERROR;
2039 if (!demux->src || demux->src->len == 0) {
2040 GST_ERROR_OBJECT (demux, "No streams created yet");
2041 return GST_FLOW_ERROR;
2044 track_number = GST_READ_UINT32_BE (&key->u[12]);
2046 for (i = 0; i < demux->src->len; i++) {
2047 GstMXFPad *p = g_ptr_array_index (demux->src, i);
2049 if (p->source_track->track_number == track_number ||
2050 (p->source_track->track_number == 0 &&
2051 demux->src->len == 1 &&
2052 demux->current_package->n_essence_tracks == 1)) {
2053 if (demux->essence_container_data) {
2054 for (j = 0; j < demux->essence_container_data->len; j++) {
2055 MXFMetadataEssenceContainerData *edata =
2056 &g_array_index (demux->essence_container_data,
2057 MXFMetadataEssenceContainerData, j);
2059 if (p->source_package == edata->linked_package
2060 && demux->partition.body_sid == edata->body_sid) {
2075 GST_WARNING_OBJECT (demux, "No corresponding pad found");
2079 /* TODO: Use a better start value */
2080 if (pad->need_segment) {
2081 gst_pad_push_event (GST_PAD_CAST (pad),
2082 gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1, 0));
2083 pad->need_segment = FALSE;
2086 /* Create subbuffer to be able to change metadata */
2087 inbuf = gst_buffer_create_sub (buffer, 0, GST_BUFFER_SIZE (buffer));
2089 GST_BUFFER_TIMESTAMP (inbuf) =
2090 gst_util_uint64_scale (pad->essence_element_count +
2091 pad->material_track->origin,
2092 GST_SECOND * pad->material_track->edit_rate.d,
2093 pad->material_track->edit_rate.n);
2094 GST_BUFFER_DURATION (inbuf) =
2095 gst_util_uint64_scale (GST_SECOND, pad->material_track->edit_rate.d,
2096 pad->material_track->edit_rate.n);
2097 GST_BUFFER_OFFSET (inbuf) = pad->essence_element_count;
2098 GST_BUFFER_OFFSET_END (inbuf) = GST_BUFFER_OFFSET_NONE;
2099 gst_buffer_set_caps (inbuf, pad->caps);
2101 if (pad->handle_essence_element) {
2102 /* Takes ownership of inbuf */
2104 pad->handle_essence_element (key, inbuf, pad->caps, pad->source_package,
2105 pad->source_track, pad->component, pad->mapping_data, &outbuf);
2113 pad->essence_element_count++;
2115 if (ret != GST_FLOW_OK) {
2116 GST_ERROR_OBJECT (demux, "Failed to handle essence element");
2118 gst_buffer_unref (outbuf);
2124 ret = gst_pad_push (GST_PAD_CAST (pad), outbuf);
2125 ret = gst_mxf_demux_combine_flows (demux, pad, ret);
2131 static GstFlowReturn
2132 gst_mxf_demux_handle_random_index_pack (GstMXFDemux * demux, const MXFUL * key,
2135 GST_DEBUG_OBJECT (demux,
2136 "Handling random index pack of size %u at offset %"
2137 G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
2139 /* TODO: Parse this */
2143 static GstFlowReturn
2144 gst_mxf_demux_handle_index_table_segment (GstMXFDemux * demux,
2145 const MXFUL * key, GstBuffer * buffer)
2147 GST_DEBUG_OBJECT (demux,
2148 "Handling index table segment of size %u at offset %"
2149 G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
2151 /* TODO: Parse this */
2155 static GstFlowReturn
2156 gst_mxf_demux_pull_klv_packet (GstMXFDemux * demux, guint64 offset, MXFUL * key,
2157 GstBuffer ** outbuf, guint * read)
2159 GstBuffer *buffer = NULL;
2161 guint64 data_offset = 0;
2163 GstFlowReturn ret = GST_FLOW_OK;
2165 memset (key, 0, sizeof (MXFUL));
2167 /* Pull 16 byte key and first byte of BER encoded length */
2169 gst_mxf_demux_pull_range (demux, offset, 17, &buffer)) != GST_FLOW_OK)
2172 data = GST_BUFFER_DATA (buffer);
2174 memcpy (key, GST_BUFFER_DATA (buffer), 16);
2176 /* Decode BER encoded packet length */
2177 if ((data[16] & 0x80) == 0) {
2181 guint slen = data[16] & 0x7f;
2183 data_offset = 16 + 1 + slen;
2185 gst_buffer_unref (buffer);
2188 /* Must be at most 8 according to SMPTE-379M 5.3.4 */
2190 GST_ERROR_OBJECT (demux, "Invalid KLV packet length: %u", slen);
2191 ret = GST_FLOW_ERROR;
2195 /* Now pull the length of the packet */
2196 if ((ret = gst_mxf_demux_pull_range (demux, offset + 17, slen,
2197 &buffer)) != GST_FLOW_OK)
2199 data = GST_BUFFER_DATA (buffer);
2203 length = (length << 8) | *data;
2209 gst_buffer_unref (buffer);
2212 /* GStreamer's buffer sizes are stored in a guint so we
2213 * limit ourself to G_MAXUINT large buffers */
2214 if (length > G_MAXUINT) {
2215 GST_ERROR_OBJECT (demux,
2216 "Unsupported KLV packet length: %" G_GUINT64_FORMAT, length);
2217 ret = GST_FLOW_ERROR;
2221 /* Pull the complete KLV packet */
2222 if ((ret = gst_mxf_demux_pull_range (demux, offset + data_offset, length,
2223 &buffer)) != GST_FLOW_OK)
2229 *read = data_offset + length;
2233 gst_buffer_unref (buffer);
2239 gst_mxf_demux_parse_footer_metadata (GstMXFDemux * demux)
2241 MXFPartitionPack partition;
2242 MXFPrimerPack primer;
2243 guint64 offset, old_offset = demux->offset;
2245 GstBuffer *buffer = NULL;
2247 GstFlowReturn ret = GST_FLOW_OK;
2249 memcpy (&partition, &demux->partition, sizeof (MXFPartitionPack));
2250 memcpy (&primer, &demux->primer, sizeof (MXFPrimerPack));
2251 memset (&demux->partition, 0, sizeof (MXFPartitionPack));
2252 memset (&demux->primer, 0, sizeof (MXFPrimerPack));
2254 gst_mxf_demux_reset_metadata (demux);
2256 demux->header_partition_pack_offset + demux->footer_partition_pack_offset;
2259 mxf_partition_pack_reset (&demux->partition);
2260 mxf_primer_pack_reset (&demux->primer);
2262 ret = gst_mxf_demux_pull_klv_packet (demux, offset, &key, &buffer, &read);
2263 if (G_UNLIKELY (ret != GST_FLOW_OK))
2266 if (!mxf_is_partition_pack (&key))
2269 if (!mxf_partition_pack_parse (&key, &demux->partition,
2270 GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer)))
2274 gst_buffer_unref (buffer);
2277 if (demux->partition.header_byte_count == 0) {
2278 if (demux->partition.prev_partition == 0
2279 || demux->partition.this_partition == 0)
2283 demux->header_partition_pack_offset + demux->partition.prev_partition;
2288 ret = gst_mxf_demux_pull_klv_packet (demux, offset, &key, &buffer, &read);
2289 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
2291 demux->header_partition_pack_offset + demux->partition.prev_partition;
2295 if (mxf_is_fill (&key)) {
2297 gst_buffer_unref (buffer);
2299 } else if (mxf_is_primer_pack (&key)) {
2300 if (!mxf_primer_pack_parse (&key, &demux->primer,
2301 GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
2303 gst_buffer_unref (buffer);
2306 demux->header_partition_pack_offset +
2307 demux->partition.prev_partition;
2311 gst_buffer_unref (buffer);
2315 gst_buffer_unref (buffer);
2318 demux->header_partition_pack_offset + demux->partition.prev_partition;
2323 /* parse metadata */
2325 ret = gst_mxf_demux_pull_klv_packet (demux, offset, &key, &buffer, &read);
2326 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
2328 demux->header_partition_pack_offset + demux->partition.prev_partition;
2332 if (mxf_is_metadata (&key)) {
2333 ret = gst_mxf_demux_handle_metadata (demux, &key, buffer);
2335 gst_buffer_unref (buffer);
2338 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
2339 gst_mxf_demux_reset_metadata (demux);
2341 demux->header_partition_pack_offset +
2342 demux->partition.prev_partition;
2345 } else if (mxf_is_fill (&key)) {
2347 gst_buffer_unref (buffer);
2354 /* resolve references etc */
2356 if (gst_mxf_demux_handle_header_metadata_resolve_references (demux) !=
2358 || gst_mxf_demux_handle_header_metadata_update_streams (demux) !=
2361 demux->header_partition_pack_offset + demux->partition.prev_partition;
2365 demux->final_metadata = TRUE;
2369 gst_buffer_unref (buffer);
2371 mxf_partition_pack_reset (&demux->partition);
2372 mxf_primer_pack_reset (&demux->primer);
2373 memcpy (&demux->partition, &partition, sizeof (MXFPartitionPack));
2374 memcpy (&demux->primer, &primer, sizeof (MXFPrimerPack));
2376 demux->offset = old_offset;
2379 static GstFlowReturn
2380 gst_mxf_demux_handle_klv_packet (GstMXFDemux * demux, const MXFUL * key,
2384 GstFlowReturn ret = GST_FLOW_OK;
2386 /* In pull mode try to get the last metadata */
2387 if (demux->pull_footer_metadata && !demux->final_metadata
2388 && demux->random_access && demux->partition.valid
2389 && demux->partition.type == MXF_PARTITION_PACK_HEADER
2390 && (!demux->partition.closed || !demux->partition.complete)
2391 && demux->footer_partition_pack_offset != 0) {
2392 GST_DEBUG_OBJECT (demux,
2393 "Open or incomplete header partition, trying to get final metadata from the last partitions");
2394 gst_mxf_demux_parse_footer_metadata (demux);
2395 demux->pull_footer_metadata = FALSE;
2398 /* TODO: - Pull random index pack from footer partition?
2399 * - Pull all partitions for parsing all index segments and having a complete index
2400 * as first thing. This also will make it possible to use the latest header
2401 * metadata if it's not in the footer partition
2404 if (demux->update_metadata
2405 && !mxf_timestamp_is_unknown (&demux->preface.last_modified_date)
2406 && !mxf_is_metadata (key) && !mxf_is_descriptive_metadata (key)
2407 && !mxf_is_fill (key)) {
2409 gst_mxf_demux_handle_header_metadata_resolve_references (demux)) !=
2413 gst_mxf_demux_handle_header_metadata_update_streams (demux)) !=
2418 if (!mxf_is_mxf_packet (key)) {
2419 GST_WARNING_OBJECT (demux,
2420 "Skipping non-MXF packet of size %u at offset %"
2421 G_GUINT64_FORMAT ", key: %s", GST_BUFFER_SIZE (buffer), demux->offset,
2422 mxf_ul_to_string (key, key_str));
2423 } else if (mxf_is_partition_pack (key)) {
2424 ret = gst_mxf_demux_handle_partition_pack (demux, key, buffer);
2425 } else if (mxf_is_primer_pack (key)) {
2426 ret = gst_mxf_demux_handle_primer_pack (demux, key, buffer);
2427 } else if (mxf_is_metadata (key)) {
2428 ret = gst_mxf_demux_handle_metadata (demux, key, buffer);
2429 } else if (mxf_is_generic_container_system_item (key)) {
2431 gst_mxf_demux_handle_generic_container_system_item (demux, key, buffer);
2432 } else if (mxf_is_generic_container_essence_element (key)) {
2434 gst_mxf_demux_handle_generic_container_essence_element (demux, key,
2436 } else if (mxf_is_random_index_pack (key)) {
2437 ret = gst_mxf_demux_handle_random_index_pack (demux, key, buffer);
2438 } else if (mxf_is_index_table_segment (key)) {
2439 ret = gst_mxf_demux_handle_index_table_segment (demux, key, buffer);
2440 } else if (mxf_is_fill (key)) {
2441 GST_DEBUG_OBJECT (demux,
2442 "Skipping filler packet of size %u at offset %"
2443 G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
2445 GST_DEBUG_OBJECT (demux,
2446 "Skipping unknown packet of size %u at offset %"
2447 G_GUINT64_FORMAT ", key: %s", GST_BUFFER_SIZE (buffer), demux->offset,
2448 mxf_ul_to_string (key, key_str));
2455 static GstFlowReturn
2456 gst_mxf_demux_pull_and_handle_klv_packet (GstMXFDemux * demux)
2458 GstBuffer *buffer = NULL;
2460 GstFlowReturn ret = GST_FLOW_OK;
2464 gst_mxf_demux_pull_klv_packet (demux, demux->offset, &key, &buffer,
2466 if (G_UNLIKELY (ret != GST_FLOW_OK))
2469 ret = gst_mxf_demux_handle_klv_packet (demux, &key, buffer);
2471 demux->offset += read;
2475 gst_buffer_unref (buffer);
2481 gst_mxf_demux_loop (GstPad * pad)
2483 GstMXFDemux *demux = NULL;
2484 GstFlowReturn ret = GST_FLOW_OK;
2486 demux = GST_MXF_DEMUX (gst_pad_get_parent (pad));
2488 if (demux->run_in == -1) {
2489 /* Skip run-in, which is at most 64K and is finished
2490 * by a header partition pack */
2491 while (demux->offset < 64 * 1024) {
2495 gst_mxf_demux_pull_range (demux, demux->offset, 16,
2496 &buffer)) != GST_FLOW_OK)
2499 if (mxf_is_header_partition_pack ((const MXFUL *)
2500 GST_BUFFER_DATA (buffer))) {
2501 GST_DEBUG_OBJECT (demux,
2502 "Found header partition pack at offset %" G_GUINT64_FORMAT,
2504 demux->run_in = demux->offset;
2505 demux->header_partition_pack_offset = demux->offset;
2506 gst_buffer_unref (buffer);
2511 gst_buffer_unref (buffer);
2515 if (G_UNLIKELY (ret != GST_FLOW_OK))
2518 if (G_UNLIKELY (demux->run_in == -1)) {
2519 GST_ERROR_OBJECT (demux, "No valid header partition pack found");
2520 ret = GST_FLOW_ERROR;
2524 /* Now actually do something */
2525 ret = gst_mxf_demux_pull_and_handle_klv_packet (demux);
2527 /* pause if something went wrong */
2528 if (G_UNLIKELY (ret != GST_FLOW_OK))
2531 /* check EOS condition */
2532 if ((demux->segment.flags & GST_SEEK_FLAG_SEGMENT) &&
2533 (demux->segment.stop != -1) &&
2534 (demux->segment.last_stop >= demux->segment.stop)) {
2535 ret = GST_FLOW_UNEXPECTED;
2539 gst_object_unref (demux);
2545 const gchar *reason = gst_flow_get_name (ret);
2547 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
2548 gst_pad_pause_task (pad);
2550 if (GST_FLOW_IS_FATAL (ret) || ret == GST_FLOW_NOT_LINKED) {
2551 if (ret == GST_FLOW_UNEXPECTED) {
2552 /* perform EOS logic */
2553 if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
2556 /* for segment playback we need to post when (in stream time)
2557 * we stopped, this is either stop (when set) or the duration. */
2558 if ((stop = demux->segment.stop) == -1)
2559 stop = demux->segment.duration;
2561 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
2562 gst_element_post_message (GST_ELEMENT_CAST (demux),
2563 gst_message_new_segment_done (GST_OBJECT_CAST (demux),
2564 GST_FORMAT_TIME, stop));
2566 /* normal playback, send EOS to all linked pads */
2567 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
2568 if (!gst_mxf_demux_push_src_event (demux, gst_event_new_eos ())) {
2569 GST_WARNING_OBJECT (demux, "failed pushing EOS on streams");
2573 GST_ELEMENT_ERROR (demux, STREAM, FAILED,
2574 ("Internal data stream error."),
2575 ("stream stopped, reason %s", reason));
2576 gst_mxf_demux_push_src_event (demux, gst_event_new_eos ());
2579 gst_object_unref (demux);
2584 static GstFlowReturn
2585 gst_mxf_demux_chain (GstPad * pad, GstBuffer * inbuf)
2587 GstFlowReturn ret = GST_FLOW_OK;
2588 GstMXFDemux *demux = NULL;
2590 const guint8 *data = NULL;
2593 GstBuffer *buffer = NULL;
2595 demux = GST_MXF_DEMUX (gst_pad_get_parent (pad));
2597 GST_LOG_OBJECT (demux, "received buffer of %u bytes at offset %"
2598 G_GUINT64_FORMAT, GST_BUFFER_SIZE (inbuf), GST_BUFFER_OFFSET (inbuf));
2600 if (G_UNLIKELY (GST_BUFFER_OFFSET (inbuf) == 0)) {
2601 GST_DEBUG_OBJECT (demux, "beginning of file, expect header");
2606 if (G_UNLIKELY (demux->offset == 0 && GST_BUFFER_OFFSET (inbuf) != 0)) {
2607 GST_DEBUG_OBJECT (demux, "offset was zero, synchronizing with buffer's");
2608 demux->offset = GST_BUFFER_OFFSET (inbuf);
2611 gst_adapter_push (demux->adapter, inbuf);
2614 while (ret == GST_FLOW_OK) {
2615 if (G_UNLIKELY (demux->flushing)) {
2616 GST_DEBUG_OBJECT (demux, "we are now flushing, exiting parser loop");
2617 ret = GST_FLOW_WRONG_STATE;
2621 if (gst_adapter_available (demux->adapter) < 16)
2624 if (demux->run_in == -1) {
2625 /* Skip run-in, which is at most 64K and is finished
2626 * by a header partition pack */
2628 while (demux->offset < 64 * 1024
2629 && gst_adapter_available (demux->adapter) >= 16) {
2630 data = gst_adapter_peek (demux->adapter, 16);
2632 if (mxf_is_header_partition_pack ((const MXFUL *)
2634 GST_DEBUG_OBJECT (demux,
2635 "Found header partition pack at offset %" G_GUINT64_FORMAT,
2637 demux->run_in = demux->offset;
2638 demux->header_partition_pack_offset = demux->offset;
2641 gst_adapter_flush (demux->adapter, 1);
2645 if (G_UNLIKELY (ret != GST_FLOW_OK))
2648 /* Need more data */
2649 if (demux->run_in == -1 && demux->offset < 64 * 1024)
2652 if (G_UNLIKELY (demux->run_in == -1)) {
2653 GST_ERROR_OBJECT (demux, "No valid header partition pack found");
2654 ret = GST_FLOW_ERROR;
2658 if (gst_adapter_available (demux->adapter) < 17)
2661 /* Now actually do something */
2662 memset (&key, 0, sizeof (MXFUL));
2664 /* Pull 16 byte key and first byte of BER encoded length */
2665 data = gst_adapter_peek (demux->adapter, 17);
2667 memcpy (&key, data, 16);
2669 /* Decode BER encoded packet length */
2670 if ((data[16] & 0x80) == 0) {
2674 guint slen = data[16] & 0x7f;
2676 offset = 16 + 1 + slen;
2678 /* Must be at most 8 according to SMPTE-379M 5.3.4 and
2679 * GStreamer buffers can only have a 4 bytes length */
2681 GST_ERROR_OBJECT (demux, "Invalid KLV packet length: %u", slen);
2682 ret = GST_FLOW_ERROR;
2686 if (gst_adapter_available (demux->adapter) < 17 + slen)
2689 data = gst_adapter_peek (demux->adapter, 17 + slen);
2694 length = (length << 8) | *data;
2700 /* GStreamer's buffer sizes are stored in a guint so we
2701 * limit ourself to G_MAXUINT large buffers */
2702 if (length > G_MAXUINT) {
2703 GST_ERROR_OBJECT (demux,
2704 "Unsupported KLV packet length: %" G_GUINT64_FORMAT, length);
2705 ret = GST_FLOW_ERROR;
2709 if (gst_adapter_available (demux->adapter) < offset + length)
2712 gst_adapter_flush (demux->adapter, offset);
2713 buffer = gst_adapter_take_buffer (demux->adapter, length);
2715 ret = gst_mxf_demux_handle_klv_packet (demux, &key, buffer);
2716 gst_buffer_unref (buffer);
2719 gst_object_unref (demux);
2725 gst_mxf_demux_src_event (GstPad * pad, GstEvent * event)
2727 GstMXFDemux *demux = GST_MXF_DEMUX (gst_pad_get_parent (pad));
2730 GST_DEBUG_OBJECT (pad, "handling event %s", GST_EVENT_TYPE_NAME (event));
2732 switch (GST_EVENT_TYPE (event)) {
2733 case GST_EVENT_SEEK:
2734 /* TODO: handle this */
2735 gst_event_unref (event);
2739 ret = gst_pad_push_event (demux->sinkpad, event);
2743 gst_object_unref (demux);
2748 static const GstQueryType *
2749 gst_mxf_demux_src_query_type (GstPad * pad)
2751 static const GstQueryType types[] = {
2761 gst_mxf_demux_src_query (GstPad * pad, GstQuery * query)
2763 GstMXFDemux *demux = GST_MXF_DEMUX (gst_pad_get_parent (pad));
2764 gboolean ret = FALSE;
2765 GstMXFPad *mxfpad = GST_MXF_PAD (pad);
2767 GST_DEBUG_OBJECT (pad, "handling query %s",
2768 gst_query_type_get_name (GST_QUERY_TYPE (query)));
2770 switch (GST_QUERY_TYPE (query)) {
2771 case GST_QUERY_POSITION:
2776 gst_query_parse_position (query, &format, NULL);
2777 if (format != GST_FORMAT_TIME && format != GST_FORMAT_DEFAULT)
2780 pos = mxfpad->essence_element_count;
2781 if (format == GST_FORMAT_TIME) {
2782 if (!mxfpad->material_track || mxfpad->material_track->edit_rate.n == 0
2783 || mxfpad->material_track->edit_rate.d == 0)
2787 gst_util_uint64_scale (pos + mxfpad->material_track->origin,
2788 GST_SECOND * mxfpad->material_track->edit_rate.d,
2789 mxfpad->material_track->edit_rate.n);
2792 GST_DEBUG_OBJECT (pad,
2793 "Returning position %" G_GINT64_FORMAT " in format %s", pos,
2794 gst_format_get_name (format));
2796 gst_query_set_position (query, format, pos);
2801 case GST_QUERY_DURATION:{
2805 gst_query_parse_duration (query, &format, NULL);
2806 if (format != GST_FORMAT_TIME && format != GST_FORMAT_DEFAULT)
2809 if (!mxfpad->material_track || !mxfpad->material_track->sequence)
2812 duration = mxfpad->material_track->sequence->duration;
2813 if (format == GST_FORMAT_TIME) {
2814 if (mxfpad->material_track->edit_rate.n == 0 ||
2815 mxfpad->material_track->edit_rate.d == 0)
2819 gst_util_uint64_scale (duration,
2820 GST_SECOND * mxfpad->material_track->edit_rate.d,
2821 mxfpad->material_track->edit_rate.n);
2824 GST_DEBUG_OBJECT (pad,
2825 "Returning duration %" G_GINT64_FORMAT " in format %s", duration,
2826 gst_format_get_name (format));
2828 gst_query_set_duration (query, format, duration);
2833 /* else forward upstream */
2834 ret = gst_pad_peer_query (demux->sinkpad, query);
2839 gst_object_unref (demux);
2845 GST_DEBUG_OBJECT (pad, "query failed");
2851 gst_mxf_demux_sink_activate (GstPad * sinkpad)
2853 if (gst_pad_check_pull_range (sinkpad)) {
2854 return gst_pad_activate_pull (sinkpad, TRUE);
2856 return gst_pad_activate_push (sinkpad, TRUE);
2861 gst_mxf_demux_sink_activate_push (GstPad * sinkpad, gboolean active)
2865 demux = GST_MXF_DEMUX (gst_pad_get_parent (sinkpad));
2867 demux->random_access = FALSE;
2869 gst_object_unref (demux);
2875 gst_mxf_demux_sink_activate_pull (GstPad * sinkpad, gboolean active)
2879 demux = GST_MXF_DEMUX (gst_pad_get_parent (sinkpad));
2882 demux->random_access = TRUE;
2883 gst_object_unref (demux);
2884 return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_mxf_demux_loop,
2887 demux->random_access = FALSE;
2888 gst_object_unref (demux);
2889 return gst_pad_stop_task (sinkpad);
2894 gst_mxf_demux_sink_event (GstPad * pad, GstEvent * event)
2897 gboolean ret = FALSE;
2899 demux = GST_MXF_DEMUX (gst_pad_get_parent (pad));
2901 GST_DEBUG_OBJECT (pad, "handling event %s", GST_EVENT_TYPE_NAME (event));
2903 switch (GST_EVENT_TYPE (event)) {
2904 case GST_EVENT_FLUSH_START:
2905 demux->flushing = TRUE;
2906 ret = gst_mxf_demux_push_src_event (demux, event);
2908 case GST_EVENT_FLUSH_STOP:
2909 gst_mxf_demux_flush (demux, TRUE);
2910 ret = gst_mxf_demux_push_src_event (demux, event);
2913 if (!gst_mxf_demux_push_src_event (demux, event))
2914 GST_WARNING_OBJECT (pad, "failed pushing EOS on streams");
2917 case GST_EVENT_NEWSEGMENT:
2918 /* TODO: handle this */
2919 gst_event_unref (event);
2923 ret = gst_mxf_demux_push_src_event (demux, event);
2927 gst_object_unref (demux);
2932 static GstStateChangeReturn
2933 gst_mxf_demux_change_state (GstElement * element, GstStateChange transition)
2935 GstMXFDemux *demux = GST_MXF_DEMUX (element);
2936 GstStateChangeReturn ret;
2938 switch (transition) {
2939 case GST_STATE_CHANGE_READY_TO_PAUSED:
2945 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
2946 if (ret == GST_STATE_CHANGE_FAILURE)
2949 switch (transition) {
2950 case GST_STATE_CHANGE_PAUSED_TO_READY:
2951 gst_mxf_demux_reset (demux);
2961 gst_mxf_demux_finalize (GObject * object)
2963 GstMXFDemux *demux = GST_MXF_DEMUX (object);
2965 if (demux->adapter) {
2966 g_object_unref (demux->adapter);
2967 demux->adapter = NULL;
2970 if (demux->new_seg_event) {
2971 gst_event_unref (demux->new_seg_event);
2972 demux->new_seg_event = NULL;
2975 if (demux->close_seg_event) {
2976 gst_event_unref (demux->close_seg_event);
2977 demux->close_seg_event = NULL;
2981 g_ptr_array_foreach (demux->src, (GFunc) gst_mxf_demux_remove_pad, demux);
2982 g_ptr_array_foreach (demux->src, (GFunc) gst_object_unref, NULL);
2983 g_ptr_array_free (demux->src, TRUE);
2987 G_OBJECT_CLASS (parent_class)->finalize (object);
2991 gst_mxf_demux_base_init (gpointer g_class)
2993 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
2995 gst_element_class_add_pad_template (element_class,
2996 gst_static_pad_template_get (&mxf_sink_template));
2997 gst_element_class_add_pad_template (element_class,
2998 gst_static_pad_template_get (&audio_src_template));
2999 gst_element_class_add_pad_template (element_class,
3000 gst_static_pad_template_get (&video_src_template));
3001 gst_element_class_add_pad_template (element_class,
3002 gst_static_pad_template_get (&data_src_template));
3003 gst_element_class_set_details_simple (element_class, "MXF Demuxer",
3005 "Demux MXF files", "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
3009 gst_mxf_demux_class_init (GstMXFDemuxClass * klass)
3011 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
3012 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
3014 GST_DEBUG_CATEGORY_INIT (mxfdemux_debug, "mxfdemux", 0, "MXF demuxer");
3016 gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_mxf_demux_finalize);
3018 gstelement_class->change_state =
3019 GST_DEBUG_FUNCPTR (gst_mxf_demux_change_state);
3023 gst_mxf_demux_init (GstMXFDemux * demux, GstMXFDemuxClass * g_class)
3026 gst_pad_new_from_static_template (&mxf_sink_template, "sink");
3028 gst_pad_set_event_function (demux->sinkpad,
3029 GST_DEBUG_FUNCPTR (gst_mxf_demux_sink_event));
3030 gst_pad_set_chain_function (demux->sinkpad,
3031 GST_DEBUG_FUNCPTR (gst_mxf_demux_chain));
3032 gst_pad_set_activate_function (demux->sinkpad,
3033 GST_DEBUG_FUNCPTR (gst_mxf_demux_sink_activate));
3034 gst_pad_set_activatepull_function (demux->sinkpad,
3035 GST_DEBUG_FUNCPTR (gst_mxf_demux_sink_activate_pull));
3036 gst_pad_set_activatepush_function (demux->sinkpad,
3037 GST_DEBUG_FUNCPTR (gst_mxf_demux_sink_activate_push));
3039 gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);
3041 demux->adapter = gst_adapter_new ();
3042 demux->src = g_ptr_array_new ();
3043 gst_segment_init (&demux->segment, GST_FORMAT_TIME);
3045 gst_mxf_demux_reset (demux);