diff options
author | Sebastian Dröge <slomo@circular-chaos.org> | 2008-12-15 17:27:00 +0000 |
---|---|---|
committer | Sebastian Dröge <slomo@circular-chaos.org> | 2008-12-15 17:27:00 +0000 |
commit | bc93b81dd56106f11d87f6a8ad9b6134f2817a57 (patch) | |
tree | 7c1d9ab165287ddff168bdde0d16579a1f95487c | |
parent | 9cfbca8754cef7961cbfbfb1d7a66ab886efefc9 (diff) | |
download | gst-plugins-bad-bc93b81dd56106f11d87f6a8ad9b6134f2817a57.tar.gz gst-plugins-bad-bc93b81dd56106f11d87f6a8ad9b6134f2817a57.tar.bz2 gst-plugins-bad-bc93b81dd56106f11d87f6a8ad9b6134f2817a57.zip |
gst/mxf/: Convert the structural metadata to GstMiniObjects to make a lot of code easier and to make everything bette...
Original commit message from CVS:
* gst/mxf/Makefile.am:
* gst/mxf/mxf.c: (plugin_init):
* gst/mxf/mxfaes-bwf.c:
(mxf_metadata_wave_audio_essence_descriptor_handle_tag),
(mxf_metadata_wave_audio_essence_descriptor_init),
(mxf_metadata_wave_audio_essence_descriptor_class_init),
(mxf_metadata_aes3_audio_essence_descriptor_finalize),
(mxf_metadata_aes3_audio_essence_descriptor_handle_tag),
(mxf_metadata_aes3_audio_essence_descriptor_init),
(mxf_metadata_aes3_audio_essence_descriptor_class_init),
(mxf_is_aes_bwf_essence_track), (mxf_bwf_create_caps),
(mxf_aes3_create_caps), (mxf_aes_bwf_create_caps),
(mxf_aes_bwf_init):
* gst/mxf/mxfaes-bwf.h:
* gst/mxf/mxfalaw.c: (mxf_is_alaw_essence_track),
(mxf_alaw_create_caps), (mxf_alaw_init):
* gst/mxf/mxfalaw.h:
* gst/mxf/mxfd10.c: (mxf_is_d10_essence_track),
(mxf_d10_create_caps), (mxf_d10_init):
* gst/mxf/mxfd10.h:
* gst/mxf/mxfdemux.c: (gst_mxf_demux_reset_metadata),
(gst_mxf_demux_handle_header_metadata_resolve_references),
(gst_mxf_demux_find_package), (gst_mxf_demux_choose_package),
(gst_mxf_demux_handle_header_metadata_update_streams),
(gst_mxf_demux_handle_metadata),
(gst_mxf_demux_handle_generic_container_essence_element),
(gst_mxf_demux_handle_klv_packet), (gst_mxf_demux_src_query):
* gst/mxf/mxfdemux.h:
* gst/mxf/mxfdv-dif.c: (mxf_is_dv_dif_essence_track),
(mxf_dv_dif_create_caps), (mxf_dv_dif_init):
* gst/mxf/mxfdv-dif.h:
* gst/mxf/mxfjpeg2000.c: (mxf_is_jpeg2000_essence_track),
(mxf_jpeg2000_create_caps), (mxf_jpeg2000_init):
* gst/mxf/mxfjpeg2000.h:
* gst/mxf/mxfmetadata.c: (mxf_metadata_base_finalize),
(mxf_metadata_base_handle_tag), (mxf_metadata_base_resolve),
(mxf_metadata_base_init), (mxf_metadata_base_class_init),
(mxf_metadata_parse), (mxf_metadata_resolve),
(mxf_metadata_handle_tag), (mxf_metadata_class_init),
(mxf_metadata_init), (mxf_metadata_init_types),
(mxf_metadata_register), (mxf_metadata_new),
(mxf_metadata_preface_finalize), (mxf_metadata_preface_handle_tag),
(mxf_metadata_preface_resolve), (mxf_metadata_preface_init),
(mxf_metadata_preface_class_init),
(mxf_metadata_identification_finalize),
(mxf_metadata_identification_handle_tag),
(mxf_metadata_identification_init),
(mxf_metadata_identification_class_init),
(mxf_metadata_content_storage_finalize),
(mxf_metadata_content_storage_handle_tag),
(mxf_metadata_content_storage_resolve),
(mxf_metadata_content_storage_init),
(mxf_metadata_content_storage_class_init),
(mxf_metadata_essence_container_data_handle_tag),
(mxf_metadata_essence_container_data_resolve),
(mxf_metadata_essence_container_data_init),
(mxf_metadata_essence_container_data_class_init),
(mxf_metadata_generic_package_finalize),
(mxf_metadata_generic_package_handle_tag),
(mxf_metadata_generic_package_resolve),
(mxf_metadata_generic_package_init),
(mxf_metadata_generic_package_class_init),
(mxf_metadata_material_package_resolve),
(mxf_metadata_material_package_init),
(mxf_metadata_material_package_class_init),
(mxf_metadata_source_package_finalize),
(mxf_metadata_source_package_handle_tag),
(mxf_metadata_source_package_resolve),
(mxf_metadata_source_package_init),
(mxf_metadata_source_package_class_init),
(mxf_metadata_track_finalize), (mxf_metadata_track_handle_tag),
(mxf_metadata_track_resolve), (mxf_metadata_track_init),
(mxf_metadata_track_class_init),
(mxf_metadata_track_identifier_parse),
(mxf_metadata_timeline_track_handle_tag),
(mxf_metadata_timeline_track_init),
(mxf_metadata_timeline_track_class_init),
(mxf_metadata_event_track_handle_tag),
(mxf_metadata_event_track_init),
(mxf_metadata_event_track_class_init),
(mxf_metadata_static_track_init),
(mxf_metadata_static_track_class_init),
(mxf_metadata_sequence_finalize),
(mxf_metadata_sequence_handle_tag),
(mxf_metadata_sequence_resolve), (mxf_metadata_sequence_init),
(mxf_metadata_sequence_class_init),
(mxf_metadata_structural_component_handle_tag),
(mxf_metadata_structural_component_init),
(mxf_metadata_structural_component_class_init),
(mxf_metadata_timecode_component_handle_tag),
(mxf_metadata_timecode_component_init),
(mxf_metadata_timecode_component_class_init),
(mxf_metadata_source_clip_handle_tag),
(mxf_metadata_source_clip_resolve),
(mxf_metadata_source_clip_init),
(mxf_metadata_source_clip_class_init),
(mxf_metadata_dm_source_clip_finalize),
(mxf_metadata_dm_source_clip_handle_tag),
(mxf_metadata_dm_source_clip_init),
(mxf_metadata_dm_source_clip_class_init),
(mxf_metadata_dm_segment_finalize),
(mxf_metadata_dm_segment_handle_tag),
(mxf_metadata_dm_segment_resolve), (mxf_metadata_dm_segment_init),
(mxf_metadata_dm_segment_class_init),
(mxf_metadata_generic_descriptor_finalize),
(mxf_metadata_generic_descriptor_handle_tag),
(mxf_metadata_generic_descriptor_resolve),
(mxf_metadata_generic_descriptor_init),
(mxf_metadata_generic_descriptor_class_init),
(mxf_metadata_file_descriptor_handle_tag),
(mxf_metadata_file_descriptor_init),
(mxf_metadata_file_descriptor_class_init),
(mxf_metadata_generic_picture_essence_descriptor_handle_tag),
(mxf_metadata_generic_picture_essence_descriptor_init),
(mxf_metadata_generic_picture_essence_descriptor_class_init),
(mxf_metadata_generic_picture_essence_descriptor_set_caps),
(mxf_metadata_generic_sound_essence_descriptor_handle_tag),
(mxf_metadata_generic_sound_essence_descriptor_init),
(mxf_metadata_generic_sound_essence_descriptor_class_init),
(mxf_metadata_cdci_picture_essence_descriptor_handle_tag),
(mxf_metadata_cdci_picture_essence_descriptor_init),
(mxf_metadata_cdci_picture_essence_descriptor_class_init),
(mxf_metadata_rgba_picture_essence_descriptor_finalize),
(mxf_metadata_rgba_picture_essence_descriptor_handle_tag),
(mxf_metadata_rgba_picture_essence_descriptor_init),
(mxf_metadata_rgba_picture_essence_descriptor_class_init),
(mxf_metadata_generic_data_essence_descriptor_handle_tag),
(mxf_metadata_generic_data_essence_descriptor_init),
(mxf_metadata_generic_data_essence_descriptor_class_init),
(mxf_metadata_multiple_descriptor_finalize),
(mxf_metadata_multiple_descriptor_handle_tag),
(mxf_metadata_multiple_descriptor_resolve),
(mxf_metadata_multiple_descriptor_init),
(mxf_metadata_multiple_descriptor_class_init),
(mxf_metadata_locator_init), (mxf_metadata_locator_class_init),
(mxf_metadata_text_locator_finalize),
(mxf_metadata_text_locator_handle_tag),
(mxf_metadata_text_locator_init),
(mxf_metadata_text_locator_class_init),
(mxf_metadata_network_locator_finalize),
(mxf_metadata_network_locator_handle_tag),
(mxf_metadata_network_locator_init),
(mxf_metadata_network_locator_class_init):
* gst/mxf/mxfmetadata.h:
* gst/mxf/mxfmpeg.c:
(mxf_metadata_mpeg_video_descriptor_handle_tag),
(mxf_metadata_mpeg_video_descriptor_init),
(mxf_metadata_mpeg_video_descriptor_class_init),
(mxf_is_mpeg_essence_track), (mxf_mpeg_es_create_caps),
(mxf_mpeg_create_caps), (mxf_mpeg_init):
* gst/mxf/mxfmpeg.h:
* gst/mxf/mxfparse.c: (mxf_index_table_segment_parse),
(mxf_local_tag_add_to_hash_table):
* gst/mxf/mxfparse.h:
* gst/mxf/mxftypes.h:
* gst/mxf/mxfup.c: (mxf_is_up_essence_track), (mxf_up_create_caps),
(mxf_up_init):
* gst/mxf/mxfup.h:
Convert the structural metadata to GstMiniObjects to make a lot of
code easier and to make everything better extensible.
Add a "registry" for metadata handlers to improve extensibility even
more and to remove metadata type specifics from mxfdemux.
Clean up a lot of parts and add some more NULL checks.
-rw-r--r-- | ChangeLog | 167 | ||||
-rw-r--r-- | gst/mxf/Makefile.am | 6 | ||||
-rw-r--r-- | gst/mxf/mxf.c | 17 | ||||
-rw-r--r-- | gst/mxf/mxfaes-bwf.c | 389 | ||||
-rw-r--r-- | gst/mxf/mxfaes-bwf.h | 44 | ||||
-rw-r--r-- | gst/mxf/mxfalaw.c | 18 | ||||
-rw-r--r-- | gst/mxf/mxfalaw.h | 2 | ||||
-rw-r--r-- | gst/mxf/mxfd10.c | 31 | ||||
-rw-r--r-- | gst/mxf/mxfd10.h | 2 | ||||
-rw-r--r-- | gst/mxf/mxfdemux.c | 1632 | ||||
-rw-r--r-- | gst/mxf/mxfdemux.h | 30 | ||||
-rw-r--r-- | gst/mxf/mxfdv-dif.c | 22 | ||||
-rw-r--r-- | gst/mxf/mxfdv-dif.h | 2 | ||||
-rw-r--r-- | gst/mxf/mxfjpeg2000.c | 37 | ||||
-rw-r--r-- | gst/mxf/mxfjpeg2000.h | 2 | ||||
-rw-r--r-- | gst/mxf/mxfmetadata.c | 3306 | ||||
-rw-r--r-- | gst/mxf/mxfmetadata.h | 703 | ||||
-rw-r--r-- | gst/mxf/mxfmpeg.c | 127 | ||||
-rw-r--r-- | gst/mxf/mxfmpeg.h | 23 | ||||
-rw-r--r-- | gst/mxf/mxfparse.c | 2204 | ||||
-rw-r--r-- | gst/mxf/mxfparse.h | 80 | ||||
-rw-r--r-- | gst/mxf/mxftypes.h | 406 | ||||
-rw-r--r-- | gst/mxf/mxfup.c | 22 | ||||
-rw-r--r-- | gst/mxf/mxfup.h | 2 |
24 files changed, 4830 insertions, 4444 deletions
@@ -1,3 +1,170 @@ +2008-12-15 Sebastian Dröge <sebastian.droege@collabora.co.uk> + + * gst/mxf/Makefile.am: + * gst/mxf/mxf.c: (plugin_init): + * gst/mxf/mxfaes-bwf.c: + (mxf_metadata_wave_audio_essence_descriptor_handle_tag), + (mxf_metadata_wave_audio_essence_descriptor_init), + (mxf_metadata_wave_audio_essence_descriptor_class_init), + (mxf_metadata_aes3_audio_essence_descriptor_finalize), + (mxf_metadata_aes3_audio_essence_descriptor_handle_tag), + (mxf_metadata_aes3_audio_essence_descriptor_init), + (mxf_metadata_aes3_audio_essence_descriptor_class_init), + (mxf_is_aes_bwf_essence_track), (mxf_bwf_create_caps), + (mxf_aes3_create_caps), (mxf_aes_bwf_create_caps), + (mxf_aes_bwf_init): + * gst/mxf/mxfaes-bwf.h: + * gst/mxf/mxfalaw.c: (mxf_is_alaw_essence_track), + (mxf_alaw_create_caps), (mxf_alaw_init): + * gst/mxf/mxfalaw.h: + * gst/mxf/mxfd10.c: (mxf_is_d10_essence_track), + (mxf_d10_create_caps), (mxf_d10_init): + * gst/mxf/mxfd10.h: + * gst/mxf/mxfdemux.c: (gst_mxf_demux_reset_metadata), + (gst_mxf_demux_handle_header_metadata_resolve_references), + (gst_mxf_demux_find_package), (gst_mxf_demux_choose_package), + (gst_mxf_demux_handle_header_metadata_update_streams), + (gst_mxf_demux_handle_metadata), + (gst_mxf_demux_handle_generic_container_essence_element), + (gst_mxf_demux_handle_klv_packet), (gst_mxf_demux_src_query): + * gst/mxf/mxfdemux.h: + * gst/mxf/mxfdv-dif.c: (mxf_is_dv_dif_essence_track), + (mxf_dv_dif_create_caps), (mxf_dv_dif_init): + * gst/mxf/mxfdv-dif.h: + * gst/mxf/mxfjpeg2000.c: (mxf_is_jpeg2000_essence_track), + (mxf_jpeg2000_create_caps), (mxf_jpeg2000_init): + * gst/mxf/mxfjpeg2000.h: + * gst/mxf/mxfmetadata.c: (mxf_metadata_base_finalize), + (mxf_metadata_base_handle_tag), (mxf_metadata_base_resolve), + (mxf_metadata_base_init), (mxf_metadata_base_class_init), + (mxf_metadata_parse), (mxf_metadata_resolve), + (mxf_metadata_handle_tag), (mxf_metadata_class_init), + (mxf_metadata_init), (mxf_metadata_init_types), + (mxf_metadata_register), (mxf_metadata_new), + (mxf_metadata_preface_finalize), (mxf_metadata_preface_handle_tag), + (mxf_metadata_preface_resolve), (mxf_metadata_preface_init), + (mxf_metadata_preface_class_init), + (mxf_metadata_identification_finalize), + (mxf_metadata_identification_handle_tag), + (mxf_metadata_identification_init), + (mxf_metadata_identification_class_init), + (mxf_metadata_content_storage_finalize), + (mxf_metadata_content_storage_handle_tag), + (mxf_metadata_content_storage_resolve), + (mxf_metadata_content_storage_init), + (mxf_metadata_content_storage_class_init), + (mxf_metadata_essence_container_data_handle_tag), + (mxf_metadata_essence_container_data_resolve), + (mxf_metadata_essence_container_data_init), + (mxf_metadata_essence_container_data_class_init), + (mxf_metadata_generic_package_finalize), + (mxf_metadata_generic_package_handle_tag), + (mxf_metadata_generic_package_resolve), + (mxf_metadata_generic_package_init), + (mxf_metadata_generic_package_class_init), + (mxf_metadata_material_package_resolve), + (mxf_metadata_material_package_init), + (mxf_metadata_material_package_class_init), + (mxf_metadata_source_package_finalize), + (mxf_metadata_source_package_handle_tag), + (mxf_metadata_source_package_resolve), + (mxf_metadata_source_package_init), + (mxf_metadata_source_package_class_init), + (mxf_metadata_track_finalize), (mxf_metadata_track_handle_tag), + (mxf_metadata_track_resolve), (mxf_metadata_track_init), + (mxf_metadata_track_class_init), + (mxf_metadata_track_identifier_parse), + (mxf_metadata_timeline_track_handle_tag), + (mxf_metadata_timeline_track_init), + (mxf_metadata_timeline_track_class_init), + (mxf_metadata_event_track_handle_tag), + (mxf_metadata_event_track_init), + (mxf_metadata_event_track_class_init), + (mxf_metadata_static_track_init), + (mxf_metadata_static_track_class_init), + (mxf_metadata_sequence_finalize), + (mxf_metadata_sequence_handle_tag), + (mxf_metadata_sequence_resolve), (mxf_metadata_sequence_init), + (mxf_metadata_sequence_class_init), + (mxf_metadata_structural_component_handle_tag), + (mxf_metadata_structural_component_init), + (mxf_metadata_structural_component_class_init), + (mxf_metadata_timecode_component_handle_tag), + (mxf_metadata_timecode_component_init), + (mxf_metadata_timecode_component_class_init), + (mxf_metadata_source_clip_handle_tag), + (mxf_metadata_source_clip_resolve), + (mxf_metadata_source_clip_init), + (mxf_metadata_source_clip_class_init), + (mxf_metadata_dm_source_clip_finalize), + (mxf_metadata_dm_source_clip_handle_tag), + (mxf_metadata_dm_source_clip_init), + (mxf_metadata_dm_source_clip_class_init), + (mxf_metadata_dm_segment_finalize), + (mxf_metadata_dm_segment_handle_tag), + (mxf_metadata_dm_segment_resolve), (mxf_metadata_dm_segment_init), + (mxf_metadata_dm_segment_class_init), + (mxf_metadata_generic_descriptor_finalize), + (mxf_metadata_generic_descriptor_handle_tag), + (mxf_metadata_generic_descriptor_resolve), + (mxf_metadata_generic_descriptor_init), + (mxf_metadata_generic_descriptor_class_init), + (mxf_metadata_file_descriptor_handle_tag), + (mxf_metadata_file_descriptor_init), + (mxf_metadata_file_descriptor_class_init), + (mxf_metadata_generic_picture_essence_descriptor_handle_tag), + (mxf_metadata_generic_picture_essence_descriptor_init), + (mxf_metadata_generic_picture_essence_descriptor_class_init), + (mxf_metadata_generic_picture_essence_descriptor_set_caps), + (mxf_metadata_generic_sound_essence_descriptor_handle_tag), + (mxf_metadata_generic_sound_essence_descriptor_init), + (mxf_metadata_generic_sound_essence_descriptor_class_init), + (mxf_metadata_cdci_picture_essence_descriptor_handle_tag), + (mxf_metadata_cdci_picture_essence_descriptor_init), + (mxf_metadata_cdci_picture_essence_descriptor_class_init), + (mxf_metadata_rgba_picture_essence_descriptor_finalize), + (mxf_metadata_rgba_picture_essence_descriptor_handle_tag), + (mxf_metadata_rgba_picture_essence_descriptor_init), + (mxf_metadata_rgba_picture_essence_descriptor_class_init), + (mxf_metadata_generic_data_essence_descriptor_handle_tag), + (mxf_metadata_generic_data_essence_descriptor_init), + (mxf_metadata_generic_data_essence_descriptor_class_init), + (mxf_metadata_multiple_descriptor_finalize), + (mxf_metadata_multiple_descriptor_handle_tag), + (mxf_metadata_multiple_descriptor_resolve), + (mxf_metadata_multiple_descriptor_init), + (mxf_metadata_multiple_descriptor_class_init), + (mxf_metadata_locator_init), (mxf_metadata_locator_class_init), + (mxf_metadata_text_locator_finalize), + (mxf_metadata_text_locator_handle_tag), + (mxf_metadata_text_locator_init), + (mxf_metadata_text_locator_class_init), + (mxf_metadata_network_locator_finalize), + (mxf_metadata_network_locator_handle_tag), + (mxf_metadata_network_locator_init), + (mxf_metadata_network_locator_class_init): + * gst/mxf/mxfmetadata.h: + * gst/mxf/mxfmpeg.c: + (mxf_metadata_mpeg_video_descriptor_handle_tag), + (mxf_metadata_mpeg_video_descriptor_init), + (mxf_metadata_mpeg_video_descriptor_class_init), + (mxf_is_mpeg_essence_track), (mxf_mpeg_es_create_caps), + (mxf_mpeg_create_caps), (mxf_mpeg_init): + * gst/mxf/mxfmpeg.h: + * gst/mxf/mxfparse.c: (mxf_index_table_segment_parse), + (mxf_local_tag_add_to_hash_table): + * gst/mxf/mxfparse.h: + * gst/mxf/mxftypes.h: + * gst/mxf/mxfup.c: (mxf_is_up_essence_track), (mxf_up_create_caps), + (mxf_up_init): + * gst/mxf/mxfup.h: + Convert the structural metadata to GstMiniObjects to make a lot of + code easier and to make everything better extensible. + Add a "registry" for metadata handlers to improve extensibility even + more and to remove metadata type specifics from mxfdemux. + + Clean up a lot of parts and add some more NULL checks. + 2008-12-15 Stefan Kost <ensonic@users.sf.net> * ext/faac/gstfaac.c: diff --git a/gst/mxf/Makefile.am b/gst/mxf/Makefile.am index 16e2e858..96e5720e 100644 --- a/gst/mxf/Makefile.am +++ b/gst/mxf/Makefile.am @@ -10,7 +10,8 @@ libgstmxf_la_SOURCES = \ mxfalaw.c \ mxfjpeg2000.c \ mxfd10.c \ - mxfup.c + mxfup.c \ + mxfmetadata.c libgstmxf_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) libgstmxf_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) \ @@ -27,5 +28,6 @@ noinst_HEADERS = \ mxfjpeg2000.h \ mxfd10.h \ mxfup.h \ - mxftypes.h + mxftypes.h \ + mxfmetadata.h diff --git a/gst/mxf/mxf.c b/gst/mxf/mxf.c index 655ac311..8506f431 100644 --- a/gst/mxf/mxf.c +++ b/gst/mxf/mxf.c @@ -23,6 +23,14 @@ #include <gst/gst.h> #include "mxfdemux.h" +#include "mxfmetadata.h" +#include "mxfaes-bwf.h" +#include "mxfmpeg.h" +#include "mxfdv-dif.h" +#include "mxfalaw.h" +#include "mxfjpeg2000.h" +#include "mxfd10.h" +#include "mxfup.h" GST_DEBUG_CATEGORY (mxf_debug); #define GST_CAT_DEFAULT mxf_debug @@ -30,6 +38,15 @@ GST_DEBUG_CATEGORY (mxf_debug); static gboolean plugin_init (GstPlugin * plugin) { + mxf_metadata_init_types (); + mxf_aes_bwf_init (); + mxf_mpeg_init (); + mxf_dv_dif_init (); + mxf_alaw_init (); + mxf_jpeg2000_init (); + mxf_d10_init (); + mxf_up_init (); + if (!gst_element_register (plugin, "mxfdemux", GST_RANK_PRIMARY, GST_TYPE_MXF_DEMUX)) return FALSE; diff --git a/gst/mxf/mxfaes-bwf.c b/gst/mxf/mxfaes-bwf.c index 98e0f724..6b297ef4 100644 --- a/gst/mxf/mxfaes-bwf.c +++ b/gst/mxf/mxfaes-bwf.c @@ -41,180 +41,199 @@ GST_DEBUG_CATEGORY_EXTERN (mxf_debug); #define GST_CAT_DEFAULT mxf_debug /* SMPTE 382M Annex 1 */ -gboolean - mxf_metadata_wave_audio_essence_descriptor_handle_tag - (MXFMetadataGenericDescriptor * d, const MXFPrimerPack * primer, - guint16 tag, const guint8 * tag_data, guint16 tag_size) +G_DEFINE_TYPE (MXFMetadataWaveAudioEssenceDescriptor, + mxf_metadata_wave_audio_essence_descriptor, + MXF_TYPE_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR); + +static gboolean +mxf_metadata_wave_audio_essence_descriptor_handle_tag (MXFMetadataBase * + metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) { - MXFMetadataWaveAudioEssenceDescriptor *descriptor = - (MXFMetadataWaveAudioEssenceDescriptor *) d; - gboolean ret = FALSE; + MXFMetadataWaveAudioEssenceDescriptor *self = + MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR (metadata); + gboolean ret = TRUE; gchar str[48]; switch (tag) { case 0x3d0a: if (tag_size != 2) goto error; - descriptor->block_align = GST_READ_UINT16_BE (tag_data); - GST_DEBUG (" block align = %u", descriptor->block_align); - ret = TRUE; + self->block_align = GST_READ_UINT16_BE (tag_data); + GST_DEBUG (" block align = %u", self->block_align); break; case 0x3d0b: if (tag_size != 1) goto error; - descriptor->sequence_offset = GST_READ_UINT8 (tag_data); - GST_DEBUG (" sequence offset = %u", descriptor->sequence_offset); - ret = TRUE; + self->sequence_offset = GST_READ_UINT8 (tag_data); + GST_DEBUG (" sequence offset = %u", self->sequence_offset); break; case 0x3d09: if (tag_size != 4) goto error; - descriptor->avg_bps = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" average bps = %u", descriptor->avg_bps); - ret = TRUE; + self->avg_bps = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" average bps = %u", self->avg_bps); break; case 0x3d32: if (tag_size != 16) goto error; - memcpy (&descriptor->channel_assignment, tag_data, 16); + memcpy (&self->channel_assignment, tag_data, 16); GST_DEBUG (" channel assignment = %s", - mxf_ul_to_string (&descriptor->channel_assignment, str)); - ret = TRUE; + mxf_ul_to_string (&self->channel_assignment, str)); break; case 0x3d29: if (tag_size != 4) goto error; - descriptor->peak_envelope_version = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" peak envelope version = %u", - descriptor->peak_envelope_version); - ret = TRUE; + self->peak_envelope_version = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" peak envelope version = %u", self->peak_envelope_version); break; case 0x3d2a: if (tag_size != 4) goto error; - descriptor->peak_envelope_format = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" peak envelope format = %u", - descriptor->peak_envelope_format); - ret = TRUE; + self->peak_envelope_format = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" peak envelope format = %u", self->peak_envelope_format); break; case 0x3d2b: if (tag_size != 4) goto error; - descriptor->points_per_peak_value = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" points per peak value = %u", - descriptor->points_per_peak_value); - ret = TRUE; + self->points_per_peak_value = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" points per peak value = %u", self->points_per_peak_value); break; case 0x3d2c: if (tag_size != 4) goto error; - descriptor->peak_envelope_block_size = GST_READ_UINT32_BE (tag_data); + self->peak_envelope_block_size = GST_READ_UINT32_BE (tag_data); GST_DEBUG (" peak envelope block size = %u", - descriptor->peak_envelope_block_size); - ret = TRUE; + self->peak_envelope_block_size); break; case 0x3d2d: if (tag_size != 4) goto error; - descriptor->peak_channels = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" peak channels = %u", descriptor->peak_channels); - ret = TRUE; + self->peak_channels = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" peak channels = %u", self->peak_channels); break; case 0x3d2e: if (tag_size != 4) goto error; - descriptor->peak_frames = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" peak frames = %u", descriptor->peak_frames); - ret = TRUE; + self->peak_frames = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" peak frames = %u", self->peak_frames); break; case 0x3d2f: if (tag_size != 8) goto error; - descriptor->peak_of_peaks_position = GST_READ_UINT64_BE (tag_data); + self->peak_of_peaks_position = GST_READ_UINT64_BE (tag_data); GST_DEBUG (" peak of peaks position = %" G_GINT64_FORMAT, - descriptor->peak_of_peaks_position); - ret = TRUE; + self->peak_of_peaks_position); break; case 0x3d30: - if (!mxf_timestamp_parse (&descriptor->peak_envelope_timestamp, + if (!mxf_timestamp_parse (&self->peak_envelope_timestamp, tag_data, tag_size)) goto error; GST_DEBUG (" peak envelope timestamp = %d/%u/%u %u:%u:%u.%u", - descriptor->peak_envelope_timestamp.year, - descriptor->peak_envelope_timestamp.month, - descriptor->peak_envelope_timestamp.day, - descriptor->peak_envelope_timestamp.hour, - descriptor->peak_envelope_timestamp.minute, - descriptor->peak_envelope_timestamp.second, - (descriptor->peak_envelope_timestamp.quarter_msecond * 1000) / 256); - ret = TRUE; + self->peak_envelope_timestamp.year, + self->peak_envelope_timestamp.month, + self->peak_envelope_timestamp.day, + self->peak_envelope_timestamp.hour, + self->peak_envelope_timestamp.minute, + self->peak_envelope_timestamp.second, + (self->peak_envelope_timestamp.quarter_msecond * 1000) / 256); break; case 0x3d31: - descriptor->peak_envelope_data = g_memdup (tag_data, tag_size); - descriptor->peak_envelope_data_length = tag_size; + self->peak_envelope_data = g_memdup (tag_data, tag_size); + self->peak_envelope_data_length = tag_size; GST_DEBUG (" peak evelope data size = %u", - descriptor->peak_envelope_data_length); - ret = TRUE; + self->peak_envelope_data_length); break; default: ret = - mxf_metadata_generic_sound_essence_descriptor_handle_tag (d, primer, - tag, tag_data, tag_size); + MXF_METADATA_BASE_CLASS + (mxf_metadata_wave_audio_essence_descriptor_parent_class)-> + handle_tag (metadata, primer, tag, tag_data, tag_size); break; } return ret; error: - GST_ERROR ("Invalid wave audio essence descriptor tag 0x%04x of size %u", tag, + + GST_ERROR + ("Invalid wave audio essence descriptor local tag 0x%04x of size %u", tag, tag_size); return TRUE; } -void mxf_metadata_wave_audio_essence_descriptor_reset - (MXFMetadataWaveAudioEssenceDescriptor * descriptor) +static void + mxf_metadata_wave_audio_essence_descriptor_init + (MXFMetadataWaveAudioEssenceDescriptor * self) { - g_return_if_fail (descriptor != NULL); - mxf_metadata_generic_sound_essence_descriptor_reset ( - (MXFMetadataGenericSoundEssenceDescriptor *) descriptor); +} + +static void + mxf_metadata_wave_audio_essence_descriptor_class_init + (MXFMetadataWaveAudioEssenceDescriptorClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; - MXF_METADATA_DESCRIPTOR_CLEAR (descriptor, - MXFMetadataWaveAudioEssenceDescriptor, - MXFMetadataGenericSoundEssenceDescriptor); + metadata_base_class->handle_tag = + mxf_metadata_wave_audio_essence_descriptor_handle_tag; } /* SMPTE 382M Annex 2 */ -gboolean - mxf_metadata_aes3_audio_essence_descriptor_handle_tag - (MXFMetadataGenericDescriptor * d, const MXFPrimerPack * primer, - guint16 tag, const guint8 * tag_data, guint16 tag_size) +G_DEFINE_TYPE (MXFMetadataAES3AudioEssenceDescriptor, + mxf_metadata_aes3_audio_essence_descriptor, + MXF_TYPE_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR); + +static void +mxf_metadata_aes3_audio_essence_descriptor_finalize (GstMiniObject * object) +{ + MXFMetadataAES3AudioEssenceDescriptor *self = + MXF_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR (object); + + g_free (self->channel_status_mode); + self->channel_status_mode = NULL; + g_free (self->fixed_channel_status_data); + self->fixed_channel_status_data = NULL; + g_free (self->user_data_mode); + self->user_data_mode = NULL; + g_free (self->fixed_user_data); + self->fixed_user_data = NULL; + + GST_MINI_OBJECT_CLASS + (mxf_metadata_aes3_audio_essence_descriptor_parent_class)-> + finalize (object); +} + +static gboolean +mxf_metadata_aes3_audio_essence_descriptor_handle_tag (MXFMetadataBase * + metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) { - MXFMetadataAES3AudioEssenceDescriptor *descriptor = - (MXFMetadataAES3AudioEssenceDescriptor *) d; - gboolean ret = FALSE; + MXFMetadataAES3AudioEssenceDescriptor *self = + MXF_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR (metadata); + gboolean ret = TRUE; switch (tag) { case 0x3d0d: if (tag_size != 1) goto error; - descriptor->emphasis = GST_READ_UINT8 (tag_data); - GST_DEBUG (" emphasis = %u", descriptor->emphasis); + self->emphasis = GST_READ_UINT8 (tag_data); + GST_DEBUG (" emphasis = %u", self->emphasis); ret = TRUE; break; case 0x3d0f: if (tag_size != 2) goto error; - descriptor->block_start_offset = GST_READ_UINT16_BE (tag_data); - GST_DEBUG (" block start offset = %u", descriptor->block_start_offset); + self->block_start_offset = GST_READ_UINT16_BE (tag_data); + GST_DEBUG (" block start offset = %u", self->block_start_offset); ret = TRUE; break; case 0x3d08: if (tag_size != 1) goto error; - descriptor->auxiliary_bits_mode = GST_READ_UINT8 (tag_data); - GST_DEBUG (" auxiliary bits mode = %u", descriptor->auxiliary_bits_mode); + self->auxiliary_bits_mode = GST_READ_UINT8 (tag_data); + GST_DEBUG (" auxiliary bits mode = %u", self->auxiliary_bits_mode); ret = TRUE; break; case 0x3d10:{ @@ -225,7 +244,7 @@ gboolean goto error; len = GST_READ_UINT32_BE (tag_data); GST_DEBUG (" number of channel status mode = %u", len); - descriptor->n_channel_status_mode = len; + self->n_channel_status_mode = len; if (len == 0) return TRUE; @@ -238,12 +257,12 @@ gboolean if (tag_size != len) goto error; - descriptor->channel_status_mode = g_new0 (guint8, len); + self->channel_status_mode = g_new0 (guint8, len); for (i = 0; i < len; i++) { - descriptor->channel_status_mode[i] = GST_READ_UINT8 (tag_data); + self->channel_status_mode[i] = GST_READ_UINT8 (tag_data); GST_DEBUG (" channel status mode %u = %u", i, - descriptor->channel_status_mode[i]); + self->channel_status_mode[i]); tag_data++; tag_size--; } @@ -259,7 +278,7 @@ gboolean goto error; len = GST_READ_UINT32_BE (tag_data); GST_DEBUG (" number of fixed channel status data = %u", len); - descriptor->n_fixed_channel_status_data = len; + self->n_fixed_channel_status_data = len; if (len == 0) return TRUE; @@ -272,41 +291,41 @@ gboolean if (tag_size != len * 24) goto error; - descriptor->fixed_channel_status_data = + self->fixed_channel_status_data = g_malloc0 (len * sizeof (guint8 *) + len * 24); for (i = 0; i < len; i++) { - descriptor->fixed_channel_status_data[i] = - ((guint8 *) descriptor->fixed_channel_status_data) + + self->fixed_channel_status_data[i] = + ((guint8 *) self->fixed_channel_status_data) + len * sizeof (guint8 *) + i * 24; - memcpy (descriptor->fixed_channel_status_data[i], tag_data, 24); + memcpy (self->fixed_channel_status_data[i], tag_data, 24); GST_DEBUG (" fixed channel status data %u = 0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x", - i, descriptor->fixed_channel_status_data[i][0], - descriptor->fixed_channel_status_data[i][1], - descriptor->fixed_channel_status_data[i][2], - descriptor->fixed_channel_status_data[i][3], - descriptor->fixed_channel_status_data[i][4], - descriptor->fixed_channel_status_data[i][5], - descriptor->fixed_channel_status_data[i][6], - descriptor->fixed_channel_status_data[i][7], - descriptor->fixed_channel_status_data[i][8], - descriptor->fixed_channel_status_data[i][9], - descriptor->fixed_channel_status_data[i][10], - descriptor->fixed_channel_status_data[i][11], - descriptor->fixed_channel_status_data[i][12], - descriptor->fixed_channel_status_data[i][13], - descriptor->fixed_channel_status_data[i][14], - descriptor->fixed_channel_status_data[i][15], - descriptor->fixed_channel_status_data[i][16], - descriptor->fixed_channel_status_data[i][17], - descriptor->fixed_channel_status_data[i][18], - descriptor->fixed_channel_status_data[i][19], - descriptor->fixed_channel_status_data[i][20], - descriptor->fixed_channel_status_data[i][21], - descriptor->fixed_channel_status_data[i][22], - descriptor->fixed_channel_status_data[i][23] + i, self->fixed_channel_status_data[i][0], + self->fixed_channel_status_data[i][1], + self->fixed_channel_status_data[i][2], + self->fixed_channel_status_data[i][3], + self->fixed_channel_status_data[i][4], + self->fixed_channel_status_data[i][5], + self->fixed_channel_status_data[i][6], + self->fixed_channel_status_data[i][7], + self->fixed_channel_status_data[i][8], + self->fixed_channel_status_data[i][9], + self->fixed_channel_status_data[i][10], + self->fixed_channel_status_data[i][11], + self->fixed_channel_status_data[i][12], + self->fixed_channel_status_data[i][13], + self->fixed_channel_status_data[i][14], + self->fixed_channel_status_data[i][15], + self->fixed_channel_status_data[i][16], + self->fixed_channel_status_data[i][17], + self->fixed_channel_status_data[i][18], + self->fixed_channel_status_data[i][19], + self->fixed_channel_status_data[i][20], + self->fixed_channel_status_data[i][21], + self->fixed_channel_status_data[i][22], + self->fixed_channel_status_data[i][23] ); tag_data += 24; tag_size -= 24; @@ -323,7 +342,7 @@ gboolean goto error; len = GST_READ_UINT32_BE (tag_data); GST_DEBUG (" number of user data mode = %u", len); - descriptor->n_user_data_mode = len; + self->n_user_data_mode = len; if (len == 0) return TRUE; @@ -336,12 +355,11 @@ gboolean if (tag_size != len) goto error; - descriptor->user_data_mode = g_new0 (guint8, len); + self->user_data_mode = g_new0 (guint8, len); for (i = 0; i < len; i++) { - descriptor->user_data_mode[i] = GST_READ_UINT8 (tag_data); - GST_DEBUG (" user data mode %u = %u", i, - descriptor->user_data_mode[i]); + self->user_data_mode[i] = GST_READ_UINT8 (tag_data); + GST_DEBUG (" user data mode %u = %u", i, self->user_data_mode[i]); tag_data++; tag_size--; } @@ -357,7 +375,7 @@ gboolean goto error; len = GST_READ_UINT32_BE (tag_data); GST_DEBUG (" number of fixed user data = %u", len); - descriptor->n_fixed_user_data = len; + self->n_fixed_user_data = len; if (len == 0) return TRUE; @@ -370,41 +388,39 @@ gboolean if (tag_size != len * 24) goto error; - descriptor->fixed_user_data = - g_malloc0 (len * sizeof (guint8 *) + len * 24); + self->fixed_user_data = g_malloc0 (len * sizeof (guint8 *) + len * 24); for (i = 0; i < len; i++) { - descriptor->fixed_user_data[i] = - ((guint8 *) descriptor->fixed_user_data) + len * sizeof (guint8 *) + + self->fixed_user_data[i] = + ((guint8 *) self->fixed_user_data) + len * sizeof (guint8 *) + i * 24; - memcpy (descriptor->fixed_user_data[i], tag_data, 24); + memcpy (self->fixed_user_data[i], tag_data, 24); GST_DEBUG (" fixed user data %u = 0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x", - i, descriptor->fixed_user_data[i][0], - descriptor->fixed_user_data[i][1], - descriptor->fixed_user_data[i][2], - descriptor->fixed_user_data[i][3], - descriptor->fixed_user_data[i][4], - descriptor->fixed_user_data[i][5], - descriptor->fixed_user_data[i][6], - descriptor->fixed_user_data[i][7], - descriptor->fixed_user_data[i][8], - descriptor->fixed_user_data[i][9], - descriptor->fixed_user_data[i][10], - descriptor->fixed_user_data[i][11], - descriptor->fixed_user_data[i][12], - descriptor->fixed_user_data[i][13], - descriptor->fixed_user_data[i][14], - descriptor->fixed_user_data[i][15], - descriptor->fixed_user_data[i][16], - descriptor->fixed_user_data[i][17], - descriptor->fixed_user_data[i][18], - descriptor->fixed_user_data[i][19], - descriptor->fixed_user_data[i][20], - descriptor->fixed_user_data[i][21], - descriptor->fixed_user_data[i][22], - descriptor->fixed_user_data[i][23] + i, self->fixed_user_data[i][0], + self->fixed_user_data[i][1], + self->fixed_user_data[i][2], + self->fixed_user_data[i][3], + self->fixed_user_data[i][4], + self->fixed_user_data[i][5], + self->fixed_user_data[i][6], + self->fixed_user_data[i][7], + self->fixed_user_data[i][8], + self->fixed_user_data[i][9], + self->fixed_user_data[i][10], + self->fixed_user_data[i][11], + self->fixed_user_data[i][12], + self->fixed_user_data[i][13], + self->fixed_user_data[i][14], + self->fixed_user_data[i][15], + self->fixed_user_data[i][16], + self->fixed_user_data[i][17], + self->fixed_user_data[i][18], + self->fixed_user_data[i][19], + self->fixed_user_data[i][20], + self->fixed_user_data[i][21], + self->fixed_user_data[i][22], self->fixed_user_data[i][23] ); tag_data += 24; tag_size -= 24; @@ -417,39 +433,42 @@ gboolean * SMPTE 382M Annex 2 */ default: ret = - mxf_metadata_wave_audio_essence_descriptor_handle_tag (d, primer, - tag, tag_data, tag_size); + MXF_METADATA_BASE_CLASS + (mxf_metadata_aes3_audio_essence_descriptor_parent_class)-> + handle_tag (metadata, primer, tag, tag_data, tag_size); break; } return ret; error: - GST_ERROR ("Invalid AES3 audio essence descriptor tag 0x%04x of size %u", tag, + + GST_ERROR + ("Invalid AES3 audio essence descriptor local tag 0x%04x of size %u", tag, tag_size); return TRUE; } -void mxf_metadata_aes3_audio_essence_descriptor_reset - (MXFMetadataAES3AudioEssenceDescriptor * descriptor) +static void + mxf_metadata_aes3_audio_essence_descriptor_init + (MXFMetadataAES3AudioEssenceDescriptor * self) { - g_return_if_fail (descriptor != NULL); - - mxf_metadata_wave_audio_essence_descriptor_reset ( - (MXFMetadataWaveAudioEssenceDescriptor *) descriptor); - - g_free (descriptor->channel_status_mode); - g_free (descriptor->fixed_channel_status_data); - g_free (descriptor->user_data_mode); - g_free (descriptor->fixed_user_data); - MXF_METADATA_DESCRIPTOR_CLEAR (descriptor, - MXFMetadataAES3AudioEssenceDescriptor, - MXFMetadataWaveAudioEssenceDescriptor); } +static void + mxf_metadata_aes3_audio_essence_descriptor_class_init + (MXFMetadataAES3AudioEssenceDescriptorClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + miniobject_class->finalize = + mxf_metadata_aes3_audio_essence_descriptor_finalize; + metadata_base_class->handle_tag = + mxf_metadata_aes3_audio_essence_descriptor_handle_tag; +} gboolean mxf_is_aes_bwf_essence_track (const MXFMetadataTrack * track) @@ -465,7 +484,12 @@ mxf_is_aes_bwf_essence_track (const MXFMetadataTrack * track) for (i = 0; i < track->n_descriptor; i++) { MXFMetadataFileDescriptor *d = track->descriptor[i]; - MXFUL *key = &d->essence_container; + MXFUL *key; + + if (!d) + continue; + + key = &d->essence_container; /* SMPTE 382M 9 */ if (mxf_is_generic_container_essence_container_label (key) && key->u[12] == 0x02 && @@ -548,8 +572,7 @@ mxf_bwf_create_caps (MXFMetadataGenericPackage * package, gchar str[48]; gchar *codec_name = NULL; - if (((MXFMetadataGenericDescriptor *) descriptor)->type == - MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR) + if (MXF_IS_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR (descriptor)) wa_descriptor = (MXFMetadataWaveAudioEssenceDescriptor *) descriptor; /* TODO: Handle width=!depth, needs shifting of samples */ @@ -666,10 +689,7 @@ mxf_aes3_create_caps (MXFMetadataGenericPackage * package, gchar *codec_name = NULL; guint block_align; - if (((MXFMetadataGenericDescriptor *) descriptor)->type == - MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR || - ((MXFMetadataGenericDescriptor *) descriptor)->type == - MXF_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR) + if (MXF_IS_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR (descriptor)) wa_descriptor = (MXFMetadataWaveAudioEssenceDescriptor *) descriptor; /* FIXME: set a channel layout */ @@ -731,22 +751,18 @@ mxf_aes_bwf_create_caps (MXFMetadataGenericPackage * package, } for (i = 0; i < track->n_descriptor; i++) { - if ((track->descriptor[i]->parent.type == - MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR - || track->descriptor[i]->parent.type == - MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR) + if (!track->descriptor[i]) + continue; + + if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->descriptor[i]) && (track->descriptor[i]->essence_container.u[14] == 0x01 || track->descriptor[i]->essence_container.u[14] == 0x02 || track->descriptor[i]->essence_container.u[14] == 0x08)) { s = (MXFMetadataGenericSoundEssenceDescriptor *) track->descriptor[i]; bwf = TRUE; break; - } else if ((track->descriptor[i]->parent.type == - MXF_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR - || track->descriptor[i]->parent.type == - MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR - || track->descriptor[i]->parent.type == - MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR) + } else if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track-> + descriptor[i]) && (track->descriptor[i]->essence_container.u[14] == 0x03 || track->descriptor[i]->essence_container.u[14] == 0x04 || track->descriptor[i]->essence_container.u[14] == 0x09)) { @@ -769,3 +785,12 @@ mxf_aes_bwf_create_caps (MXFMetadataGenericPackage * package, return NULL; } + +void +mxf_aes_bwf_init (void) +{ + mxf_metadata_register (0x0148, + MXF_TYPE_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR); + mxf_metadata_register (0x0147, + MXF_TYPE_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR); +} diff --git a/gst/mxf/mxfaes-bwf.h b/gst/mxf/mxfaes-bwf.h index e158a8b4..7783a2d0 100644 --- a/gst/mxf/mxfaes-bwf.h +++ b/gst/mxf/mxfaes-bwf.h @@ -27,14 +27,20 @@ #include <gst/gst.h> #include "mxfparse.h" +#include "mxfmetadata.h" /* SMPTE 382M Annex 1 */ -#define MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR 0x0148 -/* SMPTE 382M Annex 2 */ -#define MXF_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR 0x0147 - -/* SMPTE 382M Annex 1 */ -typedef struct { +#define MXF_TYPE_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR \ + (mxf_metadata_wave_audio_essence_descriptor_get_type()) +#define MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR, MXFMetadataWaveAudioEssenceDescriptor)) +#define MXF_IS_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR)) +typedef struct _MXFMetadataWaveAudioEssenceDescriptor MXFMetadataWaveAudioEssenceDescriptor; +typedef MXFMetadataBaseClass MXFMetadataWaveAudioEssenceDescriptorClass; +GType mxf_metadata_wave_audio_essence_descriptor_get_type (void); + +struct _MXFMetadataWaveAudioEssenceDescriptor { MXFMetadataGenericSoundEssenceDescriptor parent; guint16 block_align; @@ -55,10 +61,20 @@ typedef struct { guint8 *peak_envelope_data; guint16 peak_envelope_data_length; -} MXFMetadataWaveAudioEssenceDescriptor; +}; /* SMPTE 382M Annex 2 */ -typedef struct { +#define MXF_TYPE_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR \ + (mxf_metadata_aes3_audio_essence_descriptor_get_type()) +#define MXF_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR, MXFMetadataAES3AudioEssenceDescriptor)) +#define MXF_IS_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR)) +typedef struct _MXFMetadataAES3AudioEssenceDescriptor MXFMetadataAES3AudioEssenceDescriptor; +typedef MXFMetadataBaseClass MXFMetadataAES3AudioEssenceDescriptorClass; +GType mxf_metadata_aes3_audio_essence_descriptor_get_type (void); + +struct _MXFMetadataAES3AudioEssenceDescriptor { MXFMetadataWaveAudioEssenceDescriptor parent; guint8 emphasis; @@ -79,19 +95,13 @@ typedef struct { guint32 linked_timecode_track_id; guint8 stream_number; -} MXFMetadataAES3AudioEssenceDescriptor; - -gboolean mxf_metadata_wave_audio_essence_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor, - const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size); -void mxf_metadata_wave_audio_essence_descriptor_reset (MXFMetadataWaveAudioEssenceDescriptor *descriptor); - -gboolean mxf_metadata_aes3_audio_essence_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor, - const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size); -void mxf_metadata_aes3_audio_essence_descriptor_reset (MXFMetadataAES3AudioEssenceDescriptor *descriptor); +}; gboolean mxf_is_aes_bwf_essence_track (const MXFMetadataTrack *track); GstCaps * mxf_aes_bwf_create_caps (MXFMetadataGenericPackage *package, MXFMetadataTrack *track, GstTagList **tags, MXFEssenceElementHandler *handler, gpointer *mapping_data); +void mxf_aes_bwf_init (void); + #endif /* __MXF_AES_BWF_H__ */ diff --git a/gst/mxf/mxfalaw.c b/gst/mxf/mxfalaw.c index 847eb90a..6b7e419b 100644 --- a/gst/mxf/mxfalaw.c +++ b/gst/mxf/mxfalaw.c @@ -45,7 +45,12 @@ mxf_is_alaw_essence_track (const MXFMetadataTrack * track) for (i = 0; i < track->n_descriptor; i++) { MXFMetadataFileDescriptor *d = track->descriptor[i]; - MXFUL *key = &d->essence_container; + MXFUL *key; + + if (!d) + continue; + + key = &d->essence_container; /* SMPTE 388M 6.1 */ if (mxf_is_generic_container_essence_container_label (key) && key->u[12] == 0x02 && key->u[13] == 0x0a && @@ -93,8 +98,10 @@ mxf_alaw_create_caps (MXFMetadataGenericPackage * package, } for (i = 0; i < track->n_descriptor; i++) { - if (((MXFMetadataGenericDescriptor *) track->descriptor[i])->type == - MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR) { + if (!track->descriptor[i]) + continue; + + if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->descriptor[i])) { s = (MXFMetadataGenericSoundEssenceDescriptor *) track->descriptor[i]; break; } @@ -127,3 +134,8 @@ mxf_alaw_create_caps (MXFMetadataGenericPackage * package, return caps; } + +void +mxf_alaw_init (void) +{ +} diff --git a/gst/mxf/mxfalaw.h b/gst/mxf/mxfalaw.h index 20883fdf..2a1279cc 100644 --- a/gst/mxf/mxfalaw.h +++ b/gst/mxf/mxfalaw.h @@ -33,4 +33,6 @@ gboolean mxf_is_alaw_essence_track (const MXFMetadataTrack *track); GstCaps * mxf_alaw_create_caps (MXFMetadataGenericPackage *package, MXFMetadataTrack *track, GstTagList **tags, MXFEssenceElementHandler *handler, gpointer *mapping_data); +void mxf_alaw_init (void); + #endif /* __MXF_ALAW_H__ */ diff --git a/gst/mxf/mxfd10.c b/gst/mxf/mxfd10.c index bbeb858e..f7d29140 100644 --- a/gst/mxf/mxfd10.c +++ b/gst/mxf/mxfd10.c @@ -52,7 +52,12 @@ mxf_is_d10_essence_track (const MXFMetadataTrack * track) for (i = 0; i < track->n_descriptor; i++) { MXFMetadataFileDescriptor *d = track->descriptor[i]; - MXFUL *key = &d->essence_container; + MXFUL *key; + + if (!d) + continue; + + key = &d->essence_container; /* SMPTE 386M 5.1 */ if (mxf_is_generic_container_essence_container_label (key) && key->u[12] == 0x02 && key->u[13] == 0x01 && @@ -167,20 +172,15 @@ mxf_d10_create_caps (MXFMetadataGenericPackage * package, } for (i = 0; i < track->n_descriptor; i++) { - if (((MXFMetadataGenericDescriptor *) track->descriptor[i])->type == - MXF_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR || - ((MXFMetadataGenericDescriptor *) track->descriptor[i])->type == - MXF_METADATA_MPEG_VIDEO_DESCRIPTOR || - ((MXFMetadataGenericDescriptor *) track->descriptor[i])->type == - MXF_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR) { + if (!track->descriptor[i]) + continue; + + if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track-> + descriptor[i])) { p = (MXFMetadataGenericPictureEssenceDescriptor *) track->descriptor[i]; break; - } else if (((MXFMetadataGenericDescriptor *) track->descriptor[i])->type == - MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR || - ((MXFMetadataGenericDescriptor *) track->descriptor[i])->type == - MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR || - ((MXFMetadataGenericDescriptor *) track->descriptor[i])->type == - MXF_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR) { + } else if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track-> + descriptor[i])) { s = (MXFMetadataGenericSoundEssenceDescriptor *) track->descriptor[i]; break; } @@ -242,3 +242,8 @@ mxf_d10_create_caps (MXFMetadataGenericPackage * package, return caps; } + +void +mxf_d10_init (void) +{ +} diff --git a/gst/mxf/mxfd10.h b/gst/mxf/mxfd10.h index 2fca77b8..e3167d1b 100644 --- a/gst/mxf/mxfd10.h +++ b/gst/mxf/mxfd10.h @@ -33,4 +33,6 @@ gboolean mxf_is_d10_essence_track (const MXFMetadataTrack *track); GstCaps * mxf_d10_create_caps (MXFMetadataGenericPackage *package, MXFMetadataTrack *track, GstTagList **tags, MXFEssenceElementHandler *handler, gpointer *mapping_data); +void mxf_d10_init (void); + #endif /* __MXF_D10_H__ */ diff --git a/gst/mxf/mxfdemux.c b/gst/mxf/mxfdemux.c index f8a2b3b1..b0c0d177 100644 --- a/gst/mxf/mxfdemux.c +++ b/gst/mxf/mxfdemux.c @@ -18,7 +18,6 @@ */ /* TODO: - * - GObjectify structural metadata to get rid of the current inheritance mess * - Implement support for DMS-1 and descriptive metadata tracks * - 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. @@ -56,6 +55,7 @@ #include "mxfdemux.h" #include "mxfparse.h" +#include "mxfmetadata.h" #include "mxfaes-bwf.h" #include "mxfmpeg.h" #include "mxfdv-dif.h" @@ -91,7 +91,6 @@ typedef struct GstPad parent; guint32 track_id; - MXFMetadataTrackType track_type; gboolean need_segment; GstFlowReturn last_flow; @@ -104,11 +103,11 @@ typedef struct guint current_material_component; MXFMetadataGenericPackage *material_package; - MXFMetadataTrack *material_track; + MXFMetadataTimelineTrack *material_track; MXFMetadataStructuralComponent *component; - MXFMetadataGenericPackage *source_package; - MXFMetadataTrack *source_track; + MXFMetadataSourcePackage *source_package; + MXFMetadataTimelineTrack *source_track; GstCaps *caps; } GstMXFDemuxPad; @@ -231,177 +230,19 @@ gst_mxf_demux_reset_metadata (GstMXFDemux * demux) } } - mxf_metadata_preface_reset (&demux->preface); + demux->preface = NULL; - if (demux->identification) { - for (i = 0; i < demux->identification->len; i++) - mxf_metadata_identification_reset (&g_array_index (demux->identification, - MXFMetadataIdentification, i)); - g_array_free (demux->identification, TRUE); - demux->identification = NULL; - } - - mxf_metadata_content_storage_reset (&demux->content_storage); - - if (demux->essence_container_data) { - for (i = 0; i < demux->essence_container_data->len; i++) - mxf_metadata_essence_container_data_reset (&g_array_index - (demux->essence_container_data, MXFMetadataEssenceContainerData, i)); - g_array_free (demux->essence_container_data, TRUE); - demux->essence_container_data = NULL; - } - - if (demux->material_package) { - for (i = 0; i < demux->material_package->len; i++) - mxf_metadata_generic_package_reset (&g_array_index - (demux->material_package, MXFMetadataGenericPackage, i)); - g_array_free (demux->material_package, TRUE); - demux->material_package = NULL; - } - - if (demux->source_package) { - for (i = 0; i < demux->source_package->len; i++) - mxf_metadata_generic_package_reset (&g_array_index (demux->source_package, - MXFMetadataGenericPackage, i)); - g_array_free (demux->source_package, TRUE); - demux->source_package = NULL; - } - - if (demux->package) { - g_ptr_array_free (demux->package, TRUE); - demux->package = NULL; - } - - if (demux->track) { - for (i = 0; i < demux->track->len; i++) - mxf_metadata_track_reset (&g_array_index (demux->track, - MXFMetadataTrack, i)); - g_array_free (demux->track, TRUE); - demux->track = NULL; - } - - if (demux->sequence) { - for (i = 0; i < demux->sequence->len; i++) - mxf_metadata_sequence_reset (&g_array_index (demux->sequence, - MXFMetadataSequence, i)); - g_array_free (demux->sequence, TRUE); - demux->sequence = NULL; - } - - if (demux->structural_component) { - for (i = 0; i < demux->structural_component->len; i++) - mxf_metadata_structural_component_reset (&g_array_index - (demux->structural_component, MXFMetadataStructuralComponent, i)); - g_array_free (demux->structural_component, TRUE); - demux->structural_component = NULL; - } - - if (demux->generic_descriptor) { - for (i = 0; i < demux->generic_descriptor->len; i++) - mxf_metadata_generic_descriptor_reset (&g_array_index - (demux->generic_descriptor, MXFMetadataGenericDescriptor, i)); - g_array_free (demux->generic_descriptor, TRUE); - demux->generic_descriptor = NULL; - } - - if (demux->file_descriptor) { - for (i = 0; i < demux->file_descriptor->len; i++) - mxf_metadata_file_descriptor_reset (&g_array_index - (demux->file_descriptor, MXFMetadataFileDescriptor, i)); - g_array_free (demux->file_descriptor, TRUE); - demux->file_descriptor = NULL; - } - - if (demux->multiple_descriptor) { - for (i = 0; i < demux->multiple_descriptor->len; i++) - mxf_metadata_multiple_descriptor_reset (&g_array_index - (demux->multiple_descriptor, MXFMetadataMultipleDescriptor, i)); - g_array_free (demux->multiple_descriptor, TRUE); - demux->multiple_descriptor = NULL; - } - - if (demux->generic_data_essence_descriptor) { - for (i = 0; i < demux->generic_data_essence_descriptor->len; i++) - mxf_metadata_generic_data_essence_descriptor_reset (&g_array_index - (demux->generic_data_essence_descriptor, - MXFMetadataGenericDataEssenceDescriptor, i)); - g_array_free (demux->generic_data_essence_descriptor, TRUE); - demux->generic_data_essence_descriptor = NULL; - } - - if (demux->generic_picture_essence_descriptor) { - for (i = 0; i < demux->generic_picture_essence_descriptor->len; i++) - mxf_metadata_generic_picture_essence_descriptor_reset (&g_array_index - (demux->generic_picture_essence_descriptor, - MXFMetadataGenericPictureEssenceDescriptor, i)); - g_array_free (demux->generic_picture_essence_descriptor, TRUE); - demux->generic_picture_essence_descriptor = NULL; - } - - if (demux->cdci_picture_essence_descriptor) { - for (i = 0; i < demux->cdci_picture_essence_descriptor->len; i++) - mxf_metadata_cdci_picture_essence_descriptor_reset (&g_array_index - (demux->cdci_picture_essence_descriptor, - MXFMetadataCDCIPictureEssenceDescriptor, i)); - g_array_free (demux->cdci_picture_essence_descriptor, TRUE); - demux->cdci_picture_essence_descriptor = NULL; - } - - if (demux->rgba_picture_essence_descriptor) { - for (i = 0; i < demux->rgba_picture_essence_descriptor->len; i++) - mxf_metadata_rgba_picture_essence_descriptor_reset (&g_array_index - (demux->rgba_picture_essence_descriptor, - MXFMetadataRGBAPictureEssenceDescriptor, i)); - g_array_free (demux->rgba_picture_essence_descriptor, TRUE); - demux->rgba_picture_essence_descriptor = NULL; - } + if (demux->metadata) { + guint i; - if (demux->mpeg_video_descriptor) { - for (i = 0; i < demux->mpeg_video_descriptor->len; i++) - mxf_metadata_mpeg_video_descriptor_reset (&g_array_index - (demux->mpeg_video_descriptor, MXFMetadataMPEGVideoDescriptor, i)); - g_array_free (demux->mpeg_video_descriptor, TRUE); - demux->mpeg_video_descriptor = NULL; - } + for (i = 0; i < demux->metadata->len; i++) { + GstMiniObject *o = g_ptr_array_index (demux->metadata, i); - if (demux->generic_sound_essence_descriptor) { - for (i = 0; i < demux->generic_sound_essence_descriptor->len; i++) - mxf_metadata_generic_sound_essence_descriptor_reset (&g_array_index - (demux->generic_sound_essence_descriptor, - MXFMetadataGenericSoundEssenceDescriptor, i)); - g_array_free (demux->generic_sound_essence_descriptor, TRUE); - demux->generic_sound_essence_descriptor = NULL; - } - - if (demux->wave_audio_essence_descriptor) { - for (i = 0; i < demux->wave_audio_essence_descriptor->len; i++) - mxf_metadata_wave_audio_essence_descriptor_reset (&g_array_index - (demux->wave_audio_essence_descriptor, - MXFMetadataWaveAudioEssenceDescriptor, i)); - g_array_free (demux->wave_audio_essence_descriptor, TRUE); - demux->wave_audio_essence_descriptor = NULL; - } - - if (demux->aes3_audio_essence_descriptor) { - for (i = 0; i < demux->aes3_audio_essence_descriptor->len; i++) - mxf_metadata_aes3_audio_essence_descriptor_reset (&g_array_index - (demux->aes3_audio_essence_descriptor, - MXFMetadataAES3AudioEssenceDescriptor, i)); - g_array_free (demux->aes3_audio_essence_descriptor, TRUE); - demux->aes3_audio_essence_descriptor = NULL; - } - - if (demux->descriptor) { - g_ptr_array_free (demux->descriptor, TRUE); - demux->descriptor = NULL; - } - - if (demux->locator) { - for (i = 0; i < demux->locator->len; i++) - mxf_metadata_locator_reset (&g_array_index (demux->locator, - MXFMetadataLocator, i)); - g_array_free (demux->locator, TRUE); - demux->locator = NULL; + if (o) + gst_mini_object_unref (o); + } + g_ptr_array_free (demux->metadata, TRUE); + demux->metadata = NULL; } } @@ -594,1072 +435,35 @@ gst_mxf_demux_handle_primer_pack (GstMXFDemux * demux, const MXFUL * key, } static GstFlowReturn -gst_mxf_demux_handle_metadata_preface (GstMXFDemux * demux, - const MXFUL * key, GstBuffer * buffer) -{ - MXFMetadataPreface preface; - - GST_DEBUG_OBJECT (demux, - "Handling metadata preface of size %u" - " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset); - - if (!mxf_metadata_preface_parse (key, &preface, &demux->primer, - GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) { - GST_ERROR_OBJECT (demux, "Parsing metadata preface failed"); - return GST_FLOW_ERROR; - } - - if (mxf_timestamp_is_unknown (&demux->preface.last_modified_date) - || (!mxf_timestamp_is_unknown (&preface.last_modified_date) - && mxf_timestamp_compare (&demux->preface.last_modified_date, - &preface.last_modified_date) < 0)) { - GST_DEBUG_OBJECT (demux, - "Timestamp of new preface is newer than old, updating metadata"); - gst_mxf_demux_reset_metadata (demux); - memcpy (&demux->preface, &preface, sizeof (MXFMetadataPreface)); - } else { - GST_DEBUG_OBJECT (demux, "Preface is older than already parsed preface"); - } - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_mxf_demux_handle_metadata_identification (GstMXFDemux * demux, - const MXFUL * key, GstBuffer * buffer) -{ - MXFMetadataIdentification identification; - - GST_DEBUG_OBJECT (demux, - "Handling metadata identification of size %u" - " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset); - - if (!mxf_metadata_identification_parse (key, &identification, - &demux->primer, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) { - GST_ERROR_OBJECT (demux, "Parsing metadata identification failed"); - return GST_FLOW_ERROR; - } - - if (!demux->identification) - demux->identification = - g_array_new (FALSE, FALSE, sizeof (MXFMetadataIdentification)); - - g_array_append_val (demux->identification, identification); - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_mxf_demux_handle_metadata_content_storage (GstMXFDemux * demux, - const MXFUL * key, GstBuffer * buffer) -{ - GST_DEBUG_OBJECT (demux, - "Handling metadata content storage of size %u" - " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset); - - if (!mxf_metadata_content_storage_parse (key, - &demux->content_storage, &demux->primer, GST_BUFFER_DATA (buffer), - GST_BUFFER_SIZE (buffer))) { - GST_ERROR_OBJECT (demux, "Parsing metadata content storage failed"); - return GST_FLOW_ERROR; - } - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_mxf_demux_handle_metadata_essence_container_data (GstMXFDemux * - demux, const MXFUL * key, GstBuffer * buffer) -{ - MXFMetadataEssenceContainerData essence_container_data; - - GST_DEBUG_OBJECT (demux, - "Handling metadata essence container data of size %u" - " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset); - - if (!mxf_metadata_essence_container_data_parse (key, - &essence_container_data, &demux->primer, GST_BUFFER_DATA (buffer), - GST_BUFFER_SIZE (buffer))) { - GST_ERROR_OBJECT (demux, "Parsing metadata essence container data failed"); - return GST_FLOW_ERROR; - } - - if (!demux->essence_container_data) - demux->essence_container_data = - g_array_new (FALSE, FALSE, sizeof (MXFMetadataEssenceContainerData)); - - g_array_append_val (demux->essence_container_data, essence_container_data); - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_mxf_demux_handle_metadata_material_package (GstMXFDemux * demux, - const MXFUL * key, GstBuffer * buffer) -{ - MXFMetadataGenericPackage material_package; - - GST_DEBUG_OBJECT (demux, - "Handling metadata material package of size %u" - " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset); - - if (!mxf_metadata_generic_package_parse (key, &material_package, - &demux->primer, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) { - GST_ERROR_OBJECT (demux, "Parsing metadata material package failed"); - return GST_FLOW_ERROR; - } - - if (!demux->material_package) - demux->material_package = - g_array_new (FALSE, FALSE, sizeof (MXFMetadataMaterialPackage)); - - g_array_append_val (demux->material_package, material_package); - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_mxf_demux_handle_metadata_source_package (GstMXFDemux * demux, - const MXFUL * key, GstBuffer * buffer) -{ - MXFMetadataGenericPackage source_package; - - GST_DEBUG_OBJECT (demux, - "Handling metadata source package of size %u" - " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset); - - if (!mxf_metadata_generic_package_parse (key, &source_package, - &demux->primer, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) { - GST_ERROR_OBJECT (demux, "Parsing metadata source package failed"); - return GST_FLOW_ERROR; - } - - if (!demux->source_package) - demux->source_package = - g_array_new (FALSE, FALSE, sizeof (MXFMetadataSourcePackage)); - - g_array_append_val (demux->source_package, source_package); - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_mxf_demux_handle_metadata_track (GstMXFDemux * demux, - const MXFUL * key, guint16 type, GstBuffer * buffer) -{ - MXFMetadataTrack track; - - GST_DEBUG_OBJECT (demux, - "Handling metadata track with type 0x%04x of size %u" - " at offset %" G_GUINT64_FORMAT, type, GST_BUFFER_SIZE (buffer), - demux->offset); - - if (!mxf_metadata_track_parse (key, &track, &demux->primer, - type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) { - GST_ERROR_OBJECT (demux, "Parsing metadata track failed"); - return GST_FLOW_ERROR; - } - - if (!demux->track) - demux->track = g_array_new (FALSE, FALSE, sizeof (MXFMetadataTrack)); - - g_array_append_val (demux->track, track); - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_mxf_demux_handle_metadata_sequence (GstMXFDemux * demux, - const MXFUL * key, GstBuffer * buffer) -{ - MXFMetadataSequence sequence; - - GST_DEBUG_OBJECT (demux, - "Handling metadata sequence of size %u" - " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset); - - if (!mxf_metadata_sequence_parse (key, &sequence, - &demux->primer, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) { - GST_ERROR_OBJECT (demux, "Parsing metadata sequence failed"); - return GST_FLOW_ERROR; - } - - if (!demux->sequence) - demux->sequence = g_array_new (FALSE, FALSE, sizeof (MXFMetadataSequence)); - - g_array_append_val (demux->sequence, sequence); - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_mxf_demux_handle_metadata_structural_component (GstMXFDemux * demux, - const MXFUL * key, guint16 type, GstBuffer * buffer) -{ - MXFMetadataStructuralComponent component; - - GST_DEBUG_OBJECT (demux, - "Handling metadata structural component of size %u" - " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset); - - if (!mxf_metadata_structural_component_parse (key, &component, - &demux->primer, type, GST_BUFFER_DATA (buffer), - GST_BUFFER_SIZE (buffer))) { - GST_ERROR_OBJECT (demux, "Parsing metadata structural component failed"); - return GST_FLOW_ERROR; - } - - if (!demux->structural_component) - demux->structural_component = - g_array_new (FALSE, FALSE, sizeof (MXFMetadataStructuralComponent)); - - g_array_append_val (demux->structural_component, component); - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_mxf_demux_handle_metadata_file_descriptor (GstMXFDemux * demux, - const MXFUL * key, guint16 type, GstBuffer * buffer) -{ - MXFMetadataFileDescriptor descriptor; - - memset (&descriptor, 0, sizeof (descriptor)); - - GST_DEBUG_OBJECT (demux, - "Handling metadata file descriptor of size %u" - " at offset %" G_GUINT64_FORMAT " with type 0x%04d", - GST_BUFFER_SIZE (buffer), demux->offset, type); - - if (!mxf_metadata_descriptor_parse (key, - (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer, - type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), - (MXFMetadataDescriptorHandleTag) - mxf_metadata_file_descriptor_handle_tag, - (MXFMetadataDescriptorReset) mxf_metadata_file_descriptor_reset)) { - GST_ERROR_OBJECT (demux, "Parsing metadata file descriptor failed"); - return GST_FLOW_ERROR; - } - - if (!demux->file_descriptor) - demux->file_descriptor = - g_array_new (FALSE, FALSE, sizeof (MXFMetadataFileDescriptor)); - - g_array_append_val (demux->file_descriptor, descriptor); - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_mxf_demux_handle_metadata_multiple_descriptor (GstMXFDemux * demux, - const MXFUL * key, guint16 type, GstBuffer * buffer) -{ - MXFMetadataMultipleDescriptor descriptor; - - memset (&descriptor, 0, sizeof (descriptor)); - - GST_DEBUG_OBJECT (demux, - "Handling metadata multiple descriptor of size %u" - " at offset %" G_GUINT64_FORMAT " with type 0x%04d", - GST_BUFFER_SIZE (buffer), demux->offset, type); - - if (!mxf_metadata_descriptor_parse (key, - (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer, - type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), - (MXFMetadataDescriptorHandleTag) - mxf_metadata_multiple_descriptor_handle_tag, - (MXFMetadataDescriptorReset) mxf_metadata_multiple_descriptor_reset)) - { - GST_ERROR_OBJECT (demux, "Parsing metadata multiple descriptor failed"); - return GST_FLOW_ERROR; - } - - if (!demux->multiple_descriptor) - demux->multiple_descriptor = - g_array_new (FALSE, FALSE, sizeof (MXFMetadataMultipleDescriptor)); - - g_array_append_val (demux->multiple_descriptor, descriptor); - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_mxf_demux_handle_metadata_generic_data_essence_descriptor (GstMXFDemux * - demux, const MXFUL * key, guint16 type, GstBuffer * buffer) -{ - MXFMetadataGenericDataEssenceDescriptor descriptor; - - memset (&descriptor, 0, sizeof (descriptor)); - - GST_DEBUG_OBJECT (demux, - "Handling metadata generic data essence descriptor of size %u" - " at offset %" G_GUINT64_FORMAT " with type 0x%04d", - GST_BUFFER_SIZE (buffer), demux->offset, type); - - if (!mxf_metadata_descriptor_parse (key, - (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer, - type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), - (MXFMetadataDescriptorHandleTag) - mxf_metadata_generic_data_essence_descriptor_handle_tag, - (MXFMetadataDescriptorReset) - mxf_metadata_generic_data_essence_descriptor_reset)) { - GST_ERROR_OBJECT (demux, - "Parsing metadata generic data essence descriptor failed"); - return GST_FLOW_ERROR; - } - - if (!demux->generic_data_essence_descriptor) - demux->generic_data_essence_descriptor = - g_array_new (FALSE, FALSE, - sizeof (MXFMetadataGenericDataEssenceDescriptor)); - - g_array_append_val (demux->generic_data_essence_descriptor, descriptor); - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_mxf_demux_handle_metadata_generic_picture_essence_descriptor (GstMXFDemux * - demux, const MXFUL * key, guint16 type, GstBuffer * buffer) -{ - MXFMetadataGenericPictureEssenceDescriptor descriptor; - - memset (&descriptor, 0, sizeof (descriptor)); - - GST_DEBUG_OBJECT (demux, - "Handling metadata generic picture essence descriptor of size %u" - " at offset %" G_GUINT64_FORMAT " with type 0x%04d", - GST_BUFFER_SIZE (buffer), demux->offset, type); - - if (!mxf_metadata_descriptor_parse (key, - (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer, - type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), - (MXFMetadataDescriptorHandleTag) - mxf_metadata_generic_picture_essence_descriptor_handle_tag, - (MXFMetadataDescriptorReset) - mxf_metadata_generic_picture_essence_descriptor_reset)) { - GST_ERROR_OBJECT (demux, - "Parsing metadata generic picture essence descriptor failed"); - return GST_FLOW_ERROR; - } - - if (!demux->generic_picture_essence_descriptor) - demux->generic_picture_essence_descriptor = - g_array_new (FALSE, FALSE, - sizeof (MXFMetadataGenericPictureEssenceDescriptor)); - - g_array_append_val (demux->generic_picture_essence_descriptor, descriptor); - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_mxf_demux_handle_metadata_cdci_picture_essence_descriptor (GstMXFDemux * - demux, const MXFUL * key, guint16 type, GstBuffer * buffer) -{ - MXFMetadataCDCIPictureEssenceDescriptor descriptor; - - memset (&descriptor, 0, sizeof (descriptor)); - - GST_DEBUG_OBJECT (demux, - "Handling metadata CDCI picture essence descriptor of size %u" - " at offset %" G_GUINT64_FORMAT " with type 0x%04d", - GST_BUFFER_SIZE (buffer), demux->offset, type); - - if (!mxf_metadata_descriptor_parse (key, - (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer, - type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), - (MXFMetadataDescriptorHandleTag) - mxf_metadata_cdci_picture_essence_descriptor_handle_tag, - (MXFMetadataDescriptorReset) - mxf_metadata_cdci_picture_essence_descriptor_reset)) { - GST_ERROR_OBJECT (demux, - "Parsing metadata CDCI picture essence descriptor failed"); - return GST_FLOW_ERROR; - } - - if (!demux->cdci_picture_essence_descriptor) - demux->cdci_picture_essence_descriptor = - g_array_new (FALSE, FALSE, - sizeof (MXFMetadataCDCIPictureEssenceDescriptor)); - - g_array_append_val (demux->cdci_picture_essence_descriptor, descriptor); - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_mxf_demux_handle_metadata_rgba_picture_essence_descriptor (GstMXFDemux * - demux, const MXFUL * key, guint16 type, GstBuffer * buffer) -{ - MXFMetadataRGBAPictureEssenceDescriptor descriptor; - - memset (&descriptor, 0, sizeof (descriptor)); - - GST_DEBUG_OBJECT (demux, - "Handling metadata RGBA picture essence descriptor of size %u" - " at offset %" G_GUINT64_FORMAT " with type 0x%04d", - GST_BUFFER_SIZE (buffer), demux->offset, type); - - if (!mxf_metadata_descriptor_parse (key, - (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer, - type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), - (MXFMetadataDescriptorHandleTag) - mxf_metadata_rgba_picture_essence_descriptor_handle_tag, - (MXFMetadataDescriptorReset) - mxf_metadata_rgba_picture_essence_descriptor_reset)) { - GST_ERROR_OBJECT (demux, - "Parsing metadata RGBA picture essence descriptor failed"); - return GST_FLOW_ERROR; - } - - if (!demux->rgba_picture_essence_descriptor) - demux->rgba_picture_essence_descriptor = - g_array_new (FALSE, FALSE, - sizeof (MXFMetadataRGBAPictureEssenceDescriptor)); - - g_array_append_val (demux->rgba_picture_essence_descriptor, descriptor); - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_mxf_demux_handle_metadata_mpeg_video_descriptor (GstMXFDemux * demux, - const MXFUL * key, guint16 type, GstBuffer * buffer) -{ - MXFMetadataMPEGVideoDescriptor descriptor; - - memset (&descriptor, 0, sizeof (descriptor)); - - GST_DEBUG_OBJECT (demux, - "Handling metadata MPEG video descriptor of size %u" - " at offset %" G_GUINT64_FORMAT " with type 0x%04d", - GST_BUFFER_SIZE (buffer), demux->offset, type); - - if (!mxf_metadata_descriptor_parse (key, - (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer, - type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), - (MXFMetadataDescriptorHandleTag) - mxf_metadata_mpeg_video_descriptor_handle_tag, - (MXFMetadataDescriptorReset) - mxf_metadata_mpeg_video_descriptor_reset)) { - GST_ERROR_OBJECT (demux, "Parsing metadata MPEG video descriptor failed"); - return GST_FLOW_ERROR; - } - - if (!demux->mpeg_video_descriptor) - demux->mpeg_video_descriptor = - g_array_new (FALSE, FALSE, sizeof (MXFMetadataMPEGVideoDescriptor)); - - g_array_append_val (demux->mpeg_video_descriptor, descriptor); - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_mxf_demux_handle_metadata_generic_sound_essence_descriptor (GstMXFDemux * - demux, const MXFUL * key, guint16 type, GstBuffer * buffer) -{ - MXFMetadataGenericSoundEssenceDescriptor descriptor; - - memset (&descriptor, 0, sizeof (descriptor)); - - GST_DEBUG_OBJECT (demux, - "Handling metadata generic sound essence descriptor of size %u" - " at offset %" G_GUINT64_FORMAT " with type 0x%04d", - GST_BUFFER_SIZE (buffer), demux->offset, type); - - if (!mxf_metadata_descriptor_parse (key, - (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer, - type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), - (MXFMetadataDescriptorHandleTag) - mxf_metadata_generic_sound_essence_descriptor_handle_tag, - (MXFMetadataDescriptorReset) - mxf_metadata_generic_sound_essence_descriptor_reset)) { - GST_ERROR_OBJECT (demux, - "Parsing metadata generic sound essence descriptor failed"); - return GST_FLOW_ERROR; - } - - if (!demux->generic_sound_essence_descriptor) - demux->generic_sound_essence_descriptor = - g_array_new (FALSE, FALSE, - sizeof (MXFMetadataGenericSoundEssenceDescriptor)); - - g_array_append_val (demux->generic_sound_essence_descriptor, descriptor); - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_mxf_demux_handle_metadata_wave_audio_essence_descriptor (GstMXFDemux * - demux, const MXFUL * key, guint16 type, GstBuffer * buffer) -{ - MXFMetadataWaveAudioEssenceDescriptor descriptor; - - memset (&descriptor, 0, sizeof (descriptor)); - - GST_DEBUG_OBJECT (demux, - "Handling metadata wave sound essence descriptor of size %u" - " at offset %" G_GUINT64_FORMAT " with type 0x%04d", - GST_BUFFER_SIZE (buffer), demux->offset, type); - - if (!mxf_metadata_descriptor_parse (key, - (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer, - type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), - (MXFMetadataDescriptorHandleTag) - mxf_metadata_wave_audio_essence_descriptor_handle_tag, - (MXFMetadataDescriptorReset) - mxf_metadata_wave_audio_essence_descriptor_reset)) { - GST_ERROR_OBJECT (demux, - "Parsing metadata wave sound essence descriptor failed"); - return GST_FLOW_ERROR; - } - - if (!demux->wave_audio_essence_descriptor) - demux->wave_audio_essence_descriptor = - g_array_new (FALSE, FALSE, - sizeof (MXFMetadataWaveAudioEssenceDescriptor)); - - g_array_append_val (demux->wave_audio_essence_descriptor, descriptor); - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_mxf_demux_handle_metadata_aes3_audio_essence_descriptor (GstMXFDemux * - demux, const MXFUL * key, guint16 type, GstBuffer * buffer) -{ - MXFMetadataAES3AudioEssenceDescriptor descriptor; - - memset (&descriptor, 0, sizeof (descriptor)); - - GST_DEBUG_OBJECT (demux, - "Handling metadata AES3 audio essence descriptor of size %u" - " at offset %" G_GUINT64_FORMAT " with type 0x%04d", - GST_BUFFER_SIZE (buffer), demux->offset, type); - - if (!mxf_metadata_descriptor_parse (key, - (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer, - type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), - (MXFMetadataDescriptorHandleTag) - mxf_metadata_aes3_audio_essence_descriptor_handle_tag, - (MXFMetadataDescriptorReset) - mxf_metadata_aes3_audio_essence_descriptor_reset)) { - GST_ERROR_OBJECT (demux, - "Parsing metadata AES3 audio essence descriptor failed"); - return GST_FLOW_ERROR; - } - - if (!demux->aes3_audio_essence_descriptor) - demux->aes3_audio_essence_descriptor = - g_array_new (FALSE, FALSE, - sizeof (MXFMetadataAES3AudioEssenceDescriptor)); - - g_array_append_val (demux->aes3_audio_essence_descriptor, descriptor); - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_mxf_demux_handle_metadata_locator (GstMXFDemux * demux, - const MXFUL * key, guint16 type, GstBuffer * buffer) -{ - MXFMetadataLocator locator; - - GST_DEBUG_OBJECT (demux, - "Handling metadata locator of size %u" - " at offset %" G_GUINT64_FORMAT " with type 0x%04d", - GST_BUFFER_SIZE (buffer), demux->offset, type); - - if (!mxf_metadata_locator_parse (key, &locator, &demux->primer, - type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) { - GST_ERROR_OBJECT (demux, "Parsing metadata locator failed"); - return GST_FLOW_ERROR; - } - - if (!demux->locator) - demux->locator = g_array_new (FALSE, FALSE, sizeof (MXFMetadataLocator)); - - g_array_append_val (demux->locator, locator); - - return GST_FLOW_OK; -} - -static GstFlowReturn gst_mxf_demux_handle_header_metadata_resolve_references (GstMXFDemux * demux) { - guint i, j, k; + guint i; GstFlowReturn ret = GST_FLOW_OK; GST_DEBUG_OBJECT (demux, "Resolve metadata references"); demux->update_metadata = FALSE; - /* Fill in demux->descriptor */ - demux->descriptor = g_ptr_array_new (); - -#define FILL_DESCRIPTOR_ARRAY(desc_array, TYPE) \ - G_STMT_START { \ - if (desc_array) { \ - for (i = 0; i < desc_array->len; i++) { \ - g_ptr_array_add (demux->descriptor, \ - &g_array_index (desc_array, TYPE, i)); \ - } \ - } \ - } G_STMT_END - - FILL_DESCRIPTOR_ARRAY (demux->generic_descriptor, - MXFMetadataGenericDescriptor); - FILL_DESCRIPTOR_ARRAY (demux->file_descriptor, MXFMetadataFileDescriptor); - FILL_DESCRIPTOR_ARRAY (demux->generic_data_essence_descriptor, - MXFMetadataGenericDataEssenceDescriptor); - FILL_DESCRIPTOR_ARRAY (demux->generic_picture_essence_descriptor, - MXFMetadataGenericPictureEssenceDescriptor); - FILL_DESCRIPTOR_ARRAY (demux->cdci_picture_essence_descriptor, - MXFMetadataCDCIPictureEssenceDescriptor); - FILL_DESCRIPTOR_ARRAY (demux->rgba_picture_essence_descriptor, - MXFMetadataRGBAPictureEssenceDescriptor); - FILL_DESCRIPTOR_ARRAY (demux->mpeg_video_descriptor, - MXFMetadataMPEGVideoDescriptor); - FILL_DESCRIPTOR_ARRAY (demux->generic_sound_essence_descriptor, - MXFMetadataGenericSoundEssenceDescriptor); - FILL_DESCRIPTOR_ARRAY (demux->wave_audio_essence_descriptor, - MXFMetadataWaveAudioEssenceDescriptor); - FILL_DESCRIPTOR_ARRAY (demux->aes3_audio_essence_descriptor, - MXFMetadataAES3AudioEssenceDescriptor); - FILL_DESCRIPTOR_ARRAY (demux->multiple_descriptor, - MXFMetadataMultipleDescriptor); - -#undef FILL_DESCRIPTOR_ARRAY - - /* Fill in demux->package */ - demux->package = g_ptr_array_new (); - if (demux->material_package) { - for (i = 0; i < demux->material_package->len; i++) { - g_ptr_array_add (demux->package, &g_array_index (demux->material_package, - MXFMetadataGenericPackage, i)); - } - } - if (demux->source_package) { - for (i = 0; i < demux->source_package->len; i++) { - g_ptr_array_add (demux->package, &g_array_index (demux->source_package, - MXFMetadataGenericPackage, i)); - } - } - - /* Multiple descriptor */ - if (demux->multiple_descriptor && demux->descriptor) { - for (i = 0; i < demux->multiple_descriptor->len; i++) { - MXFMetadataMultipleDescriptor *d = - &g_array_index (demux->multiple_descriptor, - MXFMetadataMultipleDescriptor, i); - - d->sub_descriptors = - g_new0 (MXFMetadataGenericDescriptor *, d->n_sub_descriptors); - for (j = 0; j < d->n_sub_descriptors; j++) { - for (k = 0; k < demux->descriptor->len; k++) { - MXFMetadataGenericDescriptor *e = - g_ptr_array_index (demux->descriptor, k); - - if (mxf_ul_is_equal (&d->sub_descriptors_uids[j], &e->instance_uid)) { - d->sub_descriptors[j] = e; - break; - } - } - } - } - } - - /* See SMPTE 377M 8.4 */ - - /* Preface */ - if (demux->package) { - for (i = 0; i < demux->package->len; i++) { - MXFMetadataGenericPackage *package = - g_ptr_array_index (demux->package, i); - - if (mxf_ul_is_equal (&demux->preface.primary_package_uid, - &package->instance_uid)) { - demux->preface.primary_package = package; - break; - } - } - } - - demux->preface.identifications = - g_new0 (MXFMetadataIdentification *, demux->preface.n_identifications); - if (demux->identification) { - for (i = 0; i < demux->identification->len; i++) { - MXFMetadataIdentification *identification = - &g_array_index (demux->identification, - MXFMetadataIdentification, i); - - for (j = 0; j < demux->preface.n_identifications; j++) { - if (mxf_ul_is_equal (&demux->preface.identifications_uids[j], - &identification->instance_uid)) { - demux->preface.identifications[j] = identification; - break; - } - } - } - } - - if (!mxf_ul_is_equal (&demux->preface.content_storage_uid, - &demux->content_storage.instance_uid)) { - GST_ERROR_OBJECT (demux, - "Preface content storage UID not equal to actual content storage instance uid"); - ret = GST_FLOW_ERROR; - goto error; - } - demux->preface.content_storage = &demux->content_storage; - - /* Content storage */ - demux->content_storage.packages = - g_new0 (MXFMetadataGenericPackage *, demux->content_storage.n_packages); - if (demux->package) { - for (i = 0; i < demux->package->len; i++) { - MXFMetadataGenericPackage *package = - g_ptr_array_index (demux->package, i); - - for (j = 0; j < demux->content_storage.n_packages; j++) { - if (mxf_ul_is_equal (&demux->content_storage.packages_uids[j], - &package->instance_uid)) { - demux->content_storage.packages[j] = package; - break; - } - } - } - } - - demux->content_storage.essence_container_data = - g_new0 (MXFMetadataEssenceContainerData *, - demux->content_storage.n_essence_container_data); - if (demux->essence_container_data) { - for (i = 0; i < demux->essence_container_data->len; i++) { - MXFMetadataEssenceContainerData *data = - &g_array_index (demux->essence_container_data, - MXFMetadataEssenceContainerData, i); - - for (j = 0; j < demux->content_storage.n_essence_container_data; j++) { - if (mxf_ul_is_equal (&demux-> - content_storage.essence_container_data_uids[j], - &data->instance_uid)) { - demux->content_storage.essence_container_data[j] = data; - break; - } - } - } - } - - /* Essence container data */ - if (demux->package && demux->essence_container_data) { - for (i = 0; i < demux->package->len; i++) { - MXFMetadataGenericPackage *package = - g_ptr_array_index (demux->package, i); - - for (j = 0; j < demux->essence_container_data->len; j++) { - MXFMetadataEssenceContainerData *data = - &g_array_index (demux->essence_container_data, - MXFMetadataEssenceContainerData, j); - - if (mxf_umid_is_equal (&data->linked_package_uid, - &package->package_uid)) { - data->linked_package = package; - break; - } - } - } - } - - /* Generic package */ - if (demux->package) { - for (i = 0; i < demux->package->len; i++) { - MXFMetadataGenericPackage *package = - g_ptr_array_index (demux->package, i); - - package->tracks = g_new0 (MXFMetadataTrack *, package->n_tracks); - if (demux->track) { - for (j = 0; j < package->n_tracks; j++) { - for (k = 0; k < demux->track->len; k++) { - MXFMetadataTrack *track = - &g_array_index (demux->track, MXFMetadataTrack, k); - - if (mxf_ul_is_equal (&package->tracks_uids[j], - &track->instance_uid)) { - package->tracks[j] = track; - break; - } - } - } - } - - /* Resolve descriptors */ - if (package->n_descriptors > 0 && demux->descriptor) { - MXFMetadataGenericDescriptor *d = NULL; - - for (j = 0; j < demux->descriptor->len; j++) { - MXFMetadataGenericDescriptor *descriptor = - g_ptr_array_index (demux->descriptor, j); - - if (mxf_ul_is_equal (&package->descriptors_uid, - &descriptor->instance_uid)) { - d = descriptor; - break; - } - } - - if (d && d->type == MXF_METADATA_MULTIPLE_DESCRIPTOR) { - MXFMetadataMultipleDescriptor *e = - (MXFMetadataMultipleDescriptor *) d; - - package->n_descriptors = e->n_sub_descriptors; - package->descriptors = - g_new0 (MXFMetadataGenericDescriptor *, e->n_sub_descriptors); - - /* These are already resolved */ - for (j = 0; j < e->n_sub_descriptors; j++) - package->descriptors[j] = e->sub_descriptors[j]; - } else { - package->n_descriptors = 1; - package->descriptors = g_new0 (MXFMetadataGenericDescriptor *, 1); - package->descriptors[0] = d; - } - } - - if (package->tracks && package->descriptors) { - for (j = 0; j < package->n_tracks; j++) { - MXFMetadataTrack *track = package->tracks[j]; - guint i, n_descriptor = 0; - - if (!track) - continue; - - for (k = 0; k < package->n_descriptors; k++) { - MXFMetadataGenericDescriptor *d = package->descriptors[k]; - MXFMetadataFileDescriptor *e; - - if (!d || !d->is_file_descriptor) - continue; - - e = (MXFMetadataFileDescriptor *) d; - - if (e->linked_track_id == track->track_id || - e->linked_track_id == 0) - n_descriptor++; - } - - track->n_descriptor = n_descriptor; - track->descriptor = - g_new0 (MXFMetadataFileDescriptor *, n_descriptor); - i = 0; - - for (k = 0; k < package->n_descriptors; k++) { - MXFMetadataGenericDescriptor *d = package->descriptors[k]; - MXFMetadataFileDescriptor *e; - - if (!d || !d->is_file_descriptor) - continue; - - e = (MXFMetadataFileDescriptor *) d; - - if (e->linked_track_id == track->track_id || - (e->linked_track_id == 0 && n_descriptor == 1)) - track->descriptor[i++] = e; - } - } - } - } - } - - /* Tracks */ - if (demux->track && demux->sequence) { - for (i = 0; i < demux->track->len; i++) { - MXFMetadataTrack *track = - &g_array_index (demux->track, MXFMetadataTrack, i); - - for (j = 0; j < demux->sequence->len; j++) { - MXFMetadataSequence *sequence = - &g_array_index (demux->sequence, MXFMetadataSequence, - i); - - if (mxf_ul_is_equal (&track->sequence_uid, &sequence->instance_uid)) { - track->sequence = sequence; - break; - } - } - } - } - - /* Sequences */ - if (demux->sequence) { - for (i = 0; i < demux->sequence->len; i++) { - MXFMetadataSequence *sequence = - &g_array_index (demux->sequence, MXFMetadataSequence, i); - - sequence->structural_components = - g_new0 (MXFMetadataStructuralComponent *, - sequence->n_structural_components); - - if (demux->structural_component) { - for (j = 0; j < sequence->n_structural_components; j++) { - for (k = 0; k < demux->structural_component->len; k++) { - MXFMetadataStructuralComponent *component = - &g_array_index (demux->structural_component, - MXFMetadataStructuralComponent, k); - - if (mxf_ul_is_equal (&sequence->structural_components_uids[j], - &component->instance_uid)) { - sequence->structural_components[j] = component; - break; - } - } - } - } - } - } - - /* Source clips */ - if (demux->structural_component && demux->source_package) { - for (i = 0; i < demux->structural_component->len; i++) { - MXFMetadataStructuralComponent *component = - &g_array_index (demux->structural_component, - MXFMetadataStructuralComponent, i); - - if (component->type != MXF_METADATA_SOURCE_CLIP - && component->type != MXF_METADATA_DM_SOURCE_CLIP) - continue; - - for (j = 0; j < demux->source_package->len; j++) { - MXFMetadataGenericPackage *package = - &g_array_index (demux->source_package, MXFMetadataGenericPackage, - j); - - if (component->type == MXF_METADATA_SOURCE_CLIP && - mxf_umid_is_equal (&component->source_clip.source_package_id, - &package->package_uid)) { - component->source_clip.source_package = package; - break; - } else if (component->type == MXF_METADATA_DM_SOURCE_CLIP && - mxf_umid_is_equal (&component->dm_source_clip.source_package_id, - &package->package_uid)) { - component->dm_source_clip.source_package = package; - break; - } - } - } - } - - /* Generic descriptors */ - if (demux->descriptor) { - for (i = 0; i < demux->descriptor->len; i++) { - MXFMetadataGenericDescriptor *descriptor = - g_ptr_array_index (demux->descriptor, i); - - descriptor->locators = - g_new0 (MXFMetadataLocator *, descriptor->n_locators); - - if (demux->locator) { - for (j = 0; j < descriptor->n_locators; j++) { - for (k = 0; k < demux->locator->len; k++) { - MXFMetadataLocator *locator = - &g_array_index (demux->locator, MXFMetadataLocator, - k); - - if (mxf_ul_is_equal (&descriptor->locators_uids[j], - &locator->instance_uid)) { - descriptor->locators[j] = locator; - break; - } - } - } - } - } - } - - /* Mark packages as material, top-level source and source */ - if (demux->material_package) { - for (i = 0; i < demux->material_package->len; i++) { - MXFMetadataGenericPackage *package = - &g_array_index (demux->material_package, MXFMetadataGenericPackage, - i); - - package->type = MXF_METADATA_GENERIC_PACKAGE_MATERIAL; - - for (j = 0; j < package->n_tracks; j++) { - MXFMetadataTrack *track = package->tracks[j]; - MXFMetadataSequence *sequence; - - if (!track || !track->sequence) - continue; - - sequence = track->sequence; - - for (k = 0; k < sequence->n_structural_components; k++) { - MXFMetadataStructuralComponent *component = - sequence->structural_components[k]; - - if (!component || component->type != MXF_METADATA_SOURCE_CLIP - || !component->source_clip.source_package) - continue; - - component->source_clip.source_package->type = - MXF_METADATA_GENERIC_PACKAGE_TOP_LEVEL_SOURCE; - } - } - } + if (!demux->metadata) { + GST_ERROR_OBJECT (demux, "No metadata yet"); + return GST_FLOW_ERROR; } - /* Store, for every package, the number of timestamp, metadata, essence and other tracks - * and also store for every track the type */ - if (demux->package) { - for (i = 0; i < demux->package->len; i++) { - MXFMetadataGenericPackage *package = - g_ptr_array_index (demux->package, i); - - if (!package->tracks || package->n_tracks == 0) - continue; - - for (j = 0; j < package->n_tracks; j++) { - MXFMetadataTrack *track = package->tracks[j]; - MXFMetadataSequence *sequence; - MXFMetadataTrackType type = MXF_METADATA_TRACK_UNKNOWN; - - if (!track || !track->sequence) - continue; + /* Append NULL terminator */ + g_ptr_array_add (demux->metadata, NULL); - sequence = track->sequence; + for (i = 0; i < demux->metadata->len - 1; i++) { + MXFMetadataBase *m = + MXF_METADATA_BASE (g_ptr_array_index (demux->metadata, i)); + gboolean resolved; - if (mxf_ul_is_zero (&sequence->data_definition) - && sequence->structural_components) { - for (k = 0; k < sequence->n_structural_components; k++) { - MXFMetadataStructuralComponent *component = - sequence->structural_components[k]; - if (!component || mxf_ul_is_zero (&component->data_definition)) - continue; - - type = - mxf_metadata_track_identifier_parse - (&component->data_definition); - break; - } - } else { - type = - mxf_metadata_track_identifier_parse (&sequence->data_definition); - } + resolved = + mxf_metadata_resolve (m, (MXFMetadataBase **) demux->metadata->pdata); - track->type = type; - - if (type == MXF_METADATA_TRACK_UNKNOWN) - continue; - else if ((type & 0xf0) == 0x10) - package->n_timecode_tracks++; - else if ((type & 0xf0) == 0x20) - package->n_metadata_tracks++; - else if ((type & 0xf0) == 0x30) - package->n_essence_tracks++; - else if ((type & 0xf0) == 0x40) - package->n_other_tracks++; - } + /* Resolving can fail for anything but the preface, as the preface + * will resolve everything required */ + if (!resolved && MXF_IS_METADATA_PREFACE (m)) { + ret = GST_FLOW_ERROR; + goto error; } } @@ -1679,9 +483,14 @@ gst_mxf_demux_find_package (GstMXFDemux * demux, const MXFUMID * umid) MXFMetadataGenericPackage *ret = NULL; guint i; - if (demux->package) { - for (i = 0; i < demux->package->len; i++) { - MXFMetadataGenericPackage *p = g_ptr_array_index (demux->package, i); + if (demux->preface->content_storage + && demux->preface->content_storage->packages) { + for (i = 0; i < demux->preface->content_storage->n_packages; i++) { + MXFMetadataGenericPackage *p = + demux->preface->content_storage->packages[i]; + + if (!p) + continue; if (mxf_umid_is_equal (&p->package_uid, umid)) { ret = p; @@ -1697,6 +506,7 @@ static MXFMetadataGenericPackage * gst_mxf_demux_choose_package (GstMXFDemux * demux) { MXFMetadataGenericPackage *ret = NULL; + guint i; if (demux->requested_package_string) { MXFUMID umid; @@ -1715,33 +525,42 @@ gst_mxf_demux_choose_package (GstMXFDemux * demux) if (!mxf_umid_is_zero (&demux->current_package_uid)) ret = gst_mxf_demux_find_package (demux, &demux->current_package_uid); - if (ret && (ret->type == MXF_METADATA_GENERIC_PACKAGE_TOP_LEVEL_SOURCE - || ret->type == MXF_METADATA_GENERIC_PACKAGE_MATERIAL)) + if (ret && (MXF_IS_METADATA_MATERIAL_PACKAGE (ret) + || (MXF_IS_METADATA_SOURCE_PACKAGE (ret) + && MXF_METADATA_SOURCE_PACKAGE (ret)->top_level))) return ret; - else if (ret && ret->type == MXF_METADATA_GENERIC_PACKAGE_SOURCE) + else if (ret) GST_WARNING_OBJECT (demux, "Current package is not a material package or top-level source package, choosing the first best"); else if (!mxf_umid_is_zero (&demux->current_package_uid)) GST_WARNING_OBJECT (demux, "Current package not found, choosing the first best"); - if (demux->preface.primary_package) - ret = demux->preface.primary_package; - if (ret && (ret->type == MXF_METADATA_GENERIC_PACKAGE_TOP_LEVEL_SOURCE - || ret->type == MXF_METADATA_GENERIC_PACKAGE_MATERIAL)) + if (demux->preface->primary_package) + ret = demux->preface->primary_package; + if (ret && (MXF_IS_METADATA_MATERIAL_PACKAGE (ret) + || (MXF_IS_METADATA_SOURCE_PACKAGE (ret) + && MXF_METADATA_SOURCE_PACKAGE (ret)->top_level))) return ret; - if (!demux->material_package) { + for (i = 0; i < demux->preface->content_storage->n_packages; i++) { + if (demux->preface->content_storage->packages[i] && + MXF_IS_METADATA_MATERIAL_PACKAGE (demux->preface->content_storage-> + packages[i])) { + ret = + MXF_METADATA_GENERIC_PACKAGE (demux->preface->content_storage-> + packages[i]); + break; + } + } + + if (!ret) { GST_ERROR_OBJECT (demux, "No material package"); return NULL; - } else { - MXFMetadataGenericPackage *p = - (MXFMetadataGenericPackage *) demux->material_package->data; - memcpy (&demux->current_package_uid, &p->package_uid, 32); - - ret = gst_mxf_demux_find_package (demux, &demux->current_package_uid); } + memcpy (&demux->current_package_uid, &ret->package_uid, 32); + if (!ret) GST_ERROR_OBJECT (demux, "No suitable package found"); @@ -1774,67 +593,72 @@ gst_mxf_demux_handle_header_metadata_update_streams (GstMXFDemux * demux) demux->current_package = current_package; for (i = 0; i < current_package->n_tracks; i++) { - MXFMetadataTrack *track = current_package->tracks[i]; - MXFMetadataTrackType track_type = MXF_METADATA_TRACK_UNKNOWN; + MXFMetadataTimelineTrack *track = NULL; MXFMetadataSequence *sequence; MXFMetadataStructuralComponent *component = NULL; - MXFMetadataGenericPackage *source_package = NULL; - MXFMetadataTrack *source_track = NULL; + MXFMetadataSourcePackage *source_package = NULL; + MXFMetadataTimelineTrack *source_track = NULL; GstMXFDemuxPad *pad = NULL; GstCaps *caps = NULL; GST_DEBUG_OBJECT (demux, "Handling track %u", i); - if (!track) { + if (!current_package->tracks[i]) { GST_WARNING_OBJECT (demux, "Unresolved track"); continue; - } else if (!track->sequence) { + } + + if (!MXF_IS_METADATA_TIMELINE_TRACK (current_package->tracks[i])) { + GST_DEBUG_OBJECT (demux, "No timeline track"); + continue; + } + + track = MXF_METADATA_TIMELINE_TRACK (current_package->tracks[i]); + + if (!track->parent.sequence) { GST_WARNING_OBJECT (demux, "Track with no sequence"); continue; } - sequence = track->sequence; + sequence = track->parent.sequence; - if (current_package->type == MXF_METADATA_GENERIC_PACKAGE_TOP_LEVEL_SOURCE) { - source_package = current_package; + if (MXF_IS_METADATA_SOURCE_PACKAGE (current_package)) { + source_package = MXF_METADATA_SOURCE_PACKAGE (current_package); source_track = track; } - track_type = - mxf_metadata_track_identifier_parse (&sequence->data_definition); - /* TODO: handle multiple components, see SMPTE 377M page 37 */ if (sequence->structural_components && sequence->structural_components[0]) { component = sequence->structural_components[0]; - if (track_type == MXF_METADATA_TRACK_UNKNOWN) - track_type = - mxf_metadata_track_identifier_parse (&component->data_definition); + if (!source_package && MXF_IS_METADATA_SOURCE_CLIP (component)) { + MXFMetadataSourceClip *clip = MXF_METADATA_SOURCE_CLIP (component); - if (!source_package && component->type == MXF_METADATA_SOURCE_CLIP - && component->source_clip.source_package - && component->source_clip.source_package->type == - MXF_METADATA_GENERIC_PACKAGE_TOP_LEVEL_SOURCE - && component->source_clip.source_package->tracks) { - source_package = component->source_clip.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); - for (k = 0; k < source_package->n_tracks; k++) { - MXFMetadataTrack *tmp = source_package->tracks[k]; + source_package = clip->source_package; - if (tmp->track_id == component->source_clip.source_track_id) { - source_track = tmp; - break; + 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 (track_type && (track_type & 0xf0) != 0x30) { + if (track->parent.type && (track->parent.type & 0xf0) != 0x30) { GST_DEBUG_OBJECT (demux, "No essence track"); continue; } - if (!source_package || track_type == MXF_METADATA_TRACK_UNKNOWN + if (!source_package || track->parent.type == MXF_METADATA_TRACK_UNKNOWN || !source_track || !component) { GST_WARNING_OBJECT (demux, "No source package or track type for track found"); @@ -1846,7 +670,7 @@ gst_mxf_demux_handle_header_metadata_update_streams (GstMXFDemux * demux) continue; } - if (!source_track->descriptor) { + if (!source_track->parent.descriptor) { GST_WARNING_OBJECT (demux, "No descriptor found for track"); continue; } @@ -1856,7 +680,7 @@ gst_mxf_demux_handle_header_metadata_update_streams (GstMXFDemux * demux) for (j = 0; j < demux->src->len; j++) { GstMXFDemuxPad *tmp = g_ptr_array_index (demux->src, j); - if (tmp->track_id == track->track_id) { + if (tmp->track_id == track->parent.track_id) { pad = tmp; break; } @@ -1870,7 +694,7 @@ gst_mxf_demux_handle_header_metadata_update_streams (GstMXFDemux * demux) templ = gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (demux), "track_%u"); - pad_name = g_strdup_printf ("track_%u", track->track_id); + pad_name = g_strdup_printf ("track_%u", track->parent.track_id); g_assert (templ != NULL); @@ -1888,8 +712,7 @@ gst_mxf_demux_handle_header_metadata_update_streams (GstMXFDemux * demux) } /* Update pad */ - pad->track_id = track->track_id; - pad->track_type = track_type; + pad->track_id = track->parent.track_id; pad->material_package = current_package; pad->material_track = track; @@ -1903,64 +726,80 @@ gst_mxf_demux_handle_header_metadata_update_streams (GstMXFDemux * demux) g_free (pad->mapping_data); pad->mapping_data = NULL; - switch (track_type) { + switch (track->parent.type) { case MXF_METADATA_TRACK_PICTURE_ESSENCE: - if (mxf_is_mpeg_essence_track (source_track)) + if (mxf_is_mpeg_essence_track ((MXFMetadataTrack *) source_track)) caps = - mxf_mpeg_create_caps (source_package, source_track, - &pad->tags, &pad->handle_essence_element, &pad->mapping_data); - else if (mxf_is_dv_dif_essence_track (source_track)) + mxf_mpeg_create_caps (MXF_METADATA_GENERIC_PACKAGE + (source_package), (MXFMetadataTrack *) source_track, &pad->tags, + &pad->handle_essence_element, &pad->mapping_data); + else if (mxf_is_dv_dif_essence_track ((MXFMetadataTrack *) + source_track)) caps = - mxf_dv_dif_create_caps (source_package, source_track, - &pad->tags, &pad->handle_essence_element, &pad->mapping_data); - else if (mxf_is_jpeg2000_essence_track (source_track)) + mxf_dv_dif_create_caps (MXF_METADATA_GENERIC_PACKAGE + (source_package), (MXFMetadataTrack *) source_track, &pad->tags, + &pad->handle_essence_element, &pad->mapping_data); + else if (mxf_is_jpeg2000_essence_track ((MXFMetadataTrack *) + source_track)) caps = - mxf_jpeg2000_create_caps (source_package, source_track, - &pad->tags, &pad->handle_essence_element, &pad->mapping_data); - else if (mxf_is_d10_essence_track (source_track)) + mxf_jpeg2000_create_caps (MXF_METADATA_GENERIC_PACKAGE + (source_package), (MXFMetadataTrack *) source_track, &pad->tags, + &pad->handle_essence_element, &pad->mapping_data); + else if (mxf_is_d10_essence_track ((MXFMetadataTrack *) source_track)) caps = - mxf_d10_create_caps (source_package, source_track, - &pad->tags, &pad->handle_essence_element, &pad->mapping_data); - else if (mxf_is_up_essence_track (source_track)) + mxf_d10_create_caps (MXF_METADATA_GENERIC_PACKAGE + (source_package), (MXFMetadataTrack *) source_track, &pad->tags, + &pad->handle_essence_element, &pad->mapping_data); + else if (mxf_is_up_essence_track ((MXFMetadataTrack *) source_track)) caps = - mxf_up_create_caps (source_package, source_track, - &pad->tags, &pad->handle_essence_element, &pad->mapping_data); + mxf_up_create_caps (MXF_METADATA_GENERIC_PACKAGE (source_package), + (MXFMetadataTrack *) source_track, &pad->tags, + &pad->handle_essence_element, &pad->mapping_data); break; case MXF_METADATA_TRACK_SOUND_ESSENCE: - if (mxf_is_aes_bwf_essence_track (source_track)) + if (mxf_is_aes_bwf_essence_track ((MXFMetadataTrack *) source_track)) caps = - mxf_aes_bwf_create_caps (source_package, source_track, &pad->tags, + mxf_aes_bwf_create_caps (MXF_METADATA_GENERIC_PACKAGE + (source_package), (MXFMetadataTrack *) source_track, &pad->tags, &pad->handle_essence_element, &pad->mapping_data); - else if (mxf_is_dv_dif_essence_track (source_track)) + else if (mxf_is_dv_dif_essence_track ((MXFMetadataTrack *) + source_track)) caps = - mxf_dv_dif_create_caps (source_package, source_track, - &pad->tags, &pad->handle_essence_element, &pad->mapping_data); - else if (mxf_is_alaw_essence_track (source_track)) + mxf_dv_dif_create_caps (MXF_METADATA_GENERIC_PACKAGE + (source_package), (MXFMetadataTrack *) source_track, &pad->tags, + &pad->handle_essence_element, &pad->mapping_data); + else if (mxf_is_alaw_essence_track ((MXFMetadataTrack *) source_track)) caps = - mxf_alaw_create_caps (source_package, source_track, - &pad->tags, &pad->handle_essence_element, &pad->mapping_data); - else if (mxf_is_mpeg_essence_track (source_track)) + mxf_alaw_create_caps (MXF_METADATA_GENERIC_PACKAGE + (source_package), (MXFMetadataTrack *) source_track, &pad->tags, + &pad->handle_essence_element, &pad->mapping_data); + else if (mxf_is_mpeg_essence_track ((MXFMetadataTrack *) source_track)) caps = - mxf_mpeg_create_caps (source_package, source_track, - &pad->tags, &pad->handle_essence_element, &pad->mapping_data); - else if (mxf_is_d10_essence_track (source_track)) + mxf_mpeg_create_caps (MXF_METADATA_GENERIC_PACKAGE + (source_package), (MXFMetadataTrack *) source_track, &pad->tags, + &pad->handle_essence_element, &pad->mapping_data); + else if (mxf_is_d10_essence_track ((MXFMetadataTrack *) source_track)) caps = - mxf_d10_create_caps (source_package, source_track, - &pad->tags, &pad->handle_essence_element, &pad->mapping_data); + mxf_d10_create_caps (MXF_METADATA_GENERIC_PACKAGE + (source_package), (MXFMetadataTrack *) source_track, &pad->tags, + &pad->handle_essence_element, &pad->mapping_data); break; case MXF_METADATA_TRACK_DATA_ESSENCE: - if (mxf_is_dv_dif_essence_track (source_track)) + if (mxf_is_dv_dif_essence_track ((MXFMetadataTrack *) source_track)) caps = - mxf_dv_dif_create_caps (source_package, source_track, - &pad->tags, &pad->handle_essence_element, &pad->mapping_data); - else if (mxf_is_mpeg_essence_track (source_track)) + mxf_dv_dif_create_caps (MXF_METADATA_GENERIC_PACKAGE + (source_package), (MXFMetadataTrack *) source_track, &pad->tags, + &pad->handle_essence_element, &pad->mapping_data); + else if (mxf_is_mpeg_essence_track ((MXFMetadataTrack *) source_track)) caps = - mxf_mpeg_create_caps (source_package, source_track, - &pad->tags, &pad->handle_essence_element, &pad->mapping_data); - else if (mxf_is_d10_essence_track (source_track)) + mxf_mpeg_create_caps (MXF_METADATA_GENERIC_PACKAGE + (source_package), (MXFMetadataTrack *) source_track, &pad->tags, + &pad->handle_essence_element, &pad->mapping_data); + else if (mxf_is_d10_essence_track ((MXFMetadataTrack *) source_track)) caps = - mxf_d10_create_caps (source_package, source_track, - &pad->tags, &pad->handle_essence_element, &pad->mapping_data); + mxf_d10_create_caps (MXF_METADATA_GENERIC_PACKAGE + (source_package), (MXFMetadataTrack *) source_track, &pad->tags, + &pad->handle_essence_element, &pad->mapping_data); break; default: g_assert_not_reached (); @@ -2012,6 +851,7 @@ gst_mxf_demux_handle_metadata (GstMXFDemux * demux, const MXFUL * key, GstBuffer * buffer) { guint16 type; + MXFMetadata *metadata = NULL; GstFlowReturn ret = GST_FLOW_OK; type = GST_READ_UINT16_BE (key->u + 13); @@ -2031,109 +871,46 @@ gst_mxf_demux_handle_metadata (GstMXFDemux * demux, const MXFUL * key, return GST_FLOW_ERROR; } - if (type != MXF_METADATA_PREFACE && !demux->update_metadata) { + metadata = + mxf_metadata_new (type, &demux->primer, GST_BUFFER_DATA (buffer), + GST_BUFFER_SIZE (buffer)); + + if (metadata && !MXF_IS_METADATA_PREFACE (metadata) + && !demux->update_metadata) { GST_DEBUG_OBJECT (demux, "Skipping parsing of metadata because it's older than what we have"); + gst_mini_object_unref ((GstMiniObject *) metadata); return GST_FLOW_OK; } - switch (type) { - case MXF_METADATA_PREFACE: - ret = gst_mxf_demux_handle_metadata_preface (demux, key, buffer); - break; - case MXF_METADATA_IDENTIFICATION: - ret = gst_mxf_demux_handle_metadata_identification (demux, key, buffer); - break; - case MXF_METADATA_CONTENT_STORAGE: - ret = gst_mxf_demux_handle_metadata_content_storage (demux, key, buffer); - break; - case MXF_METADATA_ESSENCE_CONTAINER_DATA: - ret = - gst_mxf_demux_handle_metadata_essence_container_data (demux, - key, buffer); - break; - case MXF_METADATA_MATERIAL_PACKAGE: - ret = gst_mxf_demux_handle_metadata_material_package (demux, key, buffer); - break; - case MXF_METADATA_SOURCE_PACKAGE: - ret = gst_mxf_demux_handle_metadata_source_package (demux, key, buffer); - break; - case MXF_METADATA_TRACK: - case MXF_METADATA_EVENT_TRACK: - case MXF_METADATA_STATIC_TRACK: - ret = gst_mxf_demux_handle_metadata_track (demux, key, type, buffer); - break; - case MXF_METADATA_SEQUENCE: - ret = gst_mxf_demux_handle_metadata_sequence (demux, key, buffer); - break; - case MXF_METADATA_TIMECODE_COMPONENT: - case MXF_METADATA_SOURCE_CLIP: - case MXF_METADATA_DM_SEGMENT: - case MXF_METADATA_DM_SOURCE_CLIP: - ret = - gst_mxf_demux_handle_metadata_structural_component (demux, - key, type, buffer); - break; - case MXF_METADATA_FILE_DESCRIPTOR: - ret = - gst_mxf_demux_handle_metadata_file_descriptor (demux, - key, type, buffer); - break; - case MXF_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR: - ret = - gst_mxf_demux_handle_metadata_generic_data_essence_descriptor - (demux, key, type, buffer); - break; - case MXF_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR: - ret = - gst_mxf_demux_handle_metadata_generic_picture_essence_descriptor - (demux, key, type, buffer); - break; - case MXF_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR: - ret = - gst_mxf_demux_handle_metadata_cdci_picture_essence_descriptor (demux, - key, type, buffer); - break; - case MXF_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR: - ret = - gst_mxf_demux_handle_metadata_rgba_picture_essence_descriptor (demux, - key, type, buffer); - break; - case MXF_METADATA_MPEG_VIDEO_DESCRIPTOR: - ret = - gst_mxf_demux_handle_metadata_mpeg_video_descriptor (demux, - key, type, buffer); - break; - case MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR: - ret = - gst_mxf_demux_handle_metadata_generic_sound_essence_descriptor (demux, - key, type, buffer); - break; - case MXF_METADATA_MULTIPLE_DESCRIPTOR: - ret = - gst_mxf_demux_handle_metadata_multiple_descriptor (demux, - key, type, buffer); - break; - case MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR: - ret = - gst_mxf_demux_handle_metadata_wave_audio_essence_descriptor (demux, - key, type, buffer); - break; - case MXF_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR: - ret = - gst_mxf_demux_handle_metadata_aes3_audio_essence_descriptor (demux, - key, type, buffer); - break; - case MXF_METADATA_NETWORK_LOCATOR: - case MXF_METADATA_TEXT_LOCATOR: - ret = gst_mxf_demux_handle_metadata_locator (demux, key, type, buffer); - break; - default: - GST_WARNING_OBJECT (demux, - "Unknown or unhandled metadata type 0x%04x", type); - break; + if (!metadata) { + GST_ERROR_OBJECT (demux, "Parsing metadata failed"); + return GST_FLOW_ERROR; + } + + if (MXF_IS_METADATA_PREFACE (metadata)) { + MXFMetadataPreface *preface = MXF_METADATA_PREFACE (metadata); + + if (!demux->preface + || (!mxf_timestamp_is_unknown (&preface->last_modified_date) + && mxf_timestamp_compare (&demux->preface->last_modified_date, + &preface->last_modified_date) < 0)) { + GST_DEBUG_OBJECT (demux, + "Timestamp of new preface is newer than old, updating metadata"); + gst_mxf_demux_reset_metadata (demux); + demux->preface = preface; + } else { + GST_DEBUG_OBJECT (demux, "Preface is older than already parsed preface"); + gst_mini_object_unref ((GstMiniObject *) metadata); + return GST_FLOW_OK; + } } + if (!demux->metadata) + demux->metadata = g_ptr_array_new (); + + g_ptr_array_add (demux->metadata, metadata); + return ret; } @@ -2231,18 +1008,19 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux, for (i = 0; i < demux->src->len; i++) { GstMXFDemuxPad *p = g_ptr_array_index (demux->src, i); + MXFMetadataContentStorage *content_storage = + demux->preface->content_storage; - if (p->source_track->track_number == track_number || - (p->source_track->track_number == 0 && + if (p->source_track->parent.track_number == track_number || + (p->source_track->parent.track_number == 0 && demux->src->len == 1 && demux->current_package->n_essence_tracks == 1)) { - if (demux->essence_container_data) { - for (j = 0; j < demux->essence_container_data->len; j++) { + if (content_storage->essence_container_data) { + for (j = 0; j < content_storage->n_essence_container_data; j++) { MXFMetadataEssenceContainerData *edata = - &g_array_index (demux->essence_container_data, - MXFMetadataEssenceContainerData, j); + content_storage->essence_container_data[j]; - if (p->source_package == edata->linked_package + if (edata && p->source_package == edata->linked_package && demux->partition.body_sid == edata->body_sid) { pad = p; break; @@ -2292,8 +1070,10 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux, if (pad->handle_essence_element) { /* Takes ownership of inbuf */ ret = - pad->handle_essence_element (key, inbuf, pad->caps, pad->source_package, - pad->source_track, pad->component, pad->mapping_data, &outbuf); + pad->handle_essence_element (key, inbuf, pad->caps, + (MXFMetadataGenericPackage *) pad->source_package, + (MXFMetadataTrack *) pad->source_track, pad->component, + pad->mapping_data, &outbuf); inbuf = NULL; } else { outbuf = inbuf; @@ -2316,14 +1096,14 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux, GST_DEBUG_OBJECT (demux, "Pushing buffer of size %u for track %u: timestamp %" GST_TIME_FORMAT " duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (outbuf), - pad->material_track->track_id, + pad->material_track->parent.track_id, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)), GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf))); ret = gst_pad_push (GST_PAD_CAST (pad), outbuf); ret = gst_mxf_demux_combine_flows (demux, pad, ret); } else { GST_DEBUG_OBJECT (demux, "Dropping buffer for track %u", - pad->material_track->track_id); + pad->material_track->parent.track_id); } return ret; @@ -2685,7 +1465,7 @@ gst_mxf_demux_handle_klv_packet (GstMXFDemux * demux, const MXFUL * key, GstFlowReturn ret = GST_FLOW_OK; if (demux->update_metadata - && !mxf_timestamp_is_unknown (&demux->preface.last_modified_date) + && demux->preface && !mxf_is_metadata (key) && !mxf_is_descriptive_metadata (key) && !mxf_is_fill (key)) { if ((ret = @@ -3112,10 +1892,10 @@ gst_mxf_demux_src_query (GstPad * pad, GstQuery * query) if (format != GST_FORMAT_TIME && format != GST_FORMAT_DEFAULT) goto error; - if (!mxfpad->material_track || !mxfpad->material_track->sequence) + if (!mxfpad->material_track || !mxfpad->material_track->parent.sequence) goto error; - duration = mxfpad->material_track->sequence->duration; + duration = mxfpad->material_track->parent.sequence->duration; if (format == GST_FORMAT_TIME) { if (mxfpad->material_track->edit_rate.n == 0 || mxfpad->material_track->edit_rate.d == 0) diff --git a/gst/mxf/mxfdemux.h b/gst/mxf/mxfdemux.h index 82b82c28..bb9d5933 100644 --- a/gst/mxf/mxfdemux.h +++ b/gst/mxf/mxfdemux.h @@ -23,7 +23,9 @@ #include <gst/gst.h> #include <gst/base/gstadapter.h> +#include "mxftypes.h" #include "mxfparse.h" +#include "mxfmetadata.h" G_BEGIN_DECLS #define GST_TYPE_MXF_DEMUX \ @@ -75,31 +77,9 @@ struct _GstMXFDemux gboolean pull_footer_metadata; gboolean metadata_resolved; - MXFMetadataPreface preface; - GArray *identification; - MXFMetadataContentStorage content_storage; - GArray *essence_container_data; - GArray *material_package; - GArray *source_package; - GPtrArray *package; - GArray *track; - GArray *sequence; - GArray *structural_component; - GArray *locator; - - GPtrArray *descriptor; - GArray *generic_descriptor; - GArray *file_descriptor; - GArray *generic_sound_essence_descriptor; - GArray *generic_picture_essence_descriptor; - GArray *generic_data_essence_descriptor; - GArray *cdci_picture_essence_descriptor; - GArray *rgba_picture_essence_descriptor; - GArray *mpeg_video_descriptor; - GArray *wave_audio_essence_descriptor; - GArray *aes3_audio_essence_descriptor; - GArray *multiple_descriptor; - + MXFMetadataPreface *preface; + GPtrArray *metadata; + MXFUMID current_package_uid; MXFMetadataGenericPackage *current_package; gchar *current_package_string; diff --git a/gst/mxf/mxfdv-dif.c b/gst/mxf/mxfdv-dif.c index 79512f46..25bd2a95 100644 --- a/gst/mxf/mxfdv-dif.c +++ b/gst/mxf/mxfdv-dif.c @@ -51,7 +51,12 @@ mxf_is_dv_dif_essence_track (const MXFMetadataTrack * track) for (i = 0; i < track->n_descriptor; i++) { MXFMetadataFileDescriptor *d = track->descriptor[i]; - MXFUL *key = &d->essence_container; + MXFUL *key; + + if (!d) + continue; + + key = &d->essence_container; /* SMPTE 383M 8 */ if (mxf_is_generic_container_essence_container_label (key) && key->u[12] == 0x02 && key->u[13] == 0x02) @@ -97,10 +102,11 @@ mxf_dv_dif_create_caps (MXFMetadataGenericPackage * package, } for (i = 0; i < track->n_descriptor; i++) { - if (((MXFMetadataGenericDescriptor *) track->descriptor[i])-> - is_file_descriptor - && ((MXFMetadataGenericDescriptor *) track->descriptor[i])->type != - MXF_METADATA_MULTIPLE_DESCRIPTOR) { + if (!track->descriptor[i]) + continue; + + if (MXF_IS_METADATA_FILE_DESCRIPTOR (track->descriptor[i]) && + !MXF_IS_METADATA_MULTIPLE_DESCRIPTOR (track->descriptor[i])) { f = track->descriptor[i]; } } @@ -131,3 +137,9 @@ mxf_dv_dif_create_caps (MXFMetadataGenericPackage * package, return caps; } + +void +mxf_dv_dif_init (void) +{ + +} diff --git a/gst/mxf/mxfdv-dif.h b/gst/mxf/mxfdv-dif.h index a4d39f08..2e59e5e8 100644 --- a/gst/mxf/mxfdv-dif.h +++ b/gst/mxf/mxfdv-dif.h @@ -33,4 +33,6 @@ gboolean mxf_is_dv_dif_essence_track (const MXFMetadataTrack *track); GstCaps * mxf_dv_dif_create_caps (MXFMetadataGenericPackage *package, MXFMetadataTrack *track, GstTagList **tags, MXFEssenceElementHandler *handler, gpointer *mapping_data); +void mxf_dv_dif_init (void); + #endif /* __MXF_DV_DIF_H__ */ diff --git a/gst/mxf/mxfjpeg2000.c b/gst/mxf/mxfjpeg2000.c index 7ccb4818..818f6b25 100644 --- a/gst/mxf/mxfjpeg2000.c +++ b/gst/mxf/mxfjpeg2000.c @@ -50,7 +50,12 @@ mxf_is_jpeg2000_essence_track (const MXFMetadataTrack * track) for (i = 0; i < track->n_descriptor; i++) { MXFMetadataFileDescriptor *d = track->descriptor[i]; - MXFUL *key = &d->essence_container; + MXFUL *key; + + if (!d) + continue; + + key = &d->essence_container; /* SMPTE 422M 5.4 */ if (mxf_is_generic_container_essence_container_label (key) && key->u[12] == 0x02 && key->u[13] == 0x0c && @@ -99,19 +104,16 @@ mxf_jpeg2000_create_caps (MXFMetadataGenericPackage * package, } for (i = 0; i < track->n_descriptor; i++) { - if (((MXFMetadataGenericDescriptor *) track->descriptor[i])->type == - MXF_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR || - ((MXFMetadataGenericDescriptor *) track->descriptor[i])->type == - MXF_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR || - ((MXFMetadataGenericDescriptor *) track->descriptor[i])->type == - MXF_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR) { + if (!track->descriptor[i]) + continue; + + if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track-> + descriptor[i])) { p = (MXFMetadataGenericPictureEssenceDescriptor *) track->descriptor[i]; f = track->descriptor[i]; break; - } else if (((MXFMetadataGenericDescriptor *) track->descriptor[i])-> - is_file_descriptor - && ((MXFMetadataGenericDescriptor *) track->descriptor[i])->type != - MXF_METADATA_MULTIPLE_DESCRIPTOR) { + } else if (MXF_IS_METADATA_FILE_DESCRIPTOR (track->descriptor[i]) && + !MXF_IS_METADATA_MULTIPLE_DESCRIPTOR (track->descriptor[i])) { f = track->descriptor[i]; } } @@ -122,13 +124,9 @@ mxf_jpeg2000_create_caps (MXFMetadataGenericPackage * package, } fourcc = GST_MAKE_FOURCC ('s', 'R', 'G', 'B'); - if (p - && ((MXFMetadataGenericDescriptor *) p)->type == - MXF_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR) { + if (p && MXF_IS_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (p)) { fourcc = GST_MAKE_FOURCC ('s', 'Y', 'U', 'V'); - } else if (p - && ((MXFMetadataGenericDescriptor *) p)->type == - MXF_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR) { + } else if (p && MXF_IS_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (p)) { MXFMetadataRGBAPictureEssenceDescriptor *r = (MXFMetadataRGBAPictureEssenceDescriptor *) p; gboolean rgb = TRUE; @@ -199,3 +197,8 @@ mxf_jpeg2000_create_caps (MXFMetadataGenericPackage * package, return caps; } + +void +mxf_jpeg2000_init (void) +{ +} diff --git a/gst/mxf/mxfjpeg2000.h b/gst/mxf/mxfjpeg2000.h index 784c19e8..d3cda750 100644 --- a/gst/mxf/mxfjpeg2000.h +++ b/gst/mxf/mxfjpeg2000.h @@ -33,4 +33,6 @@ gboolean mxf_is_jpeg2000_essence_track (const MXFMetadataTrack *track); GstCaps * mxf_jpeg2000_create_caps (MXFMetadataGenericPackage *package, MXFMetadataTrack *track, GstTagList **tags, MXFEssenceElementHandler *handler, gpointer *mapping_data); +void mxf_jpeg2000_init (void); + #endif /* __MXF_JPEG2000_H__ */ diff --git a/gst/mxf/mxfmetadata.c b/gst/mxf/mxfmetadata.c new file mode 100644 index 00000000..54df52de --- /dev/null +++ b/gst/mxf/mxfmetadata.c @@ -0,0 +1,3306 @@ +/* GStreamer + * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gst/gst.h> +#include <string.h> + +#include "mxfparse.h" +#include "mxfmetadata.h" + +GST_DEBUG_CATEGORY_EXTERN (mxf_debug); +#define GST_CAT_DEFAULT mxf_debug + +G_DEFINE_ABSTRACT_TYPE (MXFMetadataBase, mxf_metadata_base, + GST_TYPE_MINI_OBJECT); + +static void +mxf_metadata_base_finalize (GstMiniObject * object) +{ + MXFMetadataBase *self = MXF_METADATA_BASE (object); + + if (self->other_tags) { + g_hash_table_destroy (self->other_tags); + self->other_tags = NULL; + } + + GST_MINI_OBJECT_CLASS (mxf_metadata_base_parent_class)->finalize (object); +} + +static gboolean +mxf_metadata_base_handle_tag (MXFMetadataBase * self, MXFPrimerPack * primer, + guint16 tag, const guint8 * tag_data, guint tag_size) +{ + return (mxf_local_tag_add_to_hash_table (primer, tag, tag_data, tag_size, + &self->other_tags)); +} + +static gboolean +mxf_metadata_base_resolve (MXFMetadataBase * self, MXFMetadataBase ** metadata) +{ + return TRUE; +} + +static void +mxf_metadata_base_init (MXFMetadataBase * self) +{ + +} + +static void +mxf_metadata_base_class_init (MXFMetadataBaseClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + + miniobject_class->finalize = mxf_metadata_base_finalize; + klass->handle_tag = mxf_metadata_base_handle_tag; + klass->resolve = mxf_metadata_base_resolve; +} + +gboolean +mxf_metadata_parse (MXFMetadataBase * self, MXFPrimerPack * primer, + const guint8 * data, guint size) +{ + guint16 tag, tag_size; + const guint8 *tag_data; + + g_return_val_if_fail (MXF_IS_METADATA_BASE (self), FALSE); + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (primer != NULL, FALSE); + + while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) { + if (tag_size == 0 || tag == 0x0000) + goto next; + + if (!MXF_METADATA_BASE_GET_CLASS (self)->handle_tag (self, primer, tag, + tag_data, tag_size)) + return FALSE; + next: + data += 4 + tag_size; + size -= 4 + tag_size; + } + + return TRUE; +} + +gboolean +mxf_metadata_resolve (MXFMetadataBase * self, MXFMetadataBase ** metadata) +{ + MXFMetadataBaseClass *klass; + + g_return_val_if_fail (MXF_IS_METADATA_BASE (self), FALSE); + g_return_val_if_fail (metadata != NULL, FALSE); + + if (self->resolved) + return TRUE; + + self->resolved = TRUE; + + klass = MXF_METADATA_BASE_GET_CLASS (self); + + if (klass->resolve) + return klass->resolve (self, metadata); + + return TRUE; +} + +G_DEFINE_TYPE (MXFMetadata, mxf_metadata, MXF_TYPE_METADATA_BASE); + +static gboolean +mxf_metadata_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer, + guint16 tag, const guint8 * tag_data, guint tag_size) +{ + gchar str[48]; + MXFMetadata *self = MXF_METADATA (metadata); + gboolean ret = TRUE; + + switch (tag) { + case 0x3c0a: + if (tag_size != 16) + goto error; + memcpy (&self->parent.instance_uid, tag_data, 16); + GST_DEBUG (" instance uid = %s", + mxf_ul_to_string (&self->parent.instance_uid, str)); + break; + case 0x0102: + case 0x3c09: + if (tag_size != 16) + goto error; + memcpy (&self->parent.generation_uid, tag_data, 16); + GST_DEBUG (" generation uid = %s", + mxf_ul_to_string (&self->parent.generation_uid, str)); + break; + default: + ret = + MXF_METADATA_BASE_CLASS (mxf_metadata_parent_class)-> + handle_tag (metadata, primer, tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR ("Invalid metadata local tag 0x%04x of size %u", tag, tag_size); + + return FALSE; +} + +static void +mxf_metadata_class_init (MXFMetadataClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + + metadata_base_class->handle_tag = mxf_metadata_handle_tag; +} + +static void +mxf_metadata_init (MXFMetadata * self) +{ +} + +static GSList *_mxf_metadata_registry = NULL; + +typedef struct +{ + guint16 type_id; + GType type; +} _MXFMetadataType; + +void +mxf_metadata_init_types (void) +{ + _MXFMetadataType *l; + + g_return_if_fail (_mxf_metadata_registry == NULL); + +#define _add_type(TI, T) \ + l = g_slice_new (_MXFMetadataType); \ + l->type_id = TI; \ + l->type = T; \ + _mxf_metadata_registry = g_slist_prepend (_mxf_metadata_registry, l); + + /* SMPTE S377M 8.6 Table 14 */ + _add_type (0x012f, MXF_TYPE_METADATA_PREFACE); + _add_type (0x0130, MXF_TYPE_METADATA_IDENTIFICATION); + _add_type (0x0118, MXF_TYPE_METADATA_CONTENT_STORAGE); + _add_type (0x0123, MXF_TYPE_METADATA_ESSENCE_CONTAINER_DATA); + _add_type (0x0136, MXF_TYPE_METADATA_MATERIAL_PACKAGE); + _add_type (0x0137, MXF_TYPE_METADATA_SOURCE_PACKAGE); + _add_type (0x013b, MXF_TYPE_METADATA_TIMELINE_TRACK); + _add_type (0x0139, MXF_TYPE_METADATA_EVENT_TRACK); + _add_type (0x013a, MXF_TYPE_METADATA_STATIC_TRACK); + _add_type (0x010f, MXF_TYPE_METADATA_SEQUENCE); + _add_type (0x0111, MXF_TYPE_METADATA_SOURCE_CLIP); + _add_type (0x0114, MXF_TYPE_METADATA_TIMECODE_COMPONENT); + _add_type (0x0141, MXF_TYPE_METADATA_DM_SEGMENT); + _add_type (0x0145, MXF_TYPE_METADATA_DM_SOURCE_CLIP); + _add_type (0x0125, MXF_TYPE_METADATA_FILE_DESCRIPTOR); + _add_type (0x0127, MXF_TYPE_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR); + _add_type (0x0128, MXF_TYPE_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR); + _add_type (0x0129, MXF_TYPE_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR); + _add_type (0x0142, MXF_TYPE_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR); + _add_type (0x0143, MXF_TYPE_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR); + _add_type (0x0144, MXF_TYPE_METADATA_MULTIPLE_DESCRIPTOR); + _add_type (0x0132, MXF_TYPE_METADATA_NETWORK_LOCATOR); + _add_type (0x0133, MXF_TYPE_METADATA_TEXT_LOCATOR); + +#undef _add_type +} + +void +mxf_metadata_register (guint16 type_id, GType type) +{ + g_return_if_fail (g_type_is_a (type, MXF_TYPE_METADATA)); + g_return_if_fail (type_id != 0); + g_return_if_fail (_mxf_metadata_registry != NULL); + + { + GSList *l = _mxf_metadata_registry; + + for (; l; l = l->next) { + if (((_MXFMetadataType *) l->data)->type_id == type_id) { + return; + } + } + } + + { + _MXFMetadataType *l = g_slice_new (_MXFMetadataType); + l->type_id = type_id; + l->type = type; + _mxf_metadata_registry = g_slist_prepend (_mxf_metadata_registry, l); + } +} + +MXFMetadata * +mxf_metadata_new (guint16 type, MXFPrimerPack * primer, const guint8 * data, + guint size) +{ + GSList *l; + GType t = G_TYPE_INVALID; + MXFMetadata *ret = NULL; + + g_return_val_if_fail (type != 0, NULL); + g_return_val_if_fail (primer != NULL, NULL); + g_return_val_if_fail (_mxf_metadata_registry != NULL, NULL); + + for (l = _mxf_metadata_registry; l; l = l->next) { + _MXFMetadataType *data = l->data; + + if (data->type_id == type) { + t = data->type; + break; + } + } + + if (t == G_TYPE_INVALID) { + GST_WARNING + ("No handler for type 0x%04x found -- using generic metadata parser", + type); + t = MXF_TYPE_METADATA; + } + + ret = (MXFMetadata *) g_type_create_instance (t); + if (!mxf_metadata_parse (MXF_METADATA_BASE (ret), primer, data, size)) { + GST_ERROR ("Parsing metadata failed"); + gst_mini_object_unref ((GstMiniObject *) ret); + return NULL; + } + + ret->type = type; + return ret; +} + +G_DEFINE_TYPE (MXFMetadataPreface, mxf_metadata_preface, MXF_TYPE_METADATA); + +static void +mxf_metadata_preface_finalize (GstMiniObject * object) +{ + MXFMetadataPreface *self = MXF_METADATA_PREFACE (object); + + g_free (self->identifications_uids); + self->identifications_uids = NULL; + + g_free (self->identifications); + self->identifications = NULL; + + g_free (self->essence_containers); + self->essence_containers = NULL; + + g_free (self->dm_schemes); + self->dm_schemes = NULL; + + GST_MINI_OBJECT_CLASS (mxf_metadata_preface_parent_class)->finalize (object); +} + +static gboolean +mxf_metadata_preface_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataPreface *self = MXF_METADATA_PREFACE (metadata); + gchar str[48]; + gboolean ret = TRUE; + + switch (tag) { + case 0x3b02: + if (!mxf_timestamp_parse (&self->last_modified_date, tag_data, tag_size)) + goto error; + GST_DEBUG (" last modified date = %d/%u/%u %u:%u:%u.%u", + self->last_modified_date.year, self->last_modified_date.month, + self->last_modified_date.day, self->last_modified_date.hour, + self->last_modified_date.minute, + self->last_modified_date.second, + (self->last_modified_date.quarter_msecond * 1000) / 256); + break; + case 0x3b05: + if (tag_size != 2) + goto error; + self->version = GST_READ_UINT16_BE (tag_data); + GST_DEBUG (" version = %u.%u", (self->version >> 8), + (self->version & 0x0f)); + break; + case 0x3b07: + if (tag_size != 4) + goto error; + self->object_model_version = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" object model version = %u", self->object_model_version); + break; + case 0x3b08: + if (tag_size != 16) + goto error; + memcpy (&self->primary_package_uid, tag_data, 16); + GST_DEBUG (" primary package = %s", + mxf_ul_to_string (&self->primary_package_uid, str)); + break; + case 0x3b06:{ + guint32 len; + guint i; + + + if (tag_size < 8) + goto error; + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of identifications = %u", len); + if (len == 0) + return TRUE; + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + if (tag_size < 8 + len * 16) + goto error; + + self->n_identifications = len; + self->identifications_uids = g_new (MXFUL, len); + for (i = 0; i < len; i++) { + memcpy (&self->identifications_uids[i], tag_data + 8 + i * 16, 16); + GST_DEBUG (" identification %u = %s", i, + mxf_ul_to_string (&self->identifications_uids[i], str)); + } + break; + } + case 0x3b03: + if (tag_size != 16) + goto error; + memcpy (&self->content_storage_uid, tag_data, 16); + GST_DEBUG (" content storage = %s", + mxf_ul_to_string (&self->content_storage_uid, str)); + break; + case 0x3b09: + if (tag_size != 16) + goto error; + memcpy (&self->operational_pattern, tag_data, 16); + GST_DEBUG (" operational pattern = %s", + mxf_ul_to_string (&self->operational_pattern, str)); + break; + case 0x3b0a:{ + guint32 len; + guint i; + + + if (tag_size < 8) + goto error; + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of essence containers = %u", len); + if (len == 0) + return TRUE; + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + if (tag_size < 8 + len * 16) + goto error; + + self->n_essence_containers = len; + self->essence_containers = g_new (MXFUL, len); + for (i = 0; i < len; i++) { + memcpy (&self->essence_containers[i], tag_data + 8 + i * 16, 16); + GST_DEBUG (" essence container %u = %s", i, + mxf_ul_to_string (&self->essence_containers[i], str)); + } + break; + } + case 0x3b0b:{ + guint32 len; + guint i; + + + if (tag_size < 8) + goto error; + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of DM schemes = %u", len); + if (len == 0) + return TRUE; + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + if (tag_size < 8 + len * 16) + goto error; + + self->n_dm_schemes = len; + self->dm_schemes = g_new (MXFUL, len); + for (i = 0; i < len; i++) { + memcpy (&self->dm_schemes[i], tag_data + 8 + i * 16, 16); + GST_DEBUG (" DM schemes %u = %s", i, + mxf_ul_to_string (&self->dm_schemes[i], str)); + } + break; + } + default: + ret = + MXF_METADATA_BASE_CLASS (mxf_metadata_preface_parent_class)-> + handle_tag (metadata, primer, tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR ("Invalid preface local tag 0x%04x of size %u", tag, tag_size); + + return FALSE; +} + +static gboolean +mxf_metadata_preface_resolve (MXFMetadataBase * m, MXFMetadataBase ** metadata) +{ + MXFMetadataPreface *self = MXF_METADATA_PREFACE (m); + MXFMetadataBase **p = metadata, *current; + guint i; + + while (*p && (self->primary_package == NULL || self->content_storage == NULL)) { + current = *p; + + if (MXF_IS_METADATA_GENERIC_PACKAGE (current) && + mxf_ul_is_equal (&self->primary_package_uid, ¤t->instance_uid)) { + if (mxf_metadata_resolve (current, metadata)) + self->primary_package = MXF_METADATA_GENERIC_PACKAGE (current); + } else if (MXF_IS_METADATA_CONTENT_STORAGE (current) && + mxf_ul_is_equal (&self->content_storage_uid, ¤t->instance_uid)) { + if (mxf_metadata_resolve (current, metadata)) + self->content_storage = MXF_METADATA_CONTENT_STORAGE (current); + } + p++; + } + + self->identifications = + g_new0 (MXFMetadataIdentification *, self->n_identifications); + for (i = 0; i < self->n_identifications; i++) { + p = metadata; + while (*p) { + current = *p; + + if (MXF_IS_METADATA_IDENTIFICATION (current) && + mxf_ul_is_equal (&self->identifications_uids[i], + ¤t->instance_uid)) { + if (mxf_metadata_resolve (current, metadata)) + self->identifications[i] = MXF_METADATA_IDENTIFICATION (current); + break; + } + p++; + } + } + + if (!self->content_storage) { + GST_ERROR ("Couldn't resolve content storage"); + return FALSE; + } + + return MXF_METADATA_BASE_CLASS (mxf_metadata_preface_parent_class)-> + resolve (m, metadata); +} + +static void +mxf_metadata_preface_init (MXFMetadataPreface * self) +{ + +} + +static void +mxf_metadata_preface_class_init (MXFMetadataPrefaceClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + + miniobject_class->finalize = mxf_metadata_preface_finalize; + metadata_base_class->handle_tag = mxf_metadata_preface_handle_tag; + metadata_base_class->resolve = mxf_metadata_preface_resolve; +} + +G_DEFINE_TYPE (MXFMetadataIdentification, mxf_metadata_identification, + MXF_TYPE_METADATA); + +static void +mxf_metadata_identification_finalize (GstMiniObject * object) +{ + MXFMetadataIdentification *self = MXF_METADATA_IDENTIFICATION (object); + + g_free (self->company_name); + self->company_name = NULL; + + g_free (self->product_name); + self->product_name = NULL; + + g_free (self->version_string); + self->version_string = NULL; + + g_free (self->platform); + self->platform = NULL; + + GST_MINI_OBJECT_CLASS (mxf_metadata_identification_parent_class)->finalize + (object); +} + +static gboolean +mxf_metadata_identification_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataIdentification *self = MXF_METADATA_IDENTIFICATION (metadata); + gboolean ret = TRUE; + gchar str[48]; + + switch (tag) { + case 0x3c01: + self->company_name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" company name = %s", GST_STR_NULL (self->company_name)); + break; + case 0x3c02: + self->product_name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" product name = %s", GST_STR_NULL (self->product_name)); + break; + case 0x3c03: + if (!mxf_product_version_parse (&self->product_version, + tag_data, tag_size)) + goto error; + GST_DEBUG (" product version = %u.%u.%u.%u.%u", + self->product_version.major, + self->product_version.minor, + self->product_version.patch, + self->product_version.build, self->product_version.release); + break; + case 0x3c04: + self->version_string = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" version string = %s", GST_STR_NULL (self->version_string)); + break; + case 0x3c05: + if (tag_size != 16) + goto error; + memcpy (&self->product_uid, tag_data, 16); + GST_DEBUG (" product uid = %s", + mxf_ul_to_string (&self->product_uid, str)); + break; + case 0x3c06: + if (!mxf_timestamp_parse (&self->modification_date, tag_data, tag_size)) + goto error; + GST_DEBUG (" modification date = %d/%u/%u %u:%u:%u.%u", + self->modification_date.year, + self->modification_date.month, + self->modification_date.day, + self->modification_date.hour, + self->modification_date.minute, + self->modification_date.second, + (self->modification_date.quarter_msecond * 1000) / 256); + break; + case 0x3c07: + if (!mxf_product_version_parse (&self->toolkit_version, + tag_data, tag_size)) + goto error; + GST_DEBUG (" toolkit version = %u.%u.%u.%u.%u", + self->toolkit_version.major, + self->toolkit_version.minor, + self->toolkit_version.patch, + self->toolkit_version.build, self->toolkit_version.release); + break; + case 0x3c08: + self->platform = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" platform = %s", GST_STR_NULL (self->platform)); + break; + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_identification_parent_class)->handle_tag (metadata, + primer, tag, tag_data, tag_size); + break; + } + + return ret; + +error: + GST_ERROR ("Invalid identification local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_metadata_identification_init (MXFMetadataIdentification * self) +{ + +} + +static void +mxf_metadata_identification_class_init (MXFMetadataIdentificationClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + + miniobject_class->finalize = mxf_metadata_identification_finalize; + metadata_base_class->handle_tag = mxf_metadata_identification_handle_tag; +} + +G_DEFINE_TYPE (MXFMetadataContentStorage, mxf_metadata_content_storage, + MXF_TYPE_METADATA); + +static void +mxf_metadata_content_storage_finalize (GstMiniObject * object) +{ + MXFMetadataContentStorage *self = MXF_METADATA_CONTENT_STORAGE (object); + + g_free (self->packages); + self->packages = NULL; + g_free (self->packages_uids); + self->packages_uids = NULL; + g_free (self->essence_container_data); + self->essence_container_data = NULL; + g_free (self->essence_container_data_uids); + self->essence_container_data_uids = NULL; + + GST_MINI_OBJECT_CLASS (mxf_metadata_content_storage_parent_class)->finalize + (object); +} + +static gboolean +mxf_metadata_content_storage_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataContentStorage *self = MXF_METADATA_CONTENT_STORAGE (metadata); + gboolean ret = TRUE; + gchar str[48]; + + switch (tag) { + case 0x1901:{ + guint32 len; + guint i; + + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of packages = %u", len); + if (len == 0) + return TRUE; + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + if (tag_size < 8 + len * 16) + goto error; + + self->packages_uids = g_new (MXFUL, len); + self->n_packages = len; + for (i = 0; i < len; i++) { + memcpy (&self->packages_uids[i], tag_data + 8 + i * 16, 16); + GST_DEBUG (" package %u = %s", i, + mxf_ul_to_string (&self->packages_uids[i], str)); + } + break; + } + case 0x1902:{ + guint32 len; + guint i; + + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of essence container data = %u", len); + if (len == 0) + return TRUE; + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + if (tag_size < 8 + len * 16) + goto error; + + self->essence_container_data_uids = g_new (MXFUL, len); + self->n_essence_container_data = len; + for (i = 0; i < len; i++) { + memcpy (&self->essence_container_data_uids[i], + tag_data + 8 + i * 16, 16); + GST_DEBUG (" essence container data %u = %s", i, + mxf_ul_to_string (&self->essence_container_data_uids[i], str)); + } + break; + } + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_content_storage_parent_class)->handle_tag (metadata, + primer, tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR ("Invalid content storage local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static gboolean +mxf_metadata_content_storage_resolve (MXFMetadataBase * m, + MXFMetadataBase ** metadata) +{ + MXFMetadataContentStorage *self = MXF_METADATA_CONTENT_STORAGE (m); + MXFMetadataBase **p = metadata, *current; + guint i; + gboolean have_package = FALSE; + gboolean have_ecd = FALSE; + + self->packages = g_new0 (MXFMetadataGenericPackage *, self->n_packages); + for (i = 0; i < self->n_packages; i++) { + p = metadata; + while (*p) { + current = *p; + if (MXF_IS_METADATA_GENERIC_PACKAGE (current) && + mxf_ul_is_equal (¤t->instance_uid, &self->packages_uids[i])) { + if (mxf_metadata_resolve (current, metadata)) { + self->packages[i] = MXF_METADATA_GENERIC_PACKAGE (current); + have_package = TRUE; + } + break; + } + p++; + } + } + + self->essence_container_data = + g_new0 (MXFMetadataEssenceContainerData *, + self->n_essence_container_data); + for (i = 0; i < self->n_essence_container_data; i++) { + p = metadata; + while (*p) { + current = *p; + if (MXF_IS_METADATA_ESSENCE_CONTAINER_DATA (current) && + mxf_ul_is_equal (¤t->instance_uid, + &self->essence_container_data_uids[i])) { + if (mxf_metadata_resolve (current, metadata)) { + self->essence_container_data[i] = + MXF_METADATA_ESSENCE_CONTAINER_DATA (current); + have_ecd = TRUE; + } + break; + } + p++; + } + } + + if (!have_package) { + GST_ERROR ("Couldn't resolve any package"); + return FALSE; + } else if (!have_ecd) { + GST_ERROR ("Couldn't resolve any essence container data"); + return FALSE; + } + + return MXF_METADATA_BASE_CLASS (mxf_metadata_content_storage_parent_class)-> + resolve (m, metadata); +} + +static void +mxf_metadata_content_storage_init (MXFMetadataContentStorage * self) +{ + +} + +static void +mxf_metadata_content_storage_class_init (MXFMetadataContentStorageClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + + miniobject_class->finalize = mxf_metadata_content_storage_finalize; + metadata_base_class->handle_tag = mxf_metadata_content_storage_handle_tag; + metadata_base_class->resolve = mxf_metadata_content_storage_resolve; +} + +G_DEFINE_TYPE (MXFMetadataEssenceContainerData, + mxf_metadata_essence_container_data, MXF_TYPE_METADATA); + +static gboolean +mxf_metadata_essence_container_data_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataEssenceContainerData *self = + MXF_METADATA_ESSENCE_CONTAINER_DATA (metadata); + gboolean ret = TRUE; + gchar str[96]; + + switch (tag) { + case 0x2701: + if (tag_size != 32) + goto error; + memcpy (&self->linked_package_uid, tag_data, 32); + GST_DEBUG (" linked package = %s", + mxf_umid_to_string (&self->linked_package_uid, str)); + break; + case 0x3f06: + if (tag_size != 4) + goto error; + self->index_sid = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" index sid = %u", self->index_sid); + break; + case 0x3f07: + if (tag_size != 4) + goto error; + self->body_sid = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" body sid = %u", self->body_sid); + break; + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_essence_container_data_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR ("Invalid essence container data local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static gboolean +mxf_metadata_essence_container_data_resolve (MXFMetadataBase * m, + MXFMetadataBase ** metadata) +{ + MXFMetadataEssenceContainerData *self = + MXF_METADATA_ESSENCE_CONTAINER_DATA (m); + MXFMetadataBase **p = metadata, *current; + + while (*p) { + current = *p; + + if (MXF_IS_METADATA_SOURCE_PACKAGE (current)) { + MXFMetadataSourcePackage *package = MXF_METADATA_SOURCE_PACKAGE (current); + + if (mxf_umid_is_equal (&package->parent.package_uid, + &self->linked_package_uid)) { + if (mxf_metadata_resolve (current, metadata)) { + self->linked_package = package; + } + break; + } + } + p++; + } + + if (!self->linked_package) { + GST_ERROR ("Couldn't resolve a package"); + return FALSE; + } + + return + MXF_METADATA_BASE_CLASS + (mxf_metadata_essence_container_data_parent_class)->resolve (m, metadata); +} + +static void +mxf_metadata_essence_container_data_init (MXFMetadataEssenceContainerData * + self) +{ + +} + +static void + mxf_metadata_essence_container_data_class_init + (MXFMetadataEssenceContainerDataClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + + metadata_base_class->handle_tag = + mxf_metadata_essence_container_data_handle_tag; + metadata_base_class->resolve = mxf_metadata_essence_container_data_resolve; +} + +G_DEFINE_ABSTRACT_TYPE (MXFMetadataGenericPackage, mxf_metadata_generic_package, + MXF_TYPE_METADATA); + +static void +mxf_metadata_generic_package_finalize (GstMiniObject * object) +{ + MXFMetadataGenericPackage *self = MXF_METADATA_GENERIC_PACKAGE (object); + + g_free (self->name); + self->name = NULL; + g_free (self->tracks_uids); + self->tracks_uids = NULL; + + g_free (self->tracks); + self->tracks = NULL; + + GST_MINI_OBJECT_CLASS (mxf_metadata_generic_package_parent_class)->finalize + (object); +} + +static gboolean +mxf_metadata_generic_package_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataGenericPackage *self = MXF_METADATA_GENERIC_PACKAGE (metadata); + gboolean ret = TRUE; + gchar str[96]; + + switch (tag) { + case 0x4401: + if (tag_size != 32) + goto error; + memcpy (&self->package_uid, tag_data, 32); + GST_DEBUG (" UMID = %s", mxf_umid_to_string (&self->package_uid, str)); + break; + case 0x4402: + self->name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" name = %s", GST_STR_NULL (self->name)); + break; + case 0x4405: + if (!mxf_timestamp_parse (&self->package_creation_date, + tag_data, tag_size)) + goto error; + GST_DEBUG (" creation date = %d/%u/%u %u:%u:%u.%u", + self->package_creation_date.year, + self->package_creation_date.month, + self->package_creation_date.day, + self->package_creation_date.hour, + self->package_creation_date.minute, + self->package_creation_date.second, + (self->package_creation_date.quarter_msecond * 1000) / 256); + break; + case 0x4404: + if (!mxf_timestamp_parse (&self->package_modified_date, + tag_data, tag_size)) + goto error; + GST_DEBUG (" modification date = %d/%u/%u %u:%u:%u.%u", + self->package_modified_date.year, + self->package_modified_date.month, + self->package_modified_date.day, + self->package_modified_date.hour, + self->package_modified_date.minute, + self->package_modified_date.second, + (self->package_modified_date.quarter_msecond * 1000) / 256); + break; + case 0x4403:{ + guint32 len; + guint i; + + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of tracks = %u", len); + if (len == 0) + return TRUE; + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + if (tag_size < 8 + len * 16) + goto error; + + self->tracks_uids = g_new (MXFUL, len); + self->n_tracks = len; + for (i = 0; i < len; i++) { + memcpy (&self->tracks_uids[i], tag_data + 8 + i * 16, 16); + GST_DEBUG (" track %u = %s", i, + mxf_ul_to_string (&self->tracks_uids[i], str)); + } + break; + } + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_generic_package_parent_class)->handle_tag (metadata, + primer, tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR ("Invalid generic package local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static gboolean +mxf_metadata_generic_package_resolve (MXFMetadataBase * m, + MXFMetadataBase ** metadata) +{ + MXFMetadataGenericPackage *self = MXF_METADATA_GENERIC_PACKAGE (m); + MXFMetadataBase **p, *current; + guint i; + gboolean have_track = FALSE; + + self->tracks = g_new0 (MXFMetadataTrack *, self->n_tracks); + for (i = 0; i < self->n_tracks; i++) { + p = metadata; + while (*p) { + current = *p; + + if (MXF_IS_METADATA_TRACK (current)) { + MXFMetadataTrack *track = MXF_METADATA_TRACK (current); + + if (mxf_ul_is_equal (¤t->instance_uid, &self->tracks_uids[i])) { + if (mxf_metadata_resolve (current, metadata)) { + self->tracks[i] = track; + have_track = TRUE; + + if ((track->type & 0xf0) == 0x10) + self->n_timecode_tracks++; + else if ((track->type & 0xf0) == 0x20) + self->n_metadata_tracks++; + else if ((track->type & 0xf0) == 0x30) + self->n_essence_tracks++; + else if ((track->type & 0xf0) == 0x40) + self->n_other_tracks++; + } + + break; + } + } + + p++; + } + } + + if (!have_track) { + GST_ERROR ("Couldn't resolve a track"); + return FALSE; + } + + return MXF_METADATA_BASE_CLASS (mxf_metadata_generic_package_parent_class)-> + resolve (m, metadata); +} + +static void +mxf_metadata_generic_package_init (MXFMetadataGenericPackage * self) +{ + +} + +static void +mxf_metadata_generic_package_class_init (MXFMetadataGenericPackageClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + + miniobject_class->finalize = mxf_metadata_generic_package_finalize; + metadata_base_class->handle_tag = mxf_metadata_generic_package_handle_tag; + metadata_base_class->resolve = mxf_metadata_generic_package_resolve; +} + +G_DEFINE_TYPE (MXFMetadataMaterialPackage, mxf_metadata_material_package, + MXF_TYPE_METADATA_GENERIC_PACKAGE); + +static gboolean +mxf_metadata_material_package_resolve (MXFMetadataBase * m, + MXFMetadataBase ** metadata) +{ + gboolean ret = + MXF_METADATA_BASE_CLASS (mxf_metadata_material_package_parent_class)-> + resolve (m, metadata); + MXFMetadataGenericPackage *self = MXF_METADATA_GENERIC_PACKAGE (m); + guint i; + + if (!ret) + return ret; + + for (i = 0; i < self->n_tracks; i++) { + MXFMetadataTrack *track = self->tracks[i]; + MXFMetadataSequence *sequence; + guint j; + + if (!track) + continue; + + sequence = track->sequence; + + if (!sequence || !sequence->structural_components) + continue; + + for (j = 0; j < sequence->n_structural_components; j++) { + MXFMetadataSourceClip *sc; + + if (!sequence->structural_components[j] + || !MXF_IS_METADATA_SOURCE_CLIP (sequence->structural_components[j])) + continue; + + sc = MXF_METADATA_SOURCE_CLIP (sequence->structural_components[j]); + + if (sc->source_package) + sc->source_package->top_level = TRUE; + } + } + + return TRUE; +} + +static void +mxf_metadata_material_package_init (MXFMetadataMaterialPackage * self) +{ +} + +static void +mxf_metadata_material_package_class_init (MXFMetadataMaterialPackageClass * + klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + + metadata_base_class->resolve = mxf_metadata_material_package_resolve; +} + +G_DEFINE_TYPE (MXFMetadataSourcePackage, mxf_metadata_source_package, + MXF_TYPE_METADATA_GENERIC_PACKAGE); + +static void +mxf_metadata_source_package_finalize (GstMiniObject * object) +{ + MXFMetadataSourcePackage *self = MXF_METADATA_SOURCE_PACKAGE (object); + + g_free (self->descriptors); + self->descriptors = NULL; + + GST_MINI_OBJECT_CLASS (mxf_metadata_source_package_parent_class)->finalize + (object); +} + +static gboolean +mxf_metadata_source_package_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataSourcePackage *self = MXF_METADATA_SOURCE_PACKAGE (metadata); + gboolean ret = TRUE; + gchar str[48]; + + switch (tag) { + case 0x4701: + if (tag_size != 16) + goto error; + + self->n_descriptors = 1; + memcpy (&self->descriptors_uid, tag_data, 16); + GST_DEBUG (" descriptor = %s", + mxf_ul_to_string (&self->descriptors_uid, str)); + break; + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_source_package_parent_class)->handle_tag (metadata, + primer, tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR ("Invalid source package local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static gboolean +mxf_metadata_source_package_resolve (MXFMetadataBase * m, + MXFMetadataBase ** metadata) +{ + MXFMetadataSourcePackage *self = MXF_METADATA_SOURCE_PACKAGE (m); + MXFMetadataGenericPackage *package = MXF_METADATA_GENERIC_PACKAGE (m); + MXFMetadataBase **p = metadata, *current; + guint i, j; + gboolean ret; + MXFMetadataGenericDescriptor *d = NULL; + + if (mxf_ul_is_zero (&self->descriptors_uid)) + return MXF_METADATA_BASE_CLASS (mxf_metadata_source_package_parent_class)-> + resolve (m, metadata); + + while (*p) { + current = *p; + + if (MXF_IS_METADATA_GENERIC_DESCRIPTOR (current) && + mxf_ul_is_equal (¤t->instance_uid, &self->descriptors_uid)) { + d = MXF_METADATA_GENERIC_DESCRIPTOR (current); + break; + } + p++; + } + + if (!d || !mxf_metadata_resolve (MXF_METADATA_BASE (d), metadata)) { + GST_ERROR ("Couldn't resolve descriptor"); + return FALSE; + } + + if (MXF_IS_METADATA_MULTIPLE_DESCRIPTOR (d)) { + MXFMetadataMultipleDescriptor *m = MXF_METADATA_MULTIPLE_DESCRIPTOR (d); + + if (m->sub_descriptors) { + self->n_descriptors = m->n_sub_descriptors + 1; + self->descriptors = + g_new0 (MXFMetadataGenericDescriptor *, self->n_descriptors); + + for (i = 0; i < m->n_sub_descriptors; i++) { + self->descriptors[i] = m->sub_descriptors[i]; + } + self->descriptors[self->n_descriptors - 1] = + MXF_METADATA_GENERIC_DESCRIPTOR (m); + } + } else { + self->n_descriptors = 1; + self->descriptors = g_new0 (MXFMetadataGenericDescriptor *, 1); + self->descriptors[0] = d; + } + + ret = + MXF_METADATA_BASE_CLASS (mxf_metadata_source_package_parent_class)-> + resolve (m, metadata); + + for (i = 0; i < package->n_tracks; i++) { + guint n_descriptor = 0, k = 0; + + for (j = 0; j < self->n_descriptors; j++) { + MXFMetadataFileDescriptor *d; + + if (!MXF_IS_METADATA_FILE_DESCRIPTOR (self->descriptors[j])) + continue; + d = MXF_METADATA_FILE_DESCRIPTOR (self->descriptors[j]); + + if (d->linked_track_id == package->tracks[i]->track_id || + d->linked_track_id == 0) + n_descriptor++; + } + + package->tracks[i]->descriptor = + g_new0 (MXFMetadataFileDescriptor *, n_descriptor); + package->tracks[i]->n_descriptor = n_descriptor; + for (j = 0; j < self->n_descriptors; j++) { + MXFMetadataFileDescriptor *d; + + if (!MXF_IS_METADATA_FILE_DESCRIPTOR (self->descriptors[j])) + continue; + d = MXF_METADATA_FILE_DESCRIPTOR (self->descriptors[j]); + + if (d->linked_track_id == package->tracks[i]->track_id || + (d->linked_track_id == 0 && n_descriptor == 1)) + package->tracks[i]->descriptor[k++] = d; + } + } + + return ret; +} + +static void +mxf_metadata_source_package_init (MXFMetadataSourcePackage * self) +{ + +} + +static void +mxf_metadata_source_package_class_init (MXFMetadataSourcePackageClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + + miniobject_class->finalize = mxf_metadata_source_package_finalize; + metadata_base_class->handle_tag = mxf_metadata_source_package_handle_tag; + metadata_base_class->resolve = mxf_metadata_source_package_resolve; +} + +G_DEFINE_ABSTRACT_TYPE (MXFMetadataTrack, mxf_metadata_track, + MXF_TYPE_METADATA); + +static void +mxf_metadata_track_finalize (GstMiniObject * object) +{ + MXFMetadataTrack *self = MXF_METADATA_TRACK (object); + + g_free (self->track_name); + self->track_name = NULL; + g_free (self->descriptor); + self->descriptor = NULL; + + GST_MINI_OBJECT_CLASS (mxf_metadata_track_parent_class)->finalize (object); +} + +static gboolean +mxf_metadata_track_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataTrack *self = MXF_METADATA_TRACK (metadata); + gboolean ret = TRUE; + gchar str[48]; + + switch (tag) { + case 0x4801: + if (tag_size != 4) + goto error; + self->track_id = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" track id = %u", self->track_id); + break; + case 0x4804: + if (tag_size != 4) + goto error; + self->track_number = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" track number = %u", self->track_number); + break; + case 0x4802: + self->track_name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" track name = %s", GST_STR_NULL (self->track_name)); + break; + case 0x4803: + if (tag_size != 16) + goto error; + memcpy (&self->sequence_uid, tag_data, 16); + GST_DEBUG (" sequence uid = %s", + mxf_ul_to_string (&self->sequence_uid, str)); + break; + default: + ret = + MXF_METADATA_BASE_CLASS (mxf_metadata_track_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR ("Invalid track local tag 0x%04x of size %u", tag, tag_size); + + return FALSE; +} + +static gboolean +mxf_metadata_track_resolve (MXFMetadataBase * m, MXFMetadataBase ** metadata) +{ + MXFMetadataTrack *self = MXF_METADATA_TRACK (m); + MXFMetadataBase **p = metadata, *current; + guint i; + + while (*p) { + current = *p; + if (MXF_IS_METADATA_SEQUENCE (current) && + mxf_ul_is_equal (¤t->instance_uid, &self->sequence_uid)) { + self->sequence = MXF_METADATA_SEQUENCE (current); + break; + } + p++; + } + + if (!self->sequence + || !mxf_metadata_resolve (MXF_METADATA_BASE (self->sequence), metadata)) { + GST_ERROR ("Couldn't resolve sequence"); + return FALSE; + } + + self->type = + mxf_metadata_track_identifier_parse (&self->sequence->data_definition); + if (self->type == MXF_METADATA_TRACK_UNKNOWN) { + MXFMetadataSequence *sequence = self->sequence; + + for (i = 0; i < sequence->n_structural_components; i++) { + MXFMetadataStructuralComponent *component = + sequence->structural_components[i]; + + if (!component) + continue; + + self->type = + mxf_metadata_track_identifier_parse (&component->data_definition); + if (self->type != MXF_METADATA_TRACK_UNKNOWN) + break; + } + } + + return MXF_METADATA_BASE_CLASS (mxf_metadata_track_parent_class)->resolve (m, + metadata); +} + +static void +mxf_metadata_track_init (MXFMetadataTrack * self) +{ + +} + +static void +mxf_metadata_track_class_init (MXFMetadataTrackClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + + miniobject_class->finalize = mxf_metadata_track_finalize; + metadata_base_class->handle_tag = mxf_metadata_track_handle_tag; + metadata_base_class->resolve = mxf_metadata_track_resolve; +} + +/* SMPTE RP224 */ +static const struct +{ + guint8 ul[16]; + MXFMetadataTrackType type; +} mxf_metadata_track_identifier[] = { + { { + 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, + 0x01, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00}, + MXF_METADATA_TRACK_TIMECODE_12M_INACTIVE}, { { + 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x01, + 0x02, 0x00, 0x00, 0x00}, MXF_METADATA_TRACK_TIMECODE_12M_ACTIVE}, { { + 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x01, + 0x03, 0x00, 0x00, 0x00}, MXF_METADATA_TRACK_TIMECODE_309M}, { { + 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x01, + 0x10, 0x00, 0x00, 0x00}, MXF_METADATA_TRACK_METADATA}, { { + 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x02, + 0x01, 0x00, 0x00, 0x00}, MXF_METADATA_TRACK_PICTURE_ESSENCE}, { { + 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x02, + 0x02, 0x00, 0x00, 0x00}, MXF_METADATA_TRACK_SOUND_ESSENCE}, { { + 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x02, + 0x03, 0x00, 0x00, 0x00}, MXF_METADATA_TRACK_DATA_ESSENCE}, { { + 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x03, + 0x01, 0x00, 0x00, 0x00}, MXF_METADATA_TRACK_AUXILIARY_DATA}, { { + 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x03, + 0x02, 0x00, 0x00, 0x00}, MXF_METADATA_TRACK_PARSED_TEXT} +}; + +MXFMetadataTrackType +mxf_metadata_track_identifier_parse (const MXFUL * track_identifier) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (mxf_metadata_track_identifier); i++) + if (memcmp (&mxf_metadata_track_identifier[i].ul, &track_identifier->u, + 16) == 0) + return mxf_metadata_track_identifier[i].type; + + return MXF_METADATA_TRACK_UNKNOWN; +} + +G_DEFINE_TYPE (MXFMetadataTimelineTrack, mxf_metadata_timeline_track, + MXF_TYPE_METADATA_TRACK); + +static gboolean +mxf_metadata_timeline_track_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataTimelineTrack *self = MXF_METADATA_TIMELINE_TRACK (metadata); + gboolean ret = TRUE; + + switch (tag) { + case 0x4b01: + if (!mxf_fraction_parse (&self->edit_rate, tag_data, tag_size)) + goto error; + GST_DEBUG (" edit rate = %d/%d", self->edit_rate.n, self->edit_rate.d); + break; + case 0x4b02: + if (tag_size != 8) + goto error; + self->origin = GST_READ_UINT64_BE (tag_data); + GST_DEBUG (" origin = %" G_GINT64_FORMAT, self->origin); + break; + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_timeline_track_parent_class)->handle_tag (metadata, + primer, tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR ("Invalid timeline track local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_metadata_timeline_track_init (MXFMetadataTimelineTrack * self) +{ + +} + +static void +mxf_metadata_timeline_track_class_init (MXFMetadataTimelineTrackClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + + metadata_base_class->handle_tag = mxf_metadata_timeline_track_handle_tag; +} + +G_DEFINE_TYPE (MXFMetadataEventTrack, mxf_metadata_event_track, + MXF_TYPE_METADATA_TRACK); + +static gboolean +mxf_metadata_event_track_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataEventTrack *self = MXF_METADATA_EVENT_TRACK (metadata); + gboolean ret = TRUE; + + switch (tag) { + case 0x4901: + if (!mxf_fraction_parse (&self->event_edit_rate, tag_data, tag_size)) + goto error; + GST_DEBUG (" event edit rate = %d/%d", self->event_edit_rate.n, + self->event_edit_rate.d); + break; + case 0x4902: + if (tag_size != 8) + goto error; + self->event_origin = GST_READ_UINT64_BE (tag_data); + GST_DEBUG (" event origin = %" G_GINT64_FORMAT, self->event_origin); + break; + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_event_track_parent_class)->handle_tag (metadata, primer, + tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR ("Invalid event track local tag 0x%04x of size %u", tag, tag_size); + + return FALSE; +} + +static void +mxf_metadata_event_track_init (MXFMetadataEventTrack * self) +{ + +} + +static void +mxf_metadata_event_track_class_init (MXFMetadataEventTrackClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + + metadata_base_class->handle_tag = mxf_metadata_event_track_handle_tag; +} + +G_DEFINE_TYPE (MXFMetadataStaticTrack, mxf_metadata_static_track, + MXF_TYPE_METADATA_TRACK); + +static void +mxf_metadata_static_track_init (MXFMetadataStaticTrack * self) +{ +} + +static void +mxf_metadata_static_track_class_init (MXFMetadataStaticTrackClass * klass) +{ +} + +G_DEFINE_TYPE (MXFMetadataSequence, mxf_metadata_sequence, MXF_TYPE_METADATA); + +static void +mxf_metadata_sequence_finalize (GstMiniObject * object) +{ + MXFMetadataSequence *self = MXF_METADATA_SEQUENCE (object); + + g_free (self->structural_components_uids); + self->structural_components_uids = NULL; + g_free (self->structural_components); + self->structural_components = NULL; + + GST_MINI_OBJECT_CLASS (mxf_metadata_sequence_parent_class)->finalize (object); +} + +static gboolean +mxf_metadata_sequence_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataSequence *self = MXF_METADATA_SEQUENCE (metadata); + gboolean ret = TRUE; + gchar str[48]; + + switch (tag) { + case 0x0201: + if (tag_size != 16) + goto error; + memcpy (&self->data_definition, tag_data, 16); + GST_DEBUG (" data definition = %s", + mxf_ul_to_string (&self->data_definition, str)); + break; + case 0x0202: + if (tag_size != 8) + goto error; + self->duration = GST_READ_UINT64_BE (tag_data); + GST_DEBUG (" duration = %" G_GINT64_FORMAT, self->duration); + break; + case 0x1001:{ + guint32 len; + guint i; + + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of structural components = %u", len); + if (len == 0) + return TRUE; + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + if (tag_size < 8 + len * 16) + goto error; + + self->structural_components_uids = g_new (MXFUL, len); + self->n_structural_components = len; + for (i = 0; i < len; i++) { + memcpy (&self->structural_components_uids[i], + tag_data + 8 + i * 16, 16); + GST_DEBUG (" structural component %u = %s", i, + mxf_ul_to_string (&self->structural_components_uids[i], str)); + } + break; + } + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_sequence_parent_class)->handle_tag (metadata, primer, + tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR ("Invalid sequence local tag 0x%04x of size %u", tag, tag_size); + + return FALSE; +} + +static gboolean +mxf_metadata_sequence_resolve (MXFMetadataBase * m, MXFMetadataBase ** metadata) +{ + MXFMetadataSequence *self = MXF_METADATA_SEQUENCE (m); + MXFMetadataBase **p, *current; + guint i; + guint have_sc = 0; + + self->structural_components = + g_new0 (MXFMetadataStructuralComponent *, self->n_structural_components); + for (i = 0; i < self->n_structural_components; i++) { + p = metadata; + + while (*p) { + current = *p; + + if (MXF_IS_METADATA_STRUCTURAL_COMPONENT (current) + && mxf_ul_is_equal (¤t->instance_uid, + &self->structural_components_uids[i])) { + if (mxf_metadata_resolve (current, metadata)) { + self->structural_components[i] = + MXF_METADATA_STRUCTURAL_COMPONENT (current); + have_sc++; + break; + } + } + p++; + } + } + + if (have_sc != self->n_structural_components) { + GST_ERROR ("Couldn't resolve all structural components"); + return FALSE; + } + + return MXF_METADATA_BASE_CLASS (mxf_metadata_sequence_parent_class)-> + resolve (m, metadata); + +} + +static void +mxf_metadata_sequence_init (MXFMetadataSequence * self) +{ + +} + +static void +mxf_metadata_sequence_class_init (MXFMetadataSequenceClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + + miniobject_class->finalize = mxf_metadata_sequence_finalize; + metadata_base_class->handle_tag = mxf_metadata_sequence_handle_tag; + metadata_base_class->resolve = mxf_metadata_sequence_resolve; +} + +G_DEFINE_TYPE (MXFMetadataStructuralComponent, + mxf_metadata_structural_component, MXF_TYPE_METADATA); + +static gboolean +mxf_metadata_structural_component_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataStructuralComponent *self = + MXF_METADATA_STRUCTURAL_COMPONENT (metadata); + gboolean ret = TRUE; + gchar str[48]; + + switch (tag) { + case 0x0201: + if (tag_size != 16) + goto error; + memcpy (&self->data_definition, tag_data, 16); + GST_DEBUG (" data definition = %s", + mxf_ul_to_string (&self->data_definition, str)); + break; + case 0x0202: + if (tag_size != 8) + goto error; + self->duration = GST_READ_UINT64_BE (tag_data); + GST_DEBUG (" duration = %" G_GINT64_FORMAT, self->duration); + break; + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_structural_component_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR ("Invalid structural component local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_metadata_structural_component_init (MXFMetadataStructuralComponent * self) +{ + +} + +static void + mxf_metadata_structural_component_class_init + (MXFMetadataStructuralComponentClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + + metadata_base_class->handle_tag = + mxf_metadata_structural_component_handle_tag; +} + +G_DEFINE_TYPE (MXFMetadataTimecodeComponent, mxf_metadata_timecode_component, + MXF_TYPE_METADATA_STRUCTURAL_COMPONENT); + +static gboolean +mxf_metadata_timecode_component_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataTimecodeComponent *self = + MXF_METADATA_TIMECODE_COMPONENT (metadata); + gboolean ret = TRUE; + + switch (tag) { + case 0x1502: + if (tag_size != 2) + goto error; + self->rounded_timecode_base = GST_READ_UINT16_BE (tag_data); + GST_DEBUG (" rounded timecode base = %u", self->rounded_timecode_base); + break; + case 0x1501: + if (tag_size != 8) + goto error; + self->start_timecode = GST_READ_UINT64_BE (tag_data); + GST_DEBUG (" start timecode = %" G_GINT64_FORMAT, self->start_timecode); + break; + case 0x1503: + if (tag_size != 1) + goto error; + self->drop_frame = (GST_READ_UINT8 (tag_data) != 0); + GST_DEBUG (" drop frame = %s", (self->drop_frame) ? "yes" : "no"); + break; + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_timecode_component_parent_class)->handle_tag (metadata, + primer, tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR ("Invalid timecode component local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_metadata_timecode_component_init (MXFMetadataTimecodeComponent * self) +{ + +} + +static void +mxf_metadata_timecode_component_class_init (MXFMetadataTimecodeComponentClass * + klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + + metadata_base_class->handle_tag = mxf_metadata_timecode_component_handle_tag; +} + +G_DEFINE_TYPE (MXFMetadataSourceClip, mxf_metadata_source_clip, + MXF_TYPE_METADATA_STRUCTURAL_COMPONENT); + +static gboolean +mxf_metadata_source_clip_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataSourceClip *self = MXF_METADATA_SOURCE_CLIP (metadata); + gboolean ret = TRUE; + gchar str[96]; + + switch (tag) { + case 0x1201: + if (tag_size != 8) + goto error; + + self->start_position = GST_READ_UINT64_BE (tag_data); + GST_DEBUG (" start position = %" G_GINT64_FORMAT, self->start_position); + break; + case 0x1101: + if (tag_size != 32) + goto error; + + memcpy (&self->source_package_id, tag_data, 32); + GST_DEBUG (" source package id = %s", + mxf_umid_to_string (&self->source_package_id, str)); + break; + case 0x1102: + if (tag_size != 4) + goto error; + + self->source_track_id = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" source track id = %u", self->source_track_id); + break; + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_source_clip_parent_class)->handle_tag (metadata, primer, + tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR ("Invalid source clip local tag 0x%04x of size %u", tag, tag_size); + + return FALSE; +} + +static gboolean +mxf_metadata_source_clip_resolve (MXFMetadataBase * m, + MXFMetadataBase ** metadata) +{ + MXFMetadataSourceClip *self = MXF_METADATA_SOURCE_CLIP (m); + MXFMetadataBase **p, *current; + + p = metadata; + while (*p) { + current = *p; + if (MXF_IS_METADATA_SOURCE_PACKAGE (current)) { + MXFMetadataGenericPackage *p = MXF_METADATA_GENERIC_PACKAGE (current); + + if (mxf_umid_is_equal (&p->package_uid, &self->source_package_id)) { + self->source_package = MXF_METADATA_SOURCE_PACKAGE (current); + break; + } + } + p++; + } + + return MXF_METADATA_BASE_CLASS (mxf_metadata_source_clip_parent_class)-> + resolve (m, metadata); +} + +static void +mxf_metadata_source_clip_init (MXFMetadataSourceClip * self) +{ + +} + +static void +mxf_metadata_source_clip_class_init (MXFMetadataSourceClipClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + + metadata_base_class->handle_tag = mxf_metadata_source_clip_handle_tag; + metadata_base_class->resolve = mxf_metadata_source_clip_resolve; +} + +G_DEFINE_TYPE (MXFMetadataDMSourceClip, mxf_metadata_dm_source_clip, + MXF_TYPE_METADATA_SOURCE_CLIP); + +static void +mxf_metadata_dm_source_clip_finalize (GstMiniObject * object) +{ + MXFMetadataDMSourceClip *self = MXF_METADATA_DM_SOURCE_CLIP (object); + + g_free (self->track_ids); + self->track_ids = NULL; + + GST_MINI_OBJECT_CLASS (mxf_metadata_dm_source_clip_parent_class)->finalize + (object); +} + +static gboolean +mxf_metadata_dm_source_clip_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataDMSourceClip *self = MXF_METADATA_DM_SOURCE_CLIP (metadata); + gboolean ret = TRUE; + + switch (tag) { + case 0x6103: + { + guint32 len; + guint i; + + if (tag_size < 8) + goto error; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of track ids = %u", len); + if (len == 0) + return TRUE; + + if (GST_READ_UINT32_BE (tag_data + 4) != 4) + goto error; + + if (tag_size < 8 + 4 * len) + goto error; + + tag_data += 8; + tag_size -= 8; + + self->n_track_ids = len; + self->track_ids = g_new0 (guint32, len); + + for (i = 0; i < len; i++) { + self->track_ids[i] = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" track id %u = %u", i, self->track_ids[i]); + tag_data += 4; + tag_size -= 4; + } + break; + } + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_dm_source_clip_parent_class)->handle_tag (metadata, + primer, tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR ("Invalid DM source clip local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_metadata_dm_source_clip_init (MXFMetadataDMSourceClip * self) +{ + +} + +static void +mxf_metadata_dm_source_clip_class_init (MXFMetadataDMSourceClipClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + + miniobject_class->finalize = mxf_metadata_dm_source_clip_finalize; + metadata_base_class->handle_tag = mxf_metadata_dm_source_clip_handle_tag; +} + +G_DEFINE_TYPE (MXFMetadataDMSegment, mxf_metadata_dm_segment, + MXF_TYPE_METADATA_STRUCTURAL_COMPONENT); + +static void +mxf_metadata_dm_segment_finalize (GstMiniObject * object) +{ + MXFMetadataDMSegment *self = MXF_METADATA_DM_SEGMENT (object); + + g_free (self->track_ids); + self->track_ids = NULL; + + g_free (self->event_comment); + self->event_comment = NULL; + + GST_MINI_OBJECT_CLASS (mxf_metadata_dm_segment_parent_class)->finalize + (object); +} + +static gboolean +mxf_metadata_dm_segment_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataDMSegment *self = MXF_METADATA_DM_SEGMENT (metadata); + gboolean ret = TRUE; + gchar str[48]; + + switch (tag) { + case 0x0601: + if (tag_size != 8) + goto error; + self->event_start_position = GST_READ_UINT64_BE (tag_data); + GST_DEBUG (" event start position = %" G_GINT64_FORMAT, + self->event_start_position); + break; + case 0x0602: + self->event_comment = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" event comment = %s", GST_STR_NULL (self->event_comment)); + break; + case 0x6102: + { + guint32 len; + guint i; + + if (tag_size < 8) + goto error; + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of track ids = %u", len); + if (len == 0) + return TRUE; + + if (GST_READ_UINT32_BE (tag_data + 4) != 4) + goto error; + + if (len * 4 + 8 < tag_size) + goto error; + + self->n_track_ids = len; + self->track_ids = g_new0 (guint32, len); + + tag_data += 8; + tag_size -= 8; + + for (i = 0; i < len; i++) { + self->track_ids[i] = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" track id %u = %u", i, self->track_ids[i]); + tag_data += 4; + tag_size -= 4; + } + break; + } + case 0x6101: + if (tag_size != 16) + goto error; + + memcpy (&self->dm_framework_uid, tag_data, 16); + GST_DEBUG (" DM framework = %s", + mxf_ul_to_string (&self->dm_framework_uid, str)); + break; + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_dm_segment_parent_class)->handle_tag (metadata, primer, + tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR ("Invalid DM segment local tag 0x%04x of size %u", tag, tag_size); + + return FALSE; +} + +static gboolean +mxf_metadata_dm_segment_resolve (MXFMetadataBase * m, + MXFMetadataBase ** metadata) +{ + MXFMetadataDMSegment *self = MXF_METADATA_DM_SEGMENT (m); + MXFMetadataBase **p = metadata, *current; + + while (*p) { + current = *p; + + /* TODO: if (MXF_IS_DM_FRAMEWORK (current) && */ + if (mxf_ul_is_equal (¤t->instance_uid, &self->dm_framework_uid)) { + if (mxf_metadata_resolve (current, metadata)) { + self->dm_framework = current; + } + break; + } + + p++; + } + + if (!self->dm_framework) { + GST_ERROR ("Couldn't resolve DM framework"); + return FALSE; + } + + return MXF_METADATA_BASE_CLASS (mxf_metadata_dm_segment_parent_class)-> + resolve (m, metadata); +} + +static void +mxf_metadata_dm_segment_init (MXFMetadataDMSegment * self) +{ + +} + +static void +mxf_metadata_dm_segment_class_init (MXFMetadataDMSegmentClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + + miniobject_class->finalize = mxf_metadata_dm_segment_finalize; + metadata_base_class->handle_tag = mxf_metadata_dm_segment_handle_tag; + metadata_base_class->resolve = mxf_metadata_dm_segment_resolve; +} + +G_DEFINE_ABSTRACT_TYPE (MXFMetadataGenericDescriptor, + mxf_metadata_generic_descriptor, MXF_TYPE_METADATA); + +static void +mxf_metadata_generic_descriptor_finalize (GstMiniObject * object) +{ + MXFMetadataGenericDescriptor *self = MXF_METADATA_GENERIC_DESCRIPTOR (object); + + g_free (self->locators_uids); + self->locators_uids = NULL; + + g_free (self->locators); + self->locators = NULL; + + GST_MINI_OBJECT_CLASS (mxf_metadata_generic_descriptor_parent_class)->finalize + (object); +} + +static gboolean +mxf_metadata_generic_descriptor_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataGenericDescriptor *self = + MXF_METADATA_GENERIC_DESCRIPTOR (metadata); + gboolean ret = TRUE; + gchar str[48]; + + switch (tag) { + case 0x2f01:{ + guint32 len; + guint i; + + if (tag_size < 8) + goto error; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of locators = %u", len); + if (len == 0) + return TRUE; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + + self->locators_uids = g_new (MXFUL, len); + self->n_locators = len; + for (i = 0; i < len; i++) { + memcpy (&self->locators_uids[i], tag_data + 8 + i * 16, 16); + GST_DEBUG (" locator %u = %s", i, + mxf_ul_to_string (&self->locators_uids[i], str)); + } + break; + } + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_generic_descriptor_parent_class)->handle_tag (metadata, + primer, tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR ("Invalid generic descriptor local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static gboolean +mxf_metadata_generic_descriptor_resolve (MXFMetadataBase * m, + MXFMetadataBase ** metadata) +{ + MXFMetadataGenericDescriptor *self = MXF_METADATA_GENERIC_DESCRIPTOR (m); + MXFMetadataBase **p, *current; + guint i; + gboolean have_locator = FALSE; + + self->locators = g_new0 (MXFMetadataLocator *, self->n_locators); + for (i = 0; i < self->n_locators; i++) { + p = metadata; + while (*p) { + current = *p; + + if (MXF_IS_METADATA_LOCATOR (current) && + mxf_ul_is_equal (¤t->instance_uid, &self->locators_uids[i])) { + if (mxf_metadata_resolve (current, metadata)) { + self->locators[i] = MXF_METADATA_LOCATOR (current); + have_locator = TRUE; + } + break; + } + p++; + } + } + + if (!have_locator && self->n_locators > 0) { + GST_ERROR ("Couldn't resolve a locator"); + return FALSE; + } + + return + MXF_METADATA_BASE_CLASS (mxf_metadata_generic_descriptor_parent_class)-> + resolve (m, metadata); +} + +static void +mxf_metadata_generic_descriptor_init (MXFMetadataGenericDescriptor * self) +{ + +} + +static void +mxf_metadata_generic_descriptor_class_init (MXFMetadataGenericDescriptorClass * + klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + + miniobject_class->finalize = mxf_metadata_generic_descriptor_finalize; + metadata_base_class->handle_tag = mxf_metadata_generic_descriptor_handle_tag; + metadata_base_class->resolve = mxf_metadata_generic_descriptor_resolve; +} + +G_DEFINE_TYPE (MXFMetadataFileDescriptor, mxf_metadata_file_descriptor, + MXF_TYPE_METADATA_GENERIC_DESCRIPTOR); + +static gboolean +mxf_metadata_file_descriptor_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataFileDescriptor *self = MXF_METADATA_FILE_DESCRIPTOR (metadata); + gboolean ret = TRUE; + gchar str[48]; + + switch (tag) { + case 0x3006: + if (tag_size != 4) + goto error; + self->linked_track_id = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" linked track id = %u", self->linked_track_id); + break; + case 0x3001: + if (!mxf_fraction_parse (&self->sample_rate, tag_data, tag_size)) + goto error; + GST_DEBUG (" sample rate = %d/%d", self->sample_rate.n, + self->sample_rate.d); + break; + case 0x3002: + if (tag_size != 8) + goto error; + self->container_duration = GST_READ_UINT64_BE (tag_data); + GST_DEBUG (" container duration = %" G_GINT64_FORMAT, + self->container_duration); + break; + case 0x3004: + if (tag_size != 16) + goto error; + memcpy (&self->essence_container, tag_data, 16); + GST_DEBUG (" essence container = %s", + mxf_ul_to_string (&self->essence_container, str)); + break; + case 0x3005: + if (tag_size != 16) + goto error; + memcpy (&self->codec, tag_data, 16); + GST_DEBUG (" codec = %s", mxf_ul_to_string (&self->codec, str)); + break; + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_file_descriptor_parent_class)->handle_tag (metadata, + primer, tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR ("Invalid file descriptor local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_metadata_file_descriptor_init (MXFMetadataFileDescriptor * self) +{ + +} + +static void +mxf_metadata_file_descriptor_class_init (MXFMetadataFileDescriptorClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + + metadata_base_class->handle_tag = mxf_metadata_file_descriptor_handle_tag; +} + +G_DEFINE_TYPE (MXFMetadataGenericPictureEssenceDescriptor, + mxf_metadata_generic_picture_essence_descriptor, + MXF_TYPE_METADATA_FILE_DESCRIPTOR); + +static gboolean +mxf_metadata_generic_picture_essence_descriptor_handle_tag (MXFMetadataBase * + metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataGenericPictureEssenceDescriptor *self = + MXF_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (metadata); + gboolean ret = TRUE; + gchar str[48]; + + switch (tag) { + case 0x3215: + if (tag_size != 1) + goto error; + self->signal_standard = GST_READ_UINT8 (tag_data); + GST_DEBUG (" signal standard = %u", self->signal_standard); + break; + case 0x320c: + if (tag_size != 1) + goto error; + self->frame_layout = GST_READ_UINT8 (tag_data); + GST_DEBUG (" frame layout = %u", self->frame_layout); + break; + case 0x3203: + if (tag_size != 4) + goto error; + self->stored_width = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" stored width = %u", self->stored_width); + break; + case 0x3202: + if (tag_size != 4) + goto error; + self->stored_height = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" stored height = %u", self->stored_height); + break; + case 0x3216: + if (tag_size != 4) + goto error; + self->stored_f2_offset = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" stored f2 offset = %d", self->stored_f2_offset); + break; + case 0x3205: + if (tag_size != 4) + goto error; + self->sampled_width = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" sampled width = %u", self->sampled_width); + break; + case 0x3204: + if (tag_size != 4) + goto error; + self->sampled_height = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" sampled height = %u", self->sampled_height); + break; + case 0x3206: + if (tag_size != 4) + goto error; + self->sampled_x_offset = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" sampled x offset = %d", self->sampled_x_offset); + break; + case 0x3207: + if (tag_size != 4) + goto error; + self->sampled_y_offset = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" sampled y offset = %d", self->sampled_y_offset); + break; + case 0x3208: + if (tag_size != 4) + goto error; + self->display_height = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" display height = %u", self->display_height); + break; + case 0x3209: + if (tag_size != 4) + goto error; + self->display_width = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" display width = %u", self->display_width); + break; + case 0x320a: + if (tag_size != 4) + goto error; + self->display_x_offset = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" display x offset = %d", self->display_x_offset); + break; + case 0x320b: + if (tag_size != 4) + goto error; + self->display_y_offset = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" display y offset = %d", self->display_y_offset); + break; + case 0x3217: + if (tag_size != 4) + goto error; + self->display_f2_offset = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" display f2 offset = %d", self->display_f2_offset); + break; + case 0x320e: + if (!mxf_fraction_parse (&self->aspect_ratio, tag_data, tag_size)) + goto error; + GST_DEBUG (" aspect ratio = %d/%d", self->aspect_ratio.n, + self->aspect_ratio.d); + break; + case 0x3218: + if (tag_size != 1) + goto error; + self->active_format_descriptor = GST_READ_UINT8 (tag_data); + GST_DEBUG (" active format descriptor = %u", + self->active_format_descriptor); + break; + case 0x320d: + if (tag_size < 8) + goto error; + + if (GST_READ_UINT32_BE (tag_data) == 0) + return TRUE; + + if (GST_READ_UINT32_BE (tag_data) != 2 && + GST_READ_UINT32_BE (tag_data + 4) != 4) + goto error; + + if (tag_size != 16) + goto error; + + self->video_line_map[0] = GST_READ_UINT32_BE (tag_data + 8); + self->video_line_map[1] = GST_READ_UINT32_BE (tag_data + 12); + GST_DEBUG (" video line map = {%i, %i}", self->video_line_map[0], + self->video_line_map[1]); + break; + case 0x320f: + if (tag_size != 1) + goto error; + self->alpha_transparency = GST_READ_UINT8 (tag_data); + GST_DEBUG (" alpha transparency = %u", self->alpha_transparency); + break; + case 0x3210: + if (tag_size != 16) + goto error; + memcpy (&self->capture_gamma, tag_data, 16); + GST_DEBUG (" capture gamma = %s", + mxf_ul_to_string (&self->capture_gamma, str)); + break; + case 0x3211: + if (tag_size != 4) + goto error; + self->image_alignment_offset = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" image alignment offset = %u", self->image_alignment_offset); + break; + case 0x3213: + if (tag_size != 4) + goto error; + self->image_start_offset = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" image start offset = %u", self->image_start_offset); + break; + case 0x3214: + if (tag_size != 4) + goto error; + self->image_end_offset = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" image end offset = %u", self->image_end_offset); + break; + case 0x3212: + if (tag_size != 1) + goto error; + self->field_dominance = GST_READ_UINT8 (tag_data); + GST_DEBUG (" field dominance = %u", self->field_dominance); + break; + case 0x3201: + if (tag_size != 16) + goto error; + memcpy (&self->picture_essence_coding, tag_data, 16); + GST_DEBUG (" picture essence coding = %s", + mxf_ul_to_string (&self->picture_essence_coding, str)); + break; + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_generic_picture_essence_descriptor_parent_class)-> + handle_tag (metadata, primer, tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR + ("Invalid generic picture essence descriptor local tag 0x%04x of size %u", + tag, tag_size); + + return FALSE; +} + +static void + mxf_metadata_generic_picture_essence_descriptor_init + (MXFMetadataGenericPictureEssenceDescriptor * self) +{ + self->signal_standard = 1; +} + +static void + mxf_metadata_generic_picture_essence_descriptor_class_init + (MXFMetadataGenericPictureEssenceDescriptorClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + + metadata_base_class->handle_tag = + mxf_metadata_generic_picture_essence_descriptor_handle_tag; +} + +void mxf_metadata_generic_picture_essence_descriptor_set_caps + (MXFMetadataGenericPictureEssenceDescriptor * self, GstCaps * caps) +{ + guint par_n, par_d; + guint width, height; + MXFMetadataFileDescriptor *f = (MXFMetadataFileDescriptor *) self; + + g_return_if_fail (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (self)); + g_return_if_fail (GST_IS_CAPS (caps)); + + gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION, f->sample_rate.n, + f->sample_rate.d, NULL); + + width = self->stored_width; + height = self->stored_height; + + /* If the video is stored as separate fields the + * height is only the height of one field, i.e. + * half the height of the frame. + * + * See SMPTE 377M E2.2 and E1.2 + */ + if (self->frame_layout != 0) + height *= 2; + + if (width == 0 || height == 0) + return; + + gst_caps_set_simple (caps, "width", G_TYPE_INT, width, "height", G_TYPE_INT, + height, NULL); + + if (self->aspect_ratio.n == 0 || self->aspect_ratio.d == 0) + return; + + par_n = height * self->aspect_ratio.n; + par_d = width * self->aspect_ratio.d; + + gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION, + par_n, par_d, NULL); +} + +G_DEFINE_TYPE (MXFMetadataGenericSoundEssenceDescriptor, + mxf_metadata_generic_sound_essence_descriptor, + MXF_TYPE_METADATA_FILE_DESCRIPTOR); + +static gboolean +mxf_metadata_generic_sound_essence_descriptor_handle_tag (MXFMetadataBase * + metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataGenericSoundEssenceDescriptor *self = + MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (metadata); + gboolean ret = TRUE; + gchar str[48]; + + switch (tag) { + case 0x3d03: + if (!mxf_fraction_parse (&self->audio_sampling_rate, tag_data, tag_size)) + goto error; + GST_DEBUG (" audio sampling rate = %d/%d", + self->audio_sampling_rate.n, self->audio_sampling_rate.d); + break; + case 0x3d02: + if (tag_size != 1) + goto error; + self->locked = (GST_READ_UINT8 (tag_data) != 0); + GST_DEBUG (" locked = %s", (self->locked) ? "yes" : "no"); + break; + case 0x3d04: + if (tag_size != 1) + goto error; + self->audio_ref_level = GST_READ_UINT8 (tag_data); + GST_DEBUG (" audio ref level = %d", self->audio_ref_level); + break; + case 0x3d05: + if (tag_size != 1) + goto error; + self->electro_spatial_formulation = GST_READ_UINT8 (tag_data); + GST_DEBUG (" electro spatial formulation = %u", + self->electro_spatial_formulation); + break; + case 0x3d07: + if (tag_size != 4) + goto error; + self->channel_count = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" channel count = %u", self->channel_count); + break; + case 0x3d01: + if (tag_size != 4) + goto error; + self->quantization_bits = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" quantization bits = %u", self->quantization_bits); + break; + case 0x3d0c: + if (tag_size != 1) + goto error; + self->dial_norm = GST_READ_UINT8 (tag_data); + GST_DEBUG (" dial norm = %d", self->dial_norm); + break; + case 0x3d06: + if (tag_size != 16) + goto error; + memcpy (&self->sound_essence_compression, tag_data, 16); + GST_DEBUG (" sound essence compression = %s", + mxf_ul_to_string (&self->sound_essence_compression, str)); + break; + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_generic_sound_essence_descriptor_parent_class)-> + handle_tag (metadata, primer, tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR + ("Invalid generic sound essence descriptor local tag 0x%04x of size %u", + tag, tag_size); + + return FALSE; +} + +static void + mxf_metadata_generic_sound_essence_descriptor_init + (MXFMetadataGenericSoundEssenceDescriptor * self) +{ + self->audio_sampling_rate.n = 48000; + self->audio_sampling_rate.d = 1; +} + +static void + mxf_metadata_generic_sound_essence_descriptor_class_init + (MXFMetadataGenericSoundEssenceDescriptorClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + + metadata_base_class->handle_tag = + mxf_metadata_generic_sound_essence_descriptor_handle_tag; +} + +G_DEFINE_TYPE (MXFMetadataCDCIPictureEssenceDescriptor, + mxf_metadata_cdci_picture_essence_descriptor, + MXF_TYPE_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR); + +static gboolean +mxf_metadata_cdci_picture_essence_descriptor_handle_tag (MXFMetadataBase * + metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataCDCIPictureEssenceDescriptor *self = + MXF_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (metadata); + gboolean ret = TRUE; + + switch (tag) { + case 0x3301: + if (tag_size != 4) + goto error; + self->component_depth = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" component depth = %u", self->component_depth); + break; + case 0x3302: + if (tag_size != 4) + goto error; + self->horizontal_subsampling = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" horizontal subsampling = %u", self->horizontal_subsampling); + break; + case 0x3308: + if (tag_size != 4) + goto error; + self->vertical_subsampling = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" vertical subsampling = %u", self->vertical_subsampling); + break; + case 0x3303: + if (tag_size != 1) + goto error; + self->color_siting = GST_READ_UINT8 (tag_data); + GST_DEBUG (" color siting = %u", self->color_siting); + break; + case 0x330b: + if (tag_size != 1) + goto error; + self->reversed_byte_order = GST_READ_UINT8 (tag_data); + GST_DEBUG (" reversed byte order = %s", + (self->reversed_byte_order) ? "yes" : "no"); + break; + case 0x3307: + if (tag_size != 2) + goto error; + self->padding_bits = GST_READ_UINT16_BE (tag_data); + GST_DEBUG (" padding bits = %d", self->padding_bits); + break; + case 0x3309: + if (tag_size != 4) + goto error; + self->alpha_sample_depth = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" alpha sample depth = %u", self->alpha_sample_depth); + break; + case 0x3304: + if (tag_size != 4) + goto error; + self->black_ref_level = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" black ref level = %u", self->black_ref_level); + break; + case 0x3305: + if (tag_size != 4) + goto error; + self->white_ref_level = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" white ref level = %u", self->white_ref_level); + break; + case 0x3306: + if (tag_size != 4) + goto error; + self->color_range = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" color range = %u", self->color_range); + break; + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_cdci_picture_essence_descriptor_parent_class)-> + handle_tag (metadata, primer, tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR + ("Invalid CDCI picture essence descriptor local tag 0x%04x of size %u", + tag, tag_size); + + return FALSE; +} + +static void + mxf_metadata_cdci_picture_essence_descriptor_init + (MXFMetadataCDCIPictureEssenceDescriptor * self) +{ + +} + +static void + mxf_metadata_cdci_picture_essence_descriptor_class_init + (MXFMetadataCDCIPictureEssenceDescriptorClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + + metadata_base_class->handle_tag = + mxf_metadata_cdci_picture_essence_descriptor_handle_tag; +} + +G_DEFINE_TYPE (MXFMetadataRGBAPictureEssenceDescriptor, + mxf_metadata_rgba_picture_essence_descriptor, + MXF_TYPE_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR); + +static void +mxf_metadata_rgba_picture_essence_descriptor_finalize (GstMiniObject * object) +{ + MXFMetadataRGBAPictureEssenceDescriptor *self = + MXF_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (object); + + g_free (self->pixel_layout); + self->pixel_layout = NULL; + + GST_MINI_OBJECT_CLASS + (mxf_metadata_rgba_picture_essence_descriptor_parent_class)->finalize + (object); +} + +static gboolean +mxf_metadata_rgba_picture_essence_descriptor_handle_tag (MXFMetadataBase * + metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataRGBAPictureEssenceDescriptor *self = + MXF_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (metadata); + gboolean ret = TRUE; + + switch (tag) { + case 0x3406: + if (tag_size != 4) + goto error; + self->component_max_ref = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" component max ref = %u", self->component_max_ref); + break; + case 0x3407: + if (tag_size != 4) + goto error; + self->component_min_ref = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" component min ref = %u", self->component_min_ref); + break; + case 0x3408: + if (tag_size != 4) + goto error; + self->alpha_max_ref = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" alpha max ref = %u", self->alpha_max_ref); + break; + case 0x3409: + if (tag_size != 4) + goto error; + self->alpha_min_ref = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" alpha min ref = %u", self->alpha_min_ref); + break; + case 0x3405: + if (tag_size != 1) + goto error; + self->scanning_direction = GST_READ_UINT8 (tag_data); + GST_DEBUG (" scanning direction = %u", self->scanning_direction); + break; + case 0x3401:{ + guint i, len; + + if (tag_size % 2 != 0) + goto error; + + i = 0; + while (tag_data[i] != 0 && tag_data[i + 1] != 0 && i + 2 <= tag_size) + i += 2; + len = i / 2; + + self->n_pixel_layout = len; + GST_DEBUG (" number of pixel layouts = %u", len); + if (len == 0) + return TRUE; + + self->pixel_layout = g_malloc0 (2 * len); + + for (i = 0; i < len; i++) { + self->pixel_layout[2 * i] = tag_data[2 * i]; + self->pixel_layout[2 * i + 1] = tag_data[2 * i + 1]; + GST_DEBUG (" pixel layout %u = %c : %u", i, + (gchar) self->pixel_layout[2 * i], self->pixel_layout[2 * i + 1]); + } + + break; + } + case 0x3403: + case 0x3404: + /* TODO: handle this */ + GST_WARNING (" tag 0x%04x not implemented yet", tag); + break; + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_rgba_picture_essence_descriptor_parent_class)-> + handle_tag (metadata, primer, tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR + ("Invalid RGBA picture essence descriptor local tag 0x%04x of size %u", + tag, tag_size); + + return FALSE; +} + +static void + mxf_metadata_rgba_picture_essence_descriptor_init + (MXFMetadataRGBAPictureEssenceDescriptor * self) +{ + self->component_max_ref = 255; + self->alpha_max_ref = 255; +} + +static void + mxf_metadata_rgba_picture_essence_descriptor_class_init + (MXFMetadataRGBAPictureEssenceDescriptorClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + + miniobject_class->finalize = + mxf_metadata_rgba_picture_essence_descriptor_finalize; + metadata_base_class->handle_tag = + mxf_metadata_rgba_picture_essence_descriptor_handle_tag; +} + +G_DEFINE_TYPE (MXFMetadataGenericDataEssenceDescriptor, + mxf_metadata_generic_data_essence_descriptor, + MXF_TYPE_METADATA_FILE_DESCRIPTOR); + +static gboolean +mxf_metadata_generic_data_essence_descriptor_handle_tag (MXFMetadataBase * + metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataGenericDataEssenceDescriptor *self = + MXF_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR (metadata); + gboolean ret = TRUE; + gchar str[48]; + + switch (tag) { + case 0x3e01: + if (tag_size != 16) + goto error; + memcpy (&self->data_essence_compression, tag_data, 16); + GST_DEBUG (" data essence compression = %s", + mxf_ul_to_string (&self->data_essence_compression, str)); + break; + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_generic_data_essence_descriptor_parent_class)-> + handle_tag (metadata, primer, tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR + ("Invalid generic data essence descriptor local tag 0x%04x of size %u", + tag, tag_size); + + return FALSE; +} + +static void + mxf_metadata_generic_data_essence_descriptor_init + (MXFMetadataGenericDataEssenceDescriptor * self) +{ + +} + +static void + mxf_metadata_generic_data_essence_descriptor_class_init + (MXFMetadataGenericDataEssenceDescriptorClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + + metadata_base_class->handle_tag = + mxf_metadata_generic_data_essence_descriptor_handle_tag; +} + +G_DEFINE_TYPE (MXFMetadataMultipleDescriptor, mxf_metadata_multiple_descriptor, + MXF_TYPE_METADATA_FILE_DESCRIPTOR); + +static void +mxf_metadata_multiple_descriptor_finalize (GstMiniObject * object) +{ + MXFMetadataMultipleDescriptor *self = + MXF_METADATA_MULTIPLE_DESCRIPTOR (object); + + g_free (self->sub_descriptors_uids); + self->sub_descriptors_uids = NULL; + g_free (self->sub_descriptors); + self->sub_descriptors = NULL; + + GST_MINI_OBJECT_CLASS (mxf_metadata_multiple_descriptor_parent_class)-> + finalize (object); +} + +static gboolean +mxf_metadata_multiple_descriptor_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataMultipleDescriptor *self = + MXF_METADATA_MULTIPLE_DESCRIPTOR (metadata); + gboolean ret = TRUE; + gchar str[48]; + + switch (tag) { + case 0x3f01:{ + guint32 len; + guint i; + + if (tag_size < 8) + goto error; + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of sub descriptors = %u", len); + if (len == 0) + return TRUE; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + + tag_data += 8; + tag_size -= 8; + if (tag_size < len * 16) + goto error; + + self->n_sub_descriptors = len; + self->sub_descriptors_uids = g_new (MXFUL, len); + for (i = 0; i < len; i++) { + memcpy (&self->sub_descriptors_uids[i], tag_data, 16); + tag_data += 16; + tag_size -= 16; + GST_DEBUG (" sub descriptor %u = %s", i, + mxf_ul_to_string (&self->sub_descriptors_uids[i], str)); + } + + break; + } + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_multiple_descriptor_parent_class)->handle_tag (metadata, + primer, tag, tag_data, tag_size); + break; + } + + return ret; + +error: + + GST_ERROR ("Invalid multiple descriptor local tag 0x%04x of size %u", tag, + tag_size); + + return TRUE; +} + +static gboolean +mxf_metadata_multiple_descriptor_resolve (MXFMetadataBase * m, + MXFMetadataBase ** metadata) +{ + MXFMetadataMultipleDescriptor *self = MXF_METADATA_MULTIPLE_DESCRIPTOR (m); + MXFMetadataBase **p, *current; + guint i, have_subdescriptors = 0; + + self->sub_descriptors = + g_new0 (MXFMetadataGenericDescriptor *, self->n_sub_descriptors); + for (i = 0; i < self->n_sub_descriptors; i++) { + p = metadata; + while (*p) { + current = *p; + if (MXF_IS_METADATA_GENERIC_DESCRIPTOR (current) && + mxf_ul_is_equal (¤t->instance_uid, + &self->sub_descriptors_uids[i])) { + if (mxf_metadata_resolve (current, metadata)) { + self->sub_descriptors[i] = MXF_METADATA_GENERIC_DESCRIPTOR (current); + have_subdescriptors++; + } + break; + } + p++; + } + } + + if (have_subdescriptors != self->n_sub_descriptors) { + GST_ERROR ("Couldn't resolve all subdescriptors"); + return FALSE; + } + + return + MXF_METADATA_BASE_CLASS (mxf_metadata_multiple_descriptor_parent_class)-> + resolve (m, metadata); +} + +static void +mxf_metadata_multiple_descriptor_init (MXFMetadataMultipleDescriptor * self) +{ + +} + +static void +mxf_metadata_multiple_descriptor_class_init (MXFMetadataMultipleDescriptorClass + * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + + miniobject_class->finalize = mxf_metadata_multiple_descriptor_finalize; + metadata_base_class->handle_tag = mxf_metadata_multiple_descriptor_handle_tag; + metadata_base_class->resolve = mxf_metadata_multiple_descriptor_resolve; +} + +G_DEFINE_ABSTRACT_TYPE (MXFMetadataLocator, mxf_metadata_locator, + MXF_TYPE_METADATA); + +static void +mxf_metadata_locator_init (MXFMetadataLocator * self) +{ +} + +static void +mxf_metadata_locator_class_init (MXFMetadataLocatorClass * klass) +{ +} + +G_DEFINE_TYPE (MXFMetadataTextLocator, mxf_metadata_text_locator, + MXF_TYPE_METADATA_LOCATOR); + +static void +mxf_metadata_text_locator_finalize (GstMiniObject * object) +{ + MXFMetadataTextLocator *self = MXF_METADATA_TEXT_LOCATOR (object); + + g_free (self->locator_name); + self->locator_name = NULL; + + GST_MINI_OBJECT_CLASS (mxf_metadata_text_locator_parent_class)->finalize + (object); +} + +static gboolean +mxf_metadata_text_locator_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataTextLocator *self = MXF_METADATA_TEXT_LOCATOR (metadata); + gboolean ret = TRUE; + + switch (tag) { + case 0x4101: + self->locator_name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" text locator = %s", GST_STR_NULL (self->locator_name)); + break; + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_text_locator_parent_class)->handle_tag (metadata, + primer, tag, tag_data, tag_size); + break; + } + + return ret; +} + +static void +mxf_metadata_text_locator_init (MXFMetadataTextLocator * self) +{ + +} + +static void +mxf_metadata_text_locator_class_init (MXFMetadataTextLocatorClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + + miniobject_class->finalize = mxf_metadata_text_locator_finalize; + metadata_base_class->handle_tag = mxf_metadata_text_locator_handle_tag; +} + +G_DEFINE_TYPE (MXFMetadataNetworkLocator, mxf_metadata_network_locator, + MXF_TYPE_METADATA_LOCATOR); + +static void +mxf_metadata_network_locator_finalize (GstMiniObject * object) +{ + MXFMetadataNetworkLocator *self = MXF_METADATA_NETWORK_LOCATOR (object); + + g_free (self->url_string); + self->url_string = NULL; + + GST_MINI_OBJECT_CLASS (mxf_metadata_network_locator_parent_class)->finalize + (object); +} + +static gboolean +mxf_metadata_network_locator_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFMetadataNetworkLocator *self = MXF_METADATA_NETWORK_LOCATOR (metadata); + gboolean ret = TRUE; + + switch (tag) { + case 0x4101: + self->url_string = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" url string = %s", GST_STR_NULL (self->url_string)); + break; + default: + ret = + MXF_METADATA_BASE_CLASS + (mxf_metadata_network_locator_parent_class)->handle_tag (metadata, + primer, tag, tag_data, tag_size); + break; + } + + return ret; +} + +static void +mxf_metadata_network_locator_init (MXFMetadataNetworkLocator * self) +{ +} + +static void +mxf_metadata_network_locator_class_init (MXFMetadataNetworkLocatorClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + + miniobject_class->finalize = mxf_metadata_network_locator_finalize; + metadata_base_class->handle_tag = mxf_metadata_network_locator_handle_tag; +} diff --git a/gst/mxf/mxfmetadata.h b/gst/mxf/mxfmetadata.h new file mode 100644 index 00000000..e24ce882 --- /dev/null +++ b/gst/mxf/mxfmetadata.h @@ -0,0 +1,703 @@ +/* GStreamer + * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* Handling of MXF structural metadata */ + +#ifndef __MXF_METADATA_H__ +#define __MXF_METADATA_H__ + +#include <gst/gst.h> +#include "mxftypes.h" + +#define MXF_TYPE_METADATA_BASE \ + (mxf_metadata_base_get_type()) +#define MXF_METADATA_BASE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_BASE, MXFMetadataBase)) +#define MXF_IS_METADATA_BASE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_BASE)) +#define MXF_METADATA_BASE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), MXF_TYPE_METADATA_BASE, MXFMetadataBaseClass)) +#define MXF_METADATA_BASE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),MXF_TYPE_METADATA_BASE,MXFMetadataBaseClass)) +typedef struct _MXFMetadataBase MXFMetadataBase; +typedef struct _MXFMetadataBaseClass MXFMetadataBaseClass; +GType mxf_metadata_base_get_type (void); + +#define MXF_TYPE_METADATA \ + (mxf_metadata_get_type()) +#define MXF_METADATA(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA, MXFMetadata)) +#define MXF_IS_METADATA(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA)) +#define MXF_METADATA_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), MXF_TYPE_METADATA, MXFMetadataClass)) +#define MXF_METADATA_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),MXF_TYPE_METADATA,MXFMetadataClass)) +typedef struct _MXFMetadata MXFMetadata; +typedef MXFMetadataBaseClass MXFMetadataClass; +GType mxf_metadata_get_type (void); + +#define MXF_TYPE_METADATA_PREFACE \ + (mxf_metadata_preface_get_type()) +#define MXF_METADATA_PREFACE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_PREFACE,MXFMetadataPreface)) +#define MXF_IS_METADATA_PREFACE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_PREFACE)) +typedef struct _MXFMetadataPreface MXFMetadataPreface; +typedef MXFMetadataBaseClass MXFMetadataPrefaceClass; +GType mxf_metadata_preface_get_type (void); + +#define MXF_TYPE_METADATA_IDENTIFICATION \ + (mxf_metadata_identification_get_type()) +#define MXF_METADATA_IDENTIFICATION(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_IDENTIFICATION,MXFMetadataIdentification)) +#define MXF_IS_METADATA_IDENTIFICATION(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_IDENTIFICATION)) +typedef struct _MXFMetadataIdentification MXFMetadataIdentification; +typedef MXFMetadataBaseClass MXFMetadataIdentificationClass; +GType mxf_metadata_identification_get_type (void); + +#define MXF_TYPE_METADATA_CONTENT_STORAGE \ + (mxf_metadata_content_storage_get_type()) +#define MXF_METADATA_CONTENT_STORAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_CONTENT_STORAGE, MXFMetadataContentStorage)) +#define MXF_IS_METADATA_CONTENT_STORAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_CONTENT_STORAGE)) +typedef struct _MXFMetadataContentStorage MXFMetadataContentStorage; +typedef MXFMetadataBaseClass MXFMetadataContentStorageClass; +GType mxf_metadata_content_storage_get_type (void); + +#define MXF_TYPE_METADATA_ESSENCE_CONTAINER_DATA \ + (mxf_metadata_essence_container_data_get_type()) +#define MXF_METADATA_ESSENCE_CONTAINER_DATA(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_ESSENCE_CONTAINER_DATA, MXFMetadataEssenceContainerData)) +#define MXF_IS_METADATA_ESSENCE_CONTAINER_DATA(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_ESSENCE_CONTAINER_DATA)) +typedef struct _MXFMetadataEssenceContainerData MXFMetadataEssenceContainerData; +typedef MXFMetadataBaseClass MXFMetadataEssenceContainerDataClass; +GType mxf_metadata_essence_container_data_get_type (void); + +#define MXF_TYPE_METADATA_GENERIC_PACKAGE \ + (mxf_metadata_generic_package_get_type()) +#define MXF_METADATA_GENERIC_PACKAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_GENERIC_PACKAGE, MXFMetadataGenericPackage)) +#define MXF_IS_METADATA_GENERIC_PACKAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_GENERIC_PACKAGE)) +typedef struct _MXFMetadataGenericPackage MXFMetadataGenericPackage; +typedef MXFMetadataBaseClass MXFMetadataGenericPackageClass; +GType mxf_metadata_generic_package_get_type (void); + +#define MXF_TYPE_METADATA_MATERIAL_PACKAGE \ + (mxf_metadata_material_package_get_type()) +#define MXF_METADATA_MATERIAL_PACKAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_MATERIAL_PACKAGE, MXFMetadataMaterialPackage)) +#define MXF_IS_METADATA_MATERIAL_PACKAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_MATERIAL_PACKAGE)) +typedef MXFMetadataGenericPackage MXFMetadataMaterialPackage; +typedef MXFMetadataBaseClass MXFMetadataMaterialPackageClass; +GType mxf_metadata_material_package_get_type (void); + +#define MXF_TYPE_METADATA_SOURCE_PACKAGE \ + (mxf_metadata_source_package_get_type()) +#define MXF_METADATA_SOURCE_PACKAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_SOURCE_PACKAGE, MXFMetadataSourcePackage)) +#define MXF_IS_METADATA_SOURCE_PACKAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_SOURCE_PACKAGE)) +typedef struct _MXFMetadataSourcePackage MXFMetadataSourcePackage; +typedef MXFMetadataBaseClass MXFMetadataSourcePackageClass; +GType mxf_metadata_source_package_get_type (void); + +#define MXF_TYPE_METADATA_TRACK \ + (mxf_metadata_track_get_type()) +#define MXF_METADATA_TRACK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_TRACK, MXFMetadataTrack)) +#define MXF_IS_METADATA_TRACK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_TRACK)) +typedef struct _MXFMetadataTrack MXFMetadataTrack; +typedef MXFMetadataBaseClass MXFMetadataTrackClass; +GType mxf_metadata_track_get_type (void); + +#define MXF_TYPE_METADATA_TIMELINE_TRACK \ + (mxf_metadata_timeline_track_get_type()) +#define MXF_METADATA_TIMELINE_TRACK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_TIMELINE_TRACK, MXFMetadataTimelineTrack)) +#define MXF_IS_METADATA_TIMELINE_TRACK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_TIMELINE_TRACK)) +typedef struct _MXFMetadataTimelineTrack MXFMetadataTimelineTrack; +typedef MXFMetadataBaseClass MXFMetadataTimelineTrackClass; +GType mxf_metadata_timeline_track_get_type (void); + +#define MXF_TYPE_METADATA_EVENT_TRACK \ + (mxf_metadata_event_track_get_type()) +#define MXF_METADATA_EVENT_TRACK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_EVENT_TRACK, MXFMetadataEventTrack)) +#define MXF_IS_METADATA_EVENT_TRACK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_EVENT_TRACK)) +typedef struct _MXFMetadataEventTrack MXFMetadataEventTrack; +typedef MXFMetadataBaseClass MXFMetadataEventTrackClass; +GType mxf_metadata_event_track_get_type (void); + +#define MXF_TYPE_METADATA_STATIC_TRACK \ + (mxf_metadata_static_track_get_type()) +#define MXF_METADATA_STATIC_TRACK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_STATIC_TRACK, MXFMetadataStaticTrack)) +#define MXF_IS_METADATA_STATIC_TRACK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_STATIC_TRACK)) +typedef MXFMetadataTrack MXFMetadataStaticTrack; +typedef MXFMetadataBaseClass MXFMetadataStaticTrackClass; +GType mxf_metadata_static_track_get_type (void); + +#define MXF_TYPE_METADATA_SEQUENCE \ + (mxf_metadata_sequence_get_type()) +#define MXF_METADATA_SEQUENCE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_SEQUENCE, MXFMetadataSequence)) +#define MXF_IS_METADATA_SEQUENCE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_SEQUENCE)) +typedef struct _MXFMetadataSequence MXFMetadataSequence; +typedef MXFMetadataBaseClass MXFMetadataSequenceClass; +GType mxf_metadata_sequence_get_type (void); + +#define MXF_TYPE_METADATA_STRUCTURAL_COMPONENT \ + (mxf_metadata_structural_component_get_type()) +#define MXF_METADATA_STRUCTURAL_COMPONENT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_STRUCTURAL_COMPONENT, MXFMetadataStructuralComponent)) +#define MXF_IS_METADATA_STRUCTURAL_COMPONENT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_STRUCTURAL_COMPONENT)) +typedef struct _MXFMetadataStructuralComponent MXFMetadataStructuralComponent; +typedef MXFMetadataBaseClass MXFMetadataStructuralComponentClass; +GType mxf_metadata_structural_component_get_type (void); + +#define MXF_TYPE_METADATA_SOURCE_CLIP \ + (mxf_metadata_source_clip_get_type()) +#define MXF_METADATA_SOURCE_CLIP(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_SOURCE_CLIP, MXFMetadataSourceClip)) +#define MXF_IS_METADATA_SOURCE_CLIP(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_SOURCE_CLIP)) +typedef struct _MXFMetadataSourceClip MXFMetadataSourceClip; +typedef MXFMetadataBaseClass MXFMetadataSourceClipClass; +GType mxf_metadata_source_clip_get_type (void); + +#define MXF_TYPE_METADATA_TIMECODE_COMPONENT \ + (mxf_metadata_timecode_component_get_type()) +#define MXF_METADATA_TIMECODE_COMPONENT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_TIMECODE_COMPONENT, MXFMetadataTimecodeComponent)) +#define MXF_IS_METADATA_TIMECODE_COMPONENT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_TIMECODE_COMPONENT)) +typedef struct _MXFMetadataTimecodeComponent MXFMetadataTimecodeComponent; +typedef MXFMetadataBaseClass MXFMetadataTimecodeComponentClass; +GType mxf_metadata_timecode_component_get_type (void); + +#define MXF_TYPE_METADATA_DM_SOURCE_CLIP \ + (mxf_metadata_dm_source_clip_get_type()) +#define MXF_METADATA_DM_SOURCE_CLIP(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_DM_SOURCE_CLIP, MXFMetadataDMSourceClip)) +#define MXF_IS_METADATA_DM_SOURCE_CLIP(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_DM_SOURCE_CLIP)) +typedef struct _MXFMetadataDMSourceClip MXFMetadataDMSourceClip; +typedef MXFMetadataBaseClass MXFMetadataDMSourceClipClass; +GType mxf_metadata_dm_source_clip_get_type (void); + +#define MXF_TYPE_METADATA_DM_SEGMENT \ + (mxf_metadata_dm_segment_get_type()) +#define MXF_METADATA_DM_SEGMENT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_DM_SEGMENT, MXFMetadataDMSegment)) +#define MXF_IS_METADATA_DM_SEGMENT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_DM_SEGMENT)) +typedef struct _MXFMetadataDMSegment MXFMetadataDMSegment; +typedef MXFMetadataBaseClass MXFMetadataDMSegmentClass; +GType mxf_metadata_dm_segment_get_type (void); + +#define MXF_TYPE_METADATA_GENERIC_DESCRIPTOR \ + (mxf_metadata_generic_descriptor_get_type()) +#define MXF_METADATA_GENERIC_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_GENERIC_DESCRIPTOR, MXFMetadataGenericDescriptor)) +#define MXF_IS_METADATA_GENERIC_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_GENERIC_DESCRIPTOR)) +typedef struct _MXFMetadataGenericDescriptor MXFMetadataGenericDescriptor; +typedef MXFMetadataBaseClass MXFMetadataGenericDescriptorClass; +GType mxf_metadata_generic_descriptor_get_type (void); + +#define MXF_TYPE_METADATA_FILE_DESCRIPTOR \ + (mxf_metadata_file_descriptor_get_type()) +#define MXF_METADATA_FILE_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_FILE_DESCRIPTOR, MXFMetadataFileDescriptor)) +#define MXF_IS_METADATA_FILE_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_FILE_DESCRIPTOR)) +typedef struct _MXFMetadataFileDescriptor MXFMetadataFileDescriptor; +typedef MXFMetadataBaseClass MXFMetadataFileDescriptorClass; +GType mxf_metadata_file_descriptor_get_type (void); + +#define MXF_TYPE_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR \ + (mxf_metadata_generic_picture_essence_descriptor_get_type()) +#define MXF_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR, MXFMetadataGenericPictureEssenceDescriptor)) +#define MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR)) +typedef struct _MXFMetadataGenericPictureEssenceDescriptor MXFMetadataGenericPictureEssenceDescriptor; +typedef MXFMetadataBaseClass MXFMetadataGenericPictureEssenceDescriptorClass; +GType mxf_metadata_generic_picture_essence_descriptor_get_type (void); + +#define MXF_TYPE_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR \ + (mxf_metadata_cdci_picture_essence_descriptor_get_type()) +#define MXF_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR, MXFMetadataCDCIPictureEssenceDescriptor)) +#define MXF_IS_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR)) +typedef struct _MXFMetadataCDCIPictureEssenceDescriptor MXFMetadataCDCIPictureEssenceDescriptor; +typedef MXFMetadataBaseClass MXFMetadataCDCIPictureEssenceDescriptorClass; +GType mxf_metadata_cdci_picture_essence_descriptor_get_type (void); + +#define MXF_TYPE_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR \ + (mxf_metadata_rgba_picture_essence_descriptor_get_type()) +#define MXF_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR, MXFMetadataRGBAPictureEssenceDescriptor)) +#define MXF_IS_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR)) +typedef struct _MXFMetadataRGBAPictureEssenceDescriptor MXFMetadataRGBAPictureEssenceDescriptor; +typedef MXFMetadataBaseClass MXFMetadataRGBAPictureEssenceDescriptorClass; +GType mxf_metadata_rgba_picture_essence_descriptor_get_type (void); + +#define MXF_TYPE_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR \ + (mxf_metadata_generic_sound_essence_descriptor_get_type()) +#define MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR, MXFMetadataGenericSoundEssenceDescriptor)) +#define MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR)) +typedef struct _MXFMetadataGenericSoundEssenceDescriptor MXFMetadataGenericSoundEssenceDescriptor; +typedef MXFMetadataBaseClass MXFMetadataGenericSoundEssenceDescriptorClass; +GType mxf_metadata_generic_sound_essence_descriptor_get_type (void); + +#define MXF_TYPE_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR \ + (mxf_metadata_generic_data_essence_descriptor_get_type()) +#define MXF_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR, MXFMetadataGenericDataEssenceDescriptor)) +#define MXF_IS_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR)) +typedef struct _MXFMetadataGenericDataEssenceDescriptor MXFMetadataGenericDataEssenceDescriptor; +typedef MXFMetadataBaseClass MXFMetadataGenericDataEssenceDescriptorClass; +GType mxf_metadata_generic_data_essence_descriptor_get_type (void); + +#define MXF_TYPE_METADATA_MULTIPLE_DESCRIPTOR \ + (mxf_metadata_multiple_descriptor_get_type()) +#define MXF_METADATA_MULTIPLE_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_MULTIPLE_DESCRIPTOR, MXFMetadataMultipleDescriptor)) +#define MXF_IS_METADATA_MULTIPLE_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_MULTIPLE_DESCRIPTOR)) +typedef struct _MXFMetadataMultipleDescriptor MXFMetadataMultipleDescriptor; +typedef MXFMetadataBaseClass MXFMetadataMultipleDescriptorClass; +GType mxf_metadata_multiple_descriptor_get_type (void); + +#define MXF_TYPE_METADATA_LOCATOR \ + (mxf_metadata_locator_get_type()) +#define MXF_METADATA_LOCATOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_LOCATOR, MXFMetadataLocator)) +#define MXF_IS_METADATA_LOCATOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_LOCATOR)) +typedef struct _MXFMetadataLocator MXFMetadataLocator; +typedef MXFMetadataBaseClass MXFMetadataLocatorClass; +GType mxf_metadata_locator_get_type (void); + +#define MXF_TYPE_METADATA_NETWORK_LOCATOR \ + (mxf_metadata_network_locator_get_type()) +#define MXF_METADATA_NETWORK_LOCATOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_NETWORK_LOCATOR, MXFMetadataNetworkLocator)) +#define MXF_IS_METADATA_NETWORK_LOCATOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_NETWORK_LOCATOR)) +typedef struct _MXFMetadataNetworkLocator MXFMetadataNetworkLocator; +typedef MXFMetadataBaseClass MXFMetadataNetworkLocatorClass; +GType mxf_metadata_network_locator_get_type (void); + +#define MXF_TYPE_METADATA_TEXT_LOCATOR \ + (mxf_metadata_text_locator_get_type()) +#define MXF_METADATA_TEXT_LOCATOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_TEXT_LOCATOR, MXFMetadataTextLocator)) +#define MXF_IS_METADATA_TEXT_LOCATOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_TEXT_LOCATOR)) +typedef struct _MXFMetadataTextLocator MXFMetadataTextLocator; +typedef MXFMetadataBaseClass MXFMetadataTextLocatorClass; +GType mxf_metadata_text_locator_get_type (void); + +struct _MXFMetadataBase { + GstMiniObject parent; + + MXFUL instance_uid; + MXFUL generation_uid; + + gboolean resolved; + + GHashTable *other_tags; +}; + +struct _MXFMetadataBaseClass { + GstMiniObjectClass parent; + + gboolean (*handle_tag) (MXFMetadataBase *self, MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint tag_size); + gboolean (*resolve) (MXFMetadataBase *self, MXFMetadataBase **metadata); +}; + +struct _MXFMetadata { + MXFMetadataBase parent; + + guint16 type; +}; + +struct _MXFMetadataPreface { + MXFMetadata parent; + + MXFTimestamp last_modified_date; + guint16 version; + + guint32 object_model_version; + + MXFUL primary_package_uid; + MXFMetadataGenericPackage *primary_package; + + guint32 n_identifications; + MXFUL *identifications_uids; + MXFMetadataIdentification **identifications; + + MXFUL content_storage_uid; + MXFMetadataContentStorage *content_storage; + + MXFUL operational_pattern; + + guint32 n_essence_containers; + MXFUL *essence_containers; + + guint32 n_dm_schemes; + MXFUL *dm_schemes; +}; + +struct _MXFMetadataIdentification { + MXFMetadata parent; + + gchar *company_name; + + gchar *product_name; + MXFProductVersion product_version; + + gchar *version_string; + + MXFUL product_uid; + + MXFTimestamp modification_date; + + MXFProductVersion toolkit_version; + + gchar *platform; +}; + +struct _MXFMetadataContentStorage { + MXFMetadata parent; + + guint32 n_packages; + MXFUL *packages_uids; + MXFMetadataGenericPackage **packages; + + guint32 n_essence_container_data; + MXFUL *essence_container_data_uids; + MXFMetadataEssenceContainerData **essence_container_data; +}; + +struct _MXFMetadataEssenceContainerData { + MXFMetadata parent; + + MXFUMID linked_package_uid; + MXFMetadataSourcePackage *linked_package; + + guint32 index_sid; + guint32 body_sid; +}; + +struct _MXFMetadataGenericPackage { + MXFMetadata parent; + + MXFUMID package_uid; + + gchar *name; + MXFTimestamp package_creation_date; + MXFTimestamp package_modified_date; + + guint32 n_tracks; + MXFUL *tracks_uids; + MXFMetadataTrack **tracks; + + guint n_timecode_tracks; + guint n_metadata_tracks; + guint n_essence_tracks; + guint n_other_tracks; +}; + +struct _MXFMetadataSourcePackage +{ + MXFMetadataGenericPackage parent; + + MXFUL descriptors_uid; + guint32 n_descriptors; + MXFMetadataGenericDescriptor **descriptors; + + gboolean top_level; +}; + +typedef enum { + MXF_METADATA_TRACK_UNKNOWN = 0x00, + MXF_METADATA_TRACK_TIMECODE_12M_INACTIVE = 0x10, + MXF_METADATA_TRACK_TIMECODE_12M_ACTIVE = 0x11, + MXF_METADATA_TRACK_TIMECODE_309M = 0x12, + MXF_METADATA_TRACK_METADATA = 0x20, + MXF_METADATA_TRACK_PICTURE_ESSENCE = 0x30, + MXF_METADATA_TRACK_SOUND_ESSENCE = 0x31, + MXF_METADATA_TRACK_DATA_ESSENCE = 0x32, + MXF_METADATA_TRACK_AUXILIARY_DATA = 0x40, + MXF_METADATA_TRACK_PARSED_TEXT = 0x41 +} MXFMetadataTrackType; + +struct _MXFMetadataTrack { + MXFMetadata parent; + + guint32 track_id; + guint32 track_number; + + gchar *track_name; + + MXFUL sequence_uid; + MXFMetadataSequence *sequence; + + MXFMetadataTrackType type; + + MXFMetadataFileDescriptor **descriptor; + guint n_descriptor; +}; + +struct _MXFMetadataTimelineTrack { + MXFMetadataTrack parent; + + MXFFraction edit_rate; + gint64 origin; +}; + +struct _MXFMetadataEventTrack { + MXFMetadataTrack parent; + + MXFFraction event_edit_rate; + gint64 event_origin; +}; + +struct _MXFMetadataSequence { + MXFMetadata parent; + + MXFUL data_definition; + + gint64 duration; + + guint32 n_structural_components; + MXFUL *structural_components_uids; + MXFMetadataStructuralComponent **structural_components; +}; + +struct _MXFMetadataStructuralComponent { + MXFMetadata parent; + + MXFUL data_definition; + gint64 duration; +}; + +struct _MXFMetadataTimecodeComponent { + MXFMetadataStructuralComponent parent; + + gint64 start_timecode; + guint16 rounded_timecode_base; + gboolean drop_frame; +}; + +struct _MXFMetadataSourceClip { + MXFMetadataStructuralComponent parent; + + gint64 start_position; + MXFUMID source_package_id; + MXFMetadataSourcePackage *source_package; + + guint32 source_track_id; +}; + +struct _MXFMetadataDMSourceClip { + MXFMetadataSourceClip parent; + + guint32 n_track_ids; + guint32 *track_ids; +}; + +struct _MXFMetadataDMSegment { + MXFMetadataStructuralComponent parent; + + gint64 event_start_position; + gchar *event_comment; + + guint32 n_track_ids; + guint32 *track_ids; + + MXFUL dm_framework_uid; + MXFMetadataBase *dm_framework; +}; + +struct _MXFMetadataGenericDescriptor { + MXFMetadata parent; + + guint32 n_locators; + MXFUL *locators_uids; + MXFMetadataLocator **locators; +}; + +struct _MXFMetadataFileDescriptor { + MXFMetadataGenericDescriptor parent; + + guint32 linked_track_id; + + MXFFraction sample_rate; + gint64 container_duration; + + MXFUL essence_container; + MXFUL codec; +}; + +struct _MXFMetadataGenericPictureEssenceDescriptor { + MXFMetadataFileDescriptor parent; + + guint8 signal_standard; + guint8 frame_layout; + + guint32 stored_width; + guint32 stored_height; + gint32 stored_f2_offset; + guint32 sampled_width; + guint32 sampled_height; + gint32 sampled_x_offset; + gint32 sampled_y_offset; + guint32 display_height; + guint32 display_width; + gint32 display_x_offset; + gint32 display_y_offset; + gint32 display_f2_offset; + MXFFraction aspect_ratio; + + guint8 active_format_descriptor; + gint32 video_line_map[2]; + guint8 alpha_transparency; + MXFUL capture_gamma; + + guint32 image_alignment_offset; + guint32 image_start_offset; + guint32 image_end_offset; + + guint8 field_dominance; + + MXFUL picture_essence_coding; +}; + +struct _MXFMetadataCDCIPictureEssenceDescriptor { + MXFMetadataGenericPictureEssenceDescriptor parent; + + guint32 component_depth; + guint32 horizontal_subsampling; + guint32 vertical_subsampling; + guint8 color_siting; + gboolean reversed_byte_order; + gint16 padding_bits; + guint32 alpha_sample_depth; + guint32 black_ref_level; + guint32 white_ref_level; + guint32 color_range; +}; + +struct _MXFMetadataRGBAPictureEssenceDescriptor { + MXFMetadataGenericPictureEssenceDescriptor parent; + + guint32 component_max_ref; + guint32 component_min_ref; + guint32 alpha_max_ref; + guint32 alpha_min_ref; + guint8 scanning_direction; + + guint32 n_pixel_layout; + guint8 *pixel_layout; + + /* TODO: palette & palette layout */ +}; + +struct _MXFMetadataGenericSoundEssenceDescriptor { + MXFMetadataFileDescriptor parent; + + MXFFraction audio_sampling_rate; + + gboolean locked; + + gint8 audio_ref_level; + + guint8 electro_spatial_formulation; + + guint32 channel_count; + guint32 quantization_bits; + + gint8 dial_norm; + + MXFUL sound_essence_compression; +}; + +struct _MXFMetadataGenericDataEssenceDescriptor { + MXFMetadataFileDescriptor parent; + + MXFUL data_essence_compression; +}; + +struct _MXFMetadataMultipleDescriptor { + MXFMetadataFileDescriptor parent; + + MXFUL *sub_descriptors_uids; + guint32 n_sub_descriptors; + MXFMetadataGenericDescriptor **sub_descriptors; +}; + +struct _MXFMetadataLocator { + MXFMetadata parent; +}; + +struct _MXFMetadataNetworkLocator { + MXFMetadataLocator parent; + + gchar *url_string; +}; + +struct _MXFMetadataTextLocator { + MXFMetadataLocator parent; + + gchar *locator_name; +}; + +gboolean mxf_metadata_parse (MXFMetadataBase *self, MXFPrimerPack *primer, const guint8 *data, guint size); +gboolean mxf_metadata_resolve (MXFMetadataBase *self, MXFMetadataBase **metadata); + +MXFMetadata *mxf_metadata_new (guint16 type, MXFPrimerPack *primer, const guint8 *data, guint size); +void mxf_metadata_register (guint16 type_id, GType type); +void mxf_metadata_init_types (void); + +MXFMetadataTrackType mxf_metadata_track_identifier_parse (const MXFUL * track_identifier); + +void mxf_metadata_generic_picture_essence_descriptor_set_caps (MXFMetadataGenericPictureEssenceDescriptor * self, GstCaps * caps); + +#endif /* __MXF_METADATA_H__ */ diff --git a/gst/mxf/mxfmpeg.c b/gst/mxf/mxfmpeg.c index 608ecc27..7ba129f9 100644 --- a/gst/mxf/mxfmpeg.c +++ b/gst/mxf/mxfmpeg.c @@ -91,14 +91,18 @@ static const guint8 _profile_and_level_ul[] = { 0x0a, 0x00, 0x00 }; -gboolean -mxf_metadata_mpeg_video_descriptor_handle_tag (MXFMetadataGenericDescriptor * d, - const MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, - guint16 tag_size) +G_DEFINE_TYPE (MXFMetadataMPEGVideoDescriptor, + mxf_metadata_mpeg_video_descriptor, + MXF_TYPE_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR); + +static gboolean +mxf_metadata_mpeg_video_descriptor_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) { - MXFMetadataMPEGVideoDescriptor *descriptor = - (MXFMetadataMPEGVideoDescriptor *) d; - gboolean ret = FALSE; + MXFMetadataMPEGVideoDescriptor *self = + MXF_METADATA_MPEG_VIDEO_DESCRIPTOR (metadata); + gboolean ret = TRUE; MXFUL *tag_ul = NULL; if (!(tag_ul = @@ -109,91 +113,86 @@ mxf_metadata_mpeg_video_descriptor_handle_tag (MXFMetadataGenericDescriptor * d, if (memcmp (tag_ul, &_single_sequence_ul, 16) == 0) { if (tag_size != 1) goto error; - descriptor->single_sequence = GST_READ_UINT8 (tag_data); + self->single_sequence = GST_READ_UINT8 (tag_data); GST_DEBUG (" single sequence = %s", - (descriptor->single_sequence) ? "yes" : "no"); - ret = TRUE; + (self->single_sequence) ? "yes" : "no"); } else if (memcmp (tag_ul, &_constant_b_frames_ul, 16) == 0) { if (tag_size != 1) goto error; - descriptor->const_b_frames = GST_READ_UINT8 (tag_data); + self->const_b_frames = GST_READ_UINT8 (tag_data); GST_DEBUG (" constant b frames = %s", - (descriptor->single_sequence) ? "yes" : "no"); - ret = TRUE; + (self->single_sequence) ? "yes" : "no"); } else if (memcmp (tag_ul, &_coded_content_type_ul, 16) == 0) { if (tag_size != 1) goto error; - descriptor->coded_content_type = GST_READ_UINT8 (tag_data); - GST_DEBUG (" coded content type = %u", descriptor->coded_content_type); - ret = TRUE; + self->coded_content_type = GST_READ_UINT8 (tag_data); + GST_DEBUG (" coded content type = %u", self->coded_content_type); } else if (memcmp (tag_ul, &_low_delay_ul, 16) == 0) { if (tag_size != 1) goto error; - descriptor->low_delay = GST_READ_UINT8 (tag_data); - GST_DEBUG (" low delay = %s", (descriptor->low_delay) ? "yes" : "no"); - ret = TRUE; + self->low_delay = GST_READ_UINT8 (tag_data); + GST_DEBUG (" low delay = %s", (self->low_delay) ? "yes" : "no"); } else if (memcmp (tag_ul, &_closed_gop_ul, 16) == 0) { if (tag_size != 1) goto error; - descriptor->closed_gop = GST_READ_UINT8 (tag_data); - GST_DEBUG (" closed gop = %s", (descriptor->closed_gop) ? "yes" : "no"); - ret = TRUE; + self->closed_gop = GST_READ_UINT8 (tag_data); + GST_DEBUG (" closed gop = %s", (self->closed_gop) ? "yes" : "no"); } else if (memcmp (tag_ul, &_identical_gop_ul, 16) == 0) { if (tag_size != 1) goto error; - descriptor->identical_gop = GST_READ_UINT8 (tag_data); - GST_DEBUG (" identical gop = %s", - (descriptor->identical_gop) ? "yes" : "no"); - ret = TRUE; + self->identical_gop = GST_READ_UINT8 (tag_data); + GST_DEBUG (" identical gop = %s", (self->identical_gop) ? "yes" : "no"); } else if (memcmp (tag_ul, &_max_gop_ul, 16) == 0) { if (tag_size != 2) goto error; - descriptor->max_gop = GST_READ_UINT16_BE (tag_data); - GST_DEBUG (" max gop = %u", descriptor->max_gop); - ret = TRUE; + self->max_gop = GST_READ_UINT16_BE (tag_data); + GST_DEBUG (" max gop = %u", self->max_gop); } else if (memcmp (tag_ul, &_b_picture_count_ul, 16) == 0) { if (tag_size != 2) goto error; - descriptor->b_picture_count = GST_READ_UINT16_BE (tag_data); - GST_DEBUG (" b picture count = %u", descriptor->b_picture_count); - ret = TRUE; + self->b_picture_count = GST_READ_UINT16_BE (tag_data); + GST_DEBUG (" b picture count = %u", self->b_picture_count); } else if (memcmp (tag_ul, &_bitrate_ul, 16) == 0) { if (tag_size != 4) goto error; - descriptor->bitrate = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" bitrate = %u", descriptor->bitrate); - ret = TRUE; + self->bitrate = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" bitrate = %u", self->bitrate); } else if (memcmp (tag_ul, &_profile_and_level_ul, 16) == 0) { if (tag_size != 1) goto error; - descriptor->profile_and_level = GST_READ_UINT8 (tag_data); - GST_DEBUG (" profile & level = %u", descriptor->profile_and_level); - ret = TRUE; + self->profile_and_level = GST_READ_UINT8 (tag_data); + GST_DEBUG (" profile & level = %u", self->profile_and_level); } else { ret = - mxf_metadata_cdci_picture_essence_descriptor_handle_tag (d, primer, tag, - tag_data, tag_size); + MXF_METADATA_BASE_CLASS + (mxf_metadata_mpeg_video_descriptor_parent_class)->handle_tag (metadata, + primer, tag, tag_data, tag_size); } return ret; error: - GST_ERROR ("Invalid mpeg video descriptor tag 0x%04x of size %u", tag, + + GST_ERROR ("Invalid MPEG video descriptor local tag 0x%04x of size %u", tag, tag_size); return FALSE; } -void mxf_metadata_mpeg_video_descriptor_reset - (MXFMetadataMPEGVideoDescriptor * descriptor) +static void +mxf_metadata_mpeg_video_descriptor_init (MXFMetadataMPEGVideoDescriptor * self) { - g_return_if_fail (descriptor != NULL); - mxf_metadata_cdci_picture_essence_descriptor_reset ( - (MXFMetadataCDCIPictureEssenceDescriptor *) descriptor); +} + +static void + mxf_metadata_mpeg_video_descriptor_class_init + (MXFMetadataMPEGVideoDescriptorClass * klass) +{ + MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; - MXF_METADATA_DESCRIPTOR_CLEAR (descriptor, MXFMetadataMPEGVideoDescriptor, - MXFMetadataCDCIPictureEssenceDescriptor); + metadata_base_class->handle_tag = + mxf_metadata_mpeg_video_descriptor_handle_tag; } gboolean @@ -208,7 +207,12 @@ mxf_is_mpeg_essence_track (const MXFMetadataTrack * track) for (i = 0; i < track->n_descriptor; i++) { MXFMetadataFileDescriptor *d = track->descriptor[i]; - MXFUL *key = &d->essence_container; + MXFUL *key; + + if (!d) + continue; + + key = &d->essence_container; /* SMPTE 381M 7 */ if (mxf_is_generic_container_essence_container_label (key) && key->u[12] == 0x02 && @@ -338,8 +342,8 @@ mxf_mpeg_es_create_caps (MXFMetadataGenericPackage * package, codec_name = "MPEG-1 Video"; } else if (p->picture_essence_coding.u[13] == 0x20) { MXFLocalTag *local_tag = - (((MXFMetadataGenericDescriptor *) p)->other_tags) ? - g_hash_table_lookup (((MXFMetadataGenericDescriptor *) + (((MXFMetadataBase *) p)->other_tags) ? + g_hash_table_lookup (((MXFMetadataBase *) p)->other_tags, &sony_mpeg4_extradata) : NULL; caps = gst_caps_new_simple ("video/mpeg", "mpegversion", G_TYPE_INT, 4, @@ -446,17 +450,16 @@ mxf_mpeg_create_caps (MXFMetadataGenericPackage * package, } for (i = 0; i < track->n_descriptor; i++) { - if (((MXFMetadataGenericDescriptor *) track->descriptor[i])->type == - MXF_METADATA_MPEG_VIDEO_DESCRIPTOR || - ((MXFMetadataGenericDescriptor *) track->descriptor[i])->type == - MXF_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR || - ((MXFMetadataGenericDescriptor *) track->descriptor[i])->type == - MXF_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR) { + if (!track->descriptor[i]) + continue; + + if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track-> + descriptor[i])) { f = track->descriptor[i]; p = (MXFMetadataGenericPictureEssenceDescriptor *) track->descriptor[i]; break; - } else if (((MXFMetadataGenericDescriptor *) track->descriptor[i])->type == - MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR) { + } else if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track-> + descriptor[i])) { f = track->descriptor[i]; s = (MXFMetadataGenericSoundEssenceDescriptor *) track->descriptor[i]; break; @@ -503,3 +506,9 @@ mxf_mpeg_create_caps (MXFMetadataGenericPackage * package, return caps; } + +void +mxf_mpeg_init (void) +{ + mxf_metadata_register (0x0151, MXF_TYPE_METADATA_MPEG_VIDEO_DESCRIPTOR); +} diff --git a/gst/mxf/mxfmpeg.h b/gst/mxf/mxfmpeg.h index 16258a55..6ab45e42 100644 --- a/gst/mxf/mxfmpeg.h +++ b/gst/mxf/mxfmpeg.h @@ -27,12 +27,20 @@ #include <gst/gst.h> #include "mxfparse.h" - -/* SMPTE 381M 8.1.1 */ -#define MXF_METADATA_MPEG_VIDEO_DESCRIPTOR 0x0151 +#include "mxfmetadata.h" /* SMPTE 381M 8.1 */ -typedef struct { +#define MXF_TYPE_METADATA_MPEG_VIDEO_DESCRIPTOR \ + (mxf_metadata_mpeg_video_descriptor_get_type()) +#define MXF_METADATA_MPEG_VIDEO_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_MPEG_VIDEO_DESCRIPTOR, MXFMetadataMPEGVideoDescriptor)) +#define MXF_IS_METADATA_MPEG_VIDEO_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_MPEG_VIDEO_DESCRIPTOR)) +typedef struct _MXFMetadataMPEGVideoDescriptor MXFMetadataMPEGVideoDescriptor; +typedef MXFMetadataBaseClass MXFMetadataMPEGVideoDescriptorClass; +GType mxf_metadata_mpeg_video_descriptor_get_type (void); + +struct _MXFMetadataMPEGVideoDescriptor { MXFMetadataCDCIPictureEssenceDescriptor parent; gboolean single_sequence; @@ -47,14 +55,13 @@ typedef struct { guint16 b_picture_count; guint32 bitrate; guint8 profile_and_level; -} MXFMetadataMPEGVideoDescriptor; - -gboolean mxf_metadata_mpeg_video_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor, const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size); -void mxf_metadata_mpeg_video_descriptor_reset (MXFMetadataMPEGVideoDescriptor *descriptor); +}; gboolean mxf_is_mpeg_essence_track (const MXFMetadataTrack *track); GstCaps * mxf_mpeg_create_caps (MXFMetadataGenericPackage *package, MXFMetadataTrack *track, GstTagList **tags, MXFEssenceElementHandler *handler, gpointer *mapping_data); +void mxf_mpeg_init (void); + #endif /* __MXF_MPEG_H__ */ diff --git a/gst/mxf/mxfparse.c b/gst/mxf/mxfparse.c index 9ee44e6a..571f6f20 100644 --- a/gst/mxf/mxfparse.c +++ b/gst/mxf/mxfparse.c @@ -830,7 +830,7 @@ mxf_index_table_segment_parse (const MXFUL * key, break; } default: - if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size, + if (!mxf_local_tag_add_to_hash_table (primer, tag, tag_data, tag_size, &segment->other_tags)) goto error; break; @@ -974,7 +974,7 @@ gst_mxf_local_tag_free (MXFLocalTag * tag) } gboolean -gst_metadata_add_custom_tag (const MXFPrimerPack * primer, +mxf_local_tag_add_to_hash_table (const MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, guint16 tag_size, GHashTable ** hash_table) { @@ -1015,2203 +1015,3 @@ gst_metadata_add_custom_tag (const MXFPrimerPack * primer, return TRUE; } - -/* All following defined in SMPTE 377M Annex A, B, C, D */ -gboolean -mxf_metadata_preface_parse (const MXFUL * key, - MXFMetadataPreface * preface, const MXFPrimerPack * primer, - const guint8 * data, guint size) -{ - guint16 tag, tag_size; - const guint8 *tag_data; - gchar str[48]; - - g_return_val_if_fail (data != NULL, FALSE); - - memset (preface, 0, sizeof (MXFMetadataPreface)); - - GST_DEBUG ("Parsing preface:"); - - while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) { - if (tag_size == 0 || tag == 0x0000) - goto next; - - switch (tag) { - case 0x3c0a: - if (tag_size != 16) - goto error; - memcpy (&preface->instance_uid, tag_data, 16); - GST_DEBUG (" instance uid = %s", - mxf_ul_to_string (&preface->instance_uid, str)); - break; - case 0x0102: - if (tag_size != 16) - goto error; - memcpy (&preface->generation_uid, tag_data, 16); - GST_DEBUG (" generation uid = %s", - mxf_ul_to_string (&preface->generation_uid, str)); - break; - case 0x3b02: - if (!mxf_timestamp_parse (&preface->last_modified_date, tag_data, - tag_size)) - goto error; - GST_DEBUG (" last modified date = %d/%u/%u %u:%u:%u.%u", - preface->last_modified_date.year, preface->last_modified_date.month, - preface->last_modified_date.day, preface->last_modified_date.hour, - preface->last_modified_date.minute, - preface->last_modified_date.second, - (preface->last_modified_date.quarter_msecond * 1000) / 256); - break; - case 0x3b05: - if (tag_size != 2) - goto error; - preface->version = GST_READ_UINT16_BE (tag_data); - GST_DEBUG (" version = %u.%u", (preface->version >> 8), - (preface->version & 0x0f)); - break; - case 0x3b07: - if (tag_size != 4) - goto error; - preface->object_model_version = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" object model version = %u", - preface->object_model_version); - break; - case 0x3b08: - if (tag_size != 16) - goto error; - memcpy (&preface->primary_package_uid, tag_data, 16); - GST_DEBUG (" primary package = %s", - mxf_ul_to_string (&preface->primary_package_uid, str)); - break; - case 0x3b06:{ - guint32 len; - guint i; - - - if (tag_size < 8) - goto error; - len = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" number of identifications = %u", len); - if (len == 0) - break; - if (GST_READ_UINT32_BE (tag_data + 4) != 16) - goto error; - if (tag_size < 8 + len * 16) - goto error; - - preface->n_identifications = len; - preface->identifications_uids = g_new (MXFUL, len); - for (i = 0; i < len; i++) { - memcpy (&preface->identifications_uids[i], tag_data + 8 + i * 16, 16); - GST_DEBUG (" identification %u = %s", i, - mxf_ul_to_string (&preface->identifications_uids[i], str)); - } - break; - } - case 0x3b03: - if (tag_size != 16) - goto error; - memcpy (&preface->content_storage_uid, tag_data, 16); - GST_DEBUG (" content storage = %s", - mxf_ul_to_string (&preface->content_storage_uid, str)); - break; - case 0x3b09: - if (tag_size != 16) - goto error; - memcpy (&preface->operational_pattern, tag_data, 16); - GST_DEBUG (" operational pattern = %s", - mxf_ul_to_string (&preface->operational_pattern, str)); - break; - case 0x3b0a:{ - guint32 len; - guint i; - - - if (tag_size < 8) - goto error; - len = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" number of essence containers = %u", len); - if (len == 0) - break; - if (GST_READ_UINT32_BE (tag_data + 4) != 16) - goto error; - if (tag_size < 8 + len * 16) - goto error; - - preface->n_essence_containers = len; - preface->essence_containers = g_new (MXFUL, len); - for (i = 0; i < len; i++) { - memcpy (&preface->essence_containers[i], tag_data + 8 + i * 16, 16); - GST_DEBUG (" essence container %u = %s", i, - mxf_ul_to_string (&preface->essence_containers[i], str)); - } - break; - } - case 0x3b0b:{ - guint32 len; - guint i; - - - if (tag_size < 8) - goto error; - len = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" number of DM schemes = %u", len); - if (len == 0) - break; - if (GST_READ_UINT32_BE (tag_data + 4) != 16) - goto error; - if (tag_size < 8 + len * 16) - goto error; - - preface->n_dm_schemes = len; - preface->dm_schemes = g_new (MXFUL, len); - for (i = 0; i < len; i++) { - memcpy (&preface->dm_schemes[i], tag_data + 8 + i * 16, 16); - GST_DEBUG (" DM schemes %u = %s", i, - mxf_ul_to_string (&preface->dm_schemes[i], str)); - } - break; - } - default: - if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size, - &preface->other_tags)) - goto error; - break; - } - - next: - data += 4 + tag_size; - size -= 4 + tag_size; - } - - return TRUE; - -error: - GST_ERROR ("Invalid preface"); - mxf_metadata_preface_reset (preface); - - return FALSE; -} - -void -mxf_metadata_preface_reset (MXFMetadataPreface * preface) -{ - g_return_if_fail (preface != NULL); - - g_free (preface->identifications_uids); - g_free (preface->identifications); - g_free (preface->essence_containers); - g_free (preface->dm_schemes); - - if (preface->other_tags) - g_hash_table_destroy (preface->other_tags); - - memset (preface, 0, sizeof (MXFMetadataPreface)); -} - -gboolean -mxf_metadata_identification_parse (const MXFUL * key, - MXFMetadataIdentification * identification, - const MXFPrimerPack * primer, const guint8 * data, guint size) -{ - guint16 tag, tag_size; - const guint8 *tag_data; - gchar str[48]; - - g_return_val_if_fail (data != NULL, FALSE); - - memset (identification, 0, sizeof (MXFMetadataIdentification)); - - GST_DEBUG ("Parsing identification:"); - - while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) { - if (tag_size == 0 || tag == 0x0000) - goto next; - - switch (tag) { - case 0x3c0a: - if (tag_size != 16) - goto error; - memcpy (&identification->instance_uid, tag_data, 16); - GST_DEBUG (" instance uid = %s", - mxf_ul_to_string (&identification->instance_uid, str)); - break; - case 0x3c09: - if (tag_size != 16) - goto error; - memcpy (&identification->generation_uid, tag_data, 16); - GST_DEBUG (" generation uid = %s", - mxf_ul_to_string (&identification->generation_uid, str)); - break; - case 0x3c01: - identification->company_name = mxf_utf16_to_utf8 (tag_data, tag_size); - GST_DEBUG (" company name = %s", - GST_STR_NULL (identification->company_name)); - break; - case 0x3c02: - identification->product_name = mxf_utf16_to_utf8 (tag_data, tag_size); - GST_DEBUG (" product name = %s", - GST_STR_NULL (identification->product_name)); - break; - case 0x3c03: - if (!mxf_product_version_parse (&identification->product_version, - tag_data, tag_size)) - goto error; - GST_DEBUG (" product version = %u.%u.%u.%u.%u", - identification->product_version.major, - identification->product_version.minor, - identification->product_version.patch, - identification->product_version.build, - identification->product_version.release); - break; - case 0x3c04: - identification->version_string = mxf_utf16_to_utf8 (tag_data, tag_size); - GST_DEBUG (" version string = %s", - GST_STR_NULL (identification->version_string)); - break; - case 0x3c05: - if (tag_size != 16) - goto error; - memcpy (&identification->product_uid, tag_data, 16); - GST_DEBUG (" product uid = %s", - mxf_ul_to_string (&identification->product_uid, str)); - break; - case 0x3c06: - if (!mxf_timestamp_parse (&identification->modification_date, tag_data, - tag_size)) - goto error; - GST_DEBUG (" modification date = %d/%u/%u %u:%u:%u.%u", - identification->modification_date.year, - identification->modification_date.month, - identification->modification_date.day, - identification->modification_date.hour, - identification->modification_date.minute, - identification->modification_date.second, - (identification->modification_date.quarter_msecond * 1000) / 256); - break; - case 0x3c07: - if (!mxf_product_version_parse (&identification->toolkit_version, - tag_data, tag_size)) - goto error; - GST_DEBUG (" toolkit version = %u.%u.%u.%u.%u", - identification->toolkit_version.major, - identification->toolkit_version.minor, - identification->toolkit_version.patch, - identification->toolkit_version.build, - identification->toolkit_version.release); - break; - case 0x3c08: - identification->platform = mxf_utf16_to_utf8 (tag_data, tag_size); - GST_DEBUG (" platform = %s", GST_STR_NULL (identification->platform)); - break; - default: - if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size, - &identification->other_tags)) - goto error; - break; - } - - next: - data += 4 + tag_size; - size -= 4 + tag_size; - } - - return TRUE; - -error: - GST_ERROR ("Invalid identification"); - mxf_metadata_identification_reset (identification); - - return FALSE; -} - -void mxf_metadata_identification_reset - (MXFMetadataIdentification * identification) -{ - g_return_if_fail (identification != NULL); - - g_free (identification->company_name); - g_free (identification->product_name); - g_free (identification->version_string); - g_free (identification->platform); - - if (identification->other_tags) - g_hash_table_destroy (identification->other_tags); - - memset (identification, 0, sizeof (MXFMetadataIdentification)); -} - -gboolean -mxf_metadata_content_storage_parse (const MXFUL * key, - MXFMetadataContentStorage * content_storage, - const MXFPrimerPack * primer, const guint8 * data, guint size) -{ - guint16 tag, tag_size; - const guint8 *tag_data; - gchar str[48]; - - g_return_val_if_fail (data != NULL, FALSE); - - memset (content_storage, 0, sizeof (MXFMetadataContentStorage)); - - GST_DEBUG ("Parsing content storage:"); - - while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) { - if (tag_size == 0 || tag == 0x0000) - goto next; - - switch (tag) { - case 0x3c0a: - if (tag_size != 16) - goto error; - memcpy (&content_storage->instance_uid, tag_data, 16); - GST_DEBUG (" instance uid = %s", - mxf_ul_to_string (&content_storage->instance_uid, str)); - break; - case 0x0102: - if (tag_size != 16) - goto error; - memcpy (&content_storage->generation_uid, tag_data, 16); - GST_DEBUG (" generation uid = %s", - mxf_ul_to_string (&content_storage->generation_uid, str)); - break; - case 0x1901:{ - guint32 len; - guint i; - - - len = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" number of packages = %u", len); - if (len == 0) - break; - if (GST_READ_UINT32_BE (tag_data + 4) != 16) - goto error; - if (tag_size < 8 + len * 16) - goto error; - - content_storage->packages_uids = g_new (MXFUL, len); - content_storage->n_packages = len; - for (i = 0; i < len; i++) { - memcpy (&content_storage->packages_uids[i], tag_data + 8 + i * 16, - 16); - GST_DEBUG (" package %u = %s", i, - mxf_ul_to_string (&content_storage->packages_uids[i], str)); - } - break; - } - case 0x1902:{ - guint32 len; - guint i; - - - len = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" number of essence container data = %u", len); - if (len == 0) - break; - if (GST_READ_UINT32_BE (tag_data + 4) != 16) - goto error; - if (tag_size < 8 + len * 16) - goto error; - - content_storage->essence_container_data_uids = g_new (MXFUL, len); - content_storage->n_essence_container_data = len; - for (i = 0; i < len; i++) { - memcpy (&content_storage->essence_container_data_uids[i], - tag_data + 8 + i * 16, 16); - GST_DEBUG (" essence container data %u = %s", i, - mxf_ul_to_string (&content_storage->essence_container_data_uids - [i], str)); - } - break; - } - default: - if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size, - &content_storage->other_tags)) - goto error; - break; - } - - next: - data += 4 + tag_size; - size -= 4 + tag_size; - } - - return TRUE; - -error: - GST_ERROR ("Invalid content storage"); - mxf_metadata_content_storage_reset (content_storage); - - return FALSE; -} - -void mxf_metadata_content_storage_reset - (MXFMetadataContentStorage * content_storage) -{ - g_return_if_fail (content_storage != NULL); - - g_free (content_storage->packages); - g_free (content_storage->packages_uids); - g_free (content_storage->essence_container_data); - g_free (content_storage->essence_container_data_uids); - - if (content_storage->other_tags) - g_hash_table_destroy (content_storage->other_tags); - - memset (content_storage, 0, sizeof (MXFMetadataContentStorage)); -} - -gboolean -mxf_metadata_essence_container_data_parse (const MXFUL * key, - MXFMetadataEssenceContainerData * essence_container_data, - const MXFPrimerPack * primer, const guint8 * data, guint size) -{ - guint16 tag, tag_size; - const guint8 *tag_data; - gchar str[96]; - - g_return_val_if_fail (data != NULL, FALSE); - - memset (essence_container_data, 0, sizeof (MXFMetadataEssenceContainerData)); - - GST_DEBUG ("Parsing essence container data:"); - - while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) { - if (tag_size == 0 || tag == 0x0000) - goto next; - - switch (tag) { - case 0x3c0a: - if (tag_size != 16) - goto error; - memcpy (&essence_container_data->instance_uid, tag_data, 16); - GST_DEBUG (" instance uid = %s", - mxf_ul_to_string (&essence_container_data->instance_uid, str)); - break; - case 0x2701: - if (tag_size != 32) - goto error; - memcpy (&essence_container_data->linked_package_uid, tag_data, 32); - GST_DEBUG (" linked package = %s", - mxf_umid_to_string (&essence_container_data->linked_package_uid, - str)); - break; - case 0x0102: - if (tag_size != 16) - goto error; - memcpy (&essence_container_data->generation_uid, tag_data, 16); - GST_DEBUG (" generation uid = %s", - mxf_ul_to_string (&essence_container_data->generation_uid, str)); - break; - case 0x3f06: - if (tag_size != 4) - goto error; - essence_container_data->index_sid = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" index sid = %u", essence_container_data->index_sid); - break; - case 0x3f07: - if (tag_size != 4) - goto error; - essence_container_data->body_sid = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" body sid = %u", essence_container_data->body_sid); - break; - default: - if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size, - &essence_container_data->other_tags)) - goto error; - break; - } - next: - - data += 4 + tag_size; - size -= 4 + tag_size; - } - - return TRUE; - -error: - GST_ERROR ("Invalid essence container data"); - mxf_metadata_essence_container_data_reset (essence_container_data); - - return FALSE; -} - -void mxf_metadata_essence_container_data_reset - (MXFMetadataEssenceContainerData * essence_container_data) -{ - g_return_if_fail (essence_container_data != NULL); - - if (essence_container_data->other_tags) - g_hash_table_destroy (essence_container_data->other_tags); - - memset (essence_container_data, 0, sizeof (MXFMetadataEssenceContainerData)); -} - -gboolean -mxf_metadata_generic_package_parse (const MXFUL * key, - MXFMetadataGenericPackage * generic_package, - const MXFPrimerPack * primer, const guint8 * data, guint size) -{ - guint16 tag, tag_size; - const guint8 *tag_data; - gchar str[96]; - - g_return_val_if_fail (data != NULL, FALSE); - - memset (generic_package, 0, sizeof (MXFMetadataGenericPackage)); - - GST_DEBUG ("Parsing generic package:"); - - while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) { - if (tag_size == 0 || tag == 0x0000) - goto next; - - switch (tag) { - case 0x3c0a: - if (tag_size != 16) - goto error; - memcpy (&generic_package->instance_uid, tag_data, 16); - GST_DEBUG (" instance uid = %s", - mxf_ul_to_string (&generic_package->instance_uid, str)); - break; - case 0x4401: - if (tag_size != 32) - goto error; - memcpy (&generic_package->package_uid, tag_data, 32); - GST_DEBUG (" UMID = %s", - mxf_umid_to_string (&generic_package->package_uid, str)); - break; - case 0x0102: - if (tag_size != 16) - goto error; - memcpy (&generic_package->generation_uid, tag_data, 16); - GST_DEBUG (" generation uid = %s", - mxf_ul_to_string (&generic_package->generation_uid, str)); - break; - case 0x4402: - generic_package->name = mxf_utf16_to_utf8 (tag_data, tag_size); - GST_DEBUG (" name = %s", GST_STR_NULL (generic_package->name)); - break; - case 0x4405: - if (!mxf_timestamp_parse (&generic_package->package_creation_date, - tag_data, tag_size)) - goto error; - GST_DEBUG (" creation date = %d/%u/%u %u:%u:%u.%u", - generic_package->package_creation_date.year, - generic_package->package_creation_date.month, - generic_package->package_creation_date.day, - generic_package->package_creation_date.hour, - generic_package->package_creation_date.minute, - generic_package->package_creation_date.second, - (generic_package->package_creation_date.quarter_msecond * 1000) / - 256); - break; - case 0x4404: - if (!mxf_timestamp_parse (&generic_package->package_modified_date, - tag_data, tag_size)) - goto error; - GST_DEBUG (" modification date = %d/%u/%u %u:%u:%u.%u", - generic_package->package_modified_date.year, - generic_package->package_modified_date.month, - generic_package->package_modified_date.day, - generic_package->package_modified_date.hour, - generic_package->package_modified_date.minute, - generic_package->package_modified_date.second, - (generic_package->package_modified_date.quarter_msecond * 1000) / - 256); - break; - case 0x4403:{ - guint32 len; - guint i; - - - len = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" number of tracks = %u", len); - if (len == 0) - break; - if (GST_READ_UINT32_BE (tag_data + 4) != 16) - goto error; - if (tag_size < 8 + len * 16) - goto error; - - generic_package->tracks_uids = g_new (MXFUL, len); - generic_package->n_tracks = len; - for (i = 0; i < len; i++) { - memcpy (&generic_package->tracks_uids[i], tag_data + 8 + i * 16, 16); - GST_DEBUG (" track %u = %s", i, - mxf_ul_to_string (&generic_package->tracks_uids[i], str)); - } - break; - } - case 0x4701: - if (tag_size != 16) - goto error; - - generic_package->n_descriptors = 1; - memcpy (&generic_package->descriptors_uid, tag_data, 16); - GST_DEBUG (" descriptor = %s", - mxf_ul_to_string (&generic_package->descriptors_uid, str)); - break; - default: - if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size, - &generic_package->other_tags)) - goto error; - break; - } - - next: - data += 4 + tag_size; - size -= 4 + tag_size; - } - - return TRUE; - -error: - GST_ERROR ("Invalid package"); - mxf_metadata_generic_package_reset (generic_package); - - return FALSE; -} - -void mxf_metadata_generic_package_reset - (MXFMetadataGenericPackage * generic_package) -{ - g_return_if_fail (generic_package != NULL); - - g_free (generic_package->name); - g_free (generic_package->tracks_uids); - - g_free (generic_package->tracks); - - if (generic_package->other_tags) - g_hash_table_destroy (generic_package->other_tags); - - g_free (generic_package->descriptors); - - memset (generic_package, 0, sizeof (MXFMetadataGenericPackage)); -} - -gboolean -mxf_metadata_track_parse (const MXFUL * key, - MXFMetadataTrack * track, const MXFPrimerPack * primer, - guint16 type, const guint8 * data, guint size) -{ - guint16 tag, tag_size; - const guint8 *tag_data; - gchar str[48]; - - g_return_val_if_fail (data != NULL, FALSE); - - memset (track, 0, sizeof (MXFMetadataTrack)); - - if (type == MXF_METADATA_TRACK) - track->variant = MXF_METADATA_TRACK_VARIANT_TIMELINE; - else if (type == MXF_METADATA_EVENT_TRACK) - track->variant = MXF_METADATA_TRACK_VARIANT_EVENT; - else - track->variant = MXF_METADATA_TRACK_VARIANT_STATIC; - - - GST_DEBUG ("Parsing track of type 0x%04x:", type); - - while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) { - if (tag_size == 0 || tag == 0x0000) - goto next; - - switch (tag) { - case 0x3c0a: - if (tag_size != 16) - goto error; - memcpy (&track->instance_uid, tag_data, 16); - GST_DEBUG (" instance uid = %s", - mxf_ul_to_string (&track->instance_uid, str)); - break; - case 0x0102: - if (tag_size != 16) - goto error; - memcpy (&track->generation_uid, tag_data, 16); - GST_DEBUG (" generation uid = %s", - mxf_ul_to_string (&track->generation_uid, str)); - break; - case 0x4801: - if (tag_size != 4) - goto error; - track->track_id = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" track id = %u", track->track_id); - break; - case 0x4804: - if (tag_size != 4) - goto error; - track->track_number = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" track number = %u", track->track_number); - break; - case 0x4802: - track->track_name = mxf_utf16_to_utf8 (tag_data, tag_size); - GST_DEBUG (" track name = %s", GST_STR_NULL (track->track_name)); - break; - case 0x4b01: - case 0x4901: - if (!mxf_fraction_parse (&track->edit_rate, tag_data, tag_size)) - goto error; - GST_DEBUG (" edit rate = %d/%d", track->edit_rate.n, - track->edit_rate.d); - break; - case 0x4b02: - case 0x4902: - if (tag_size != 8) - goto error; - track->origin = GST_READ_UINT64_BE (tag_data); - GST_DEBUG (" origin = %" G_GINT64_FORMAT, track->origin); - break; - case 0x4803: - if (tag_size != 16) - goto error; - memcpy (&track->sequence_uid, tag_data, 16); - GST_DEBUG (" sequence uid = %s", - mxf_ul_to_string (&track->sequence_uid, str)); - break; - default: - if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size, - &track->other_tags)) - goto error; - break; - } - - next: - data += 4 + tag_size; - size -= 4 + tag_size; - } - - return TRUE; - -error: - GST_ERROR ("Invalid track"); - mxf_metadata_track_reset (track); - - return FALSE; -} - -void -mxf_metadata_track_reset (MXFMetadataTrack * track) -{ - g_return_if_fail (track != NULL); - - g_free (track->track_name); - - if (track->descriptor) - g_free (track->descriptor); - - if (track->other_tags) - g_hash_table_destroy (track->other_tags); - - memset (track, 0, sizeof (MXFMetadataTrack)); -} - -/* SMPTE RP224 */ -static const struct -{ - guint8 ul[16]; - MXFMetadataTrackType type; -} mxf_metadata_track_identifier[] = { - { { - 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, - 0x01, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00}, - MXF_METADATA_TRACK_TIMECODE_12M_INACTIVE}, { { - 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x01, - 0x02, 0x00, 0x00, 0x00}, MXF_METADATA_TRACK_TIMECODE_12M_ACTIVE}, { { - 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x01, - 0x03, 0x00, 0x00, 0x00}, MXF_METADATA_TRACK_TIMECODE_309M}, { { - 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x01, - 0x10, 0x00, 0x00, 0x00}, MXF_METADATA_TRACK_METADATA}, { { - 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x02, - 0x01, 0x00, 0x00, 0x00}, MXF_METADATA_TRACK_PICTURE_ESSENCE}, { { - 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x02, - 0x02, 0x00, 0x00, 0x00}, MXF_METADATA_TRACK_SOUND_ESSENCE}, { { - 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x02, - 0x03, 0x00, 0x00, 0x00}, MXF_METADATA_TRACK_DATA_ESSENCE}, { { - 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x03, - 0x01, 0x00, 0x00, 0x00}, MXF_METADATA_TRACK_AUXILIARY_DATA}, { { - 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x03, - 0x02, 0x00, 0x00, 0x00}, MXF_METADATA_TRACK_PARSED_TEXT} -}; - -MXFMetadataTrackType -mxf_metadata_track_identifier_parse (const MXFUL * track_identifier) -{ - guint i; - - for (i = 0; i < G_N_ELEMENTS (mxf_metadata_track_identifier); i++) - if (memcmp (&mxf_metadata_track_identifier[i].ul, &track_identifier->u, - 16) == 0) - return mxf_metadata_track_identifier[i].type; - - return MXF_METADATA_TRACK_UNKNOWN; -} - -gboolean -mxf_metadata_sequence_parse (const MXFUL * key, - MXFMetadataSequence * sequence, const MXFPrimerPack * primer, - const guint8 * data, guint size) -{ - guint16 tag, tag_size; - const guint8 *tag_data; - gchar str[48]; - - g_return_val_if_fail (data != NULL, FALSE); - - memset (sequence, 0, sizeof (MXFMetadataSequence)); - - GST_DEBUG ("Parsing sequence:"); - - while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) { - if (tag_size == 0 || tag == 0x0000) - goto next; - - switch (tag) { - case 0x3c0a: - if (tag_size != 16) - goto error; - memcpy (&sequence->instance_uid, tag_data, 16); - GST_DEBUG (" instance uid = %s", - mxf_ul_to_string (&sequence->instance_uid, str)); - break; - case 0x0102: - if (tag_size != 16) - goto error; - memcpy (&sequence->generation_uid, tag_data, 16); - GST_DEBUG (" generation uid = %s", - mxf_ul_to_string (&sequence->generation_uid, str)); - break; - case 0x0201: - if (tag_size != 16) - goto error; - memcpy (&sequence->data_definition, tag_data, 16); - GST_DEBUG (" data definition = %s", - mxf_ul_to_string (&sequence->data_definition, str)); - break; - case 0x0202: - if (tag_size != 8) - goto error; - sequence->duration = GST_READ_UINT64_BE (tag_data); - GST_DEBUG (" duration = %" G_GINT64_FORMAT, sequence->duration); - break; - case 0x1001:{ - guint32 len; - guint i; - - - len = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" number of structural components = %u", len); - if (len == 0) - break; - if (GST_READ_UINT32_BE (tag_data + 4) != 16) - goto error; - if (tag_size < 8 + len * 16) - goto error; - - sequence->structural_components_uids = g_new (MXFUL, len); - sequence->n_structural_components = len; - for (i = 0; i < len; i++) { - memcpy (&sequence->structural_components_uids[i], - tag_data + 8 + i * 16, 16); - GST_DEBUG (" structural component %u = %s", i, - mxf_ul_to_string (&sequence->structural_components_uids[i], str)); - } - break; - } - default: - if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size, - &sequence->other_tags)) - goto error; - break; - } - - next: - data += 4 + tag_size; - size -= 4 + tag_size; - } - - return TRUE; - -error: - GST_ERROR ("Invalid sequence"); - mxf_metadata_sequence_reset (sequence); - - return FALSE; -} - -void -mxf_metadata_sequence_reset (MXFMetadataSequence * sequence) -{ - g_return_if_fail (sequence != NULL); - - g_free (sequence->structural_components_uids); - g_free (sequence->structural_components); - - if (sequence->other_tags) - g_hash_table_destroy (sequence->other_tags); - - memset (sequence, 0, sizeof (MXFMetadataSequence)); -} - -gboolean -mxf_metadata_structural_component_parse (const MXFUL * key, - MXFMetadataStructuralComponent * component, - const MXFPrimerPack * primer, guint16 type, const guint8 * data, guint size) -{ - guint16 tag, tag_size; - const guint8 *tag_data; - gchar str[96]; - - g_return_val_if_fail (data != NULL, FALSE); - - memset (component, 0, sizeof (MXFMetadataStructuralComponent)); - - GST_DEBUG ("Parsing structural component:"); - - component->type = type; - if (type == MXF_METADATA_TIMECODE_COMPONENT) - GST_DEBUG (" type = timecode component"); - else if (type == MXF_METADATA_SOURCE_CLIP) - GST_DEBUG (" type = source clip"); - else if (type == MXF_METADATA_DM_SEGMENT) - GST_DEBUG (" type = DM segment"); - else - GST_DEBUG (" type = DM source clip"); - - while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) { - if (tag_size == 0 || tag == 0x0000) - goto next; - - switch (tag) { - case 0x3c0a: - if (tag_size != 16) - goto error; - memcpy (&component->instance_uid, tag_data, 16); - GST_DEBUG (" instance uid = %s", - mxf_ul_to_string (&component->instance_uid, str)); - break; - case 0x0102: - if (tag_size != 16) - goto error; - memcpy (&component->generation_uid, tag_data, 16); - GST_DEBUG (" generation uid = %s", - mxf_ul_to_string (&component->generation_uid, str)); - break; - case 0x0201: - if (tag_size != 16) - goto error; - memcpy (&component->data_definition, tag_data, 16); - GST_DEBUG (" data definition = %s", - mxf_ul_to_string (&component->data_definition, str)); - break; - case 0x0202: - if (tag_size != 8) - goto error; - component->duration = GST_READ_UINT64_BE (tag_data); - GST_DEBUG (" duration = %" G_GINT64_FORMAT, component->duration); - break; - /* Timecode component specifics */ - case 0x1502: - if (type != MXF_METADATA_TIMECODE_COMPONENT) - goto DFLT; - if (tag_size != 2) - goto error; - component->timecode_component.rounded_timecode_base = - GST_READ_UINT16_BE (tag_data); - GST_DEBUG (" rounded timecode base = %u", - component->timecode_component.rounded_timecode_base); - break; - case 0x1501: - if (type != MXF_METADATA_TIMECODE_COMPONENT) - goto DFLT; - if (tag_size != 8) - goto error; - component->timecode_component.start_timecode = - GST_READ_UINT64_BE (tag_data); - GST_DEBUG (" start timecode = %" G_GINT64_FORMAT, - component->timecode_component.start_timecode); - break; - case 0x1503: - if (type != MXF_METADATA_TIMECODE_COMPONENT) - goto DFLT; - if (tag_size != 1) - goto error; - component->timecode_component.drop_frame = - (GST_READ_UINT8 (tag_data) != 0); - GST_DEBUG (" drop frame = %s", - (component->timecode_component.drop_frame) ? "yes" : "no"); - break; - /* Source clip specifics */ - case 0x1201: - if (type != MXF_METADATA_SOURCE_CLIP - && type != MXF_METADATA_DM_SOURCE_CLIP) - goto DFLT; - if (tag_size != 8) - goto error; - - if (type == MXF_METADATA_SOURCE_CLIP) { - component->source_clip.start_position = GST_READ_UINT64_BE (tag_data); - GST_DEBUG (" start position = %" G_GINT64_FORMAT, - component->source_clip.start_position); - } else { - component->dm_source_clip.start_position = - GST_READ_UINT64_BE (tag_data); - GST_DEBUG (" start position = %" G_GINT64_FORMAT, - component->dm_source_clip.start_position); - } - break; - case 0x1101: - if (type != MXF_METADATA_SOURCE_CLIP - && type != MXF_METADATA_DM_SOURCE_CLIP) - goto DFLT; - if (tag_size != 32) - goto error; - - if (type == MXF_METADATA_SOURCE_CLIP) { - memcpy (&component->source_clip.source_package_id, tag_data, 32); - GST_DEBUG (" source package id = %s", - mxf_umid_to_string (&component->source_clip.source_package_id, - str)); - } else { - memcpy (&component->dm_source_clip.source_package_id, tag_data, 32); - GST_DEBUG (" source package id = %s", - mxf_umid_to_string (&component->dm_source_clip.source_package_id, - str)); - } - break; - case 0x1102: - if (type != MXF_METADATA_SOURCE_CLIP - && type != MXF_METADATA_DM_SOURCE_CLIP) - goto DFLT; - if (tag_size != 4) - goto error; - - if (type == MXF_METADATA_SOURCE_CLIP) { - component->source_clip.source_track_id = - GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" source track id = %u", - component->source_clip.source_track_id); - } else { - component->dm_source_clip.source_track_id = - GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" source track id = %u", - component->dm_source_clip.source_track_id); - } - break; - /* DM Segment specifics */ - case 0x0601: - if (type != MXF_METADATA_DM_SEGMENT) - goto DFLT; - if (tag_size != 8) - goto error; - component->dm_segment.event_start_position = - GST_READ_UINT64_BE (tag_data); - GST_DEBUG (" event start position = %" G_GINT64_FORMAT, - component->dm_segment.event_start_position); - break; - case 0x0602: - if (type != MXF_METADATA_DM_SEGMENT) - goto DFLT; - component->dm_segment.event_comment = - mxf_utf16_to_utf8 (tag_data, tag_size); - GST_DEBUG (" event comment = %s", - GST_STR_NULL (component->dm_segment.event_comment)); - break; - case 0x6102: - { - guint32 len; - guint i; - - if (type != MXF_METADATA_DM_SEGMENT) - goto DFLT; - - if (tag_size < 8) - goto error; - len = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" number of track ids = %u", len); - if (len == 0) - goto next; - - if (GST_READ_UINT32_BE (tag_data + 4) != 4) - goto error; - - if (len * 4 + 8 < tag_size) - goto error; - - component->dm_segment.n_track_ids = len; - component->dm_segment.track_ids = g_new0 (guint32, len); - - tag_data += 8; - tag_size -= 8; - - for (i = 0; i < len; i++) { - component->dm_segment.track_ids[i] = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" track id %u = %u", i, - component->dm_segment.track_ids[i]); - tag_data += 4; - tag_size -= 4; - } - break; - } - case 0x6101: - if (type != MXF_METADATA_DM_SEGMENT) - goto DFLT; - if (tag_size != 16) - goto error; - - memcpy (&component->dm_segment.dm_framework, tag_data, 16); - GST_DEBUG (" DM framework = %s", - mxf_ul_to_string (&component->dm_segment.dm_framework, str)); - break; - /* DM Source Clip specifics */ - case 0x6103: - { - guint32 len; - guint i; - - if (type != MXF_METADATA_DM_SOURCE_CLIP) - goto DFLT; - if (tag_size < 8) - goto error; - - len = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" number of track ids = %u", len); - if (len == 0) - goto next; - - if (GST_READ_UINT32_BE (tag_data + 4) != 4) - goto error; - - if (tag_size < 8 + 4 * len) - goto error; - - tag_data += 8; - tag_size -= 8; - - component->dm_source_clip.n_track_ids = len; - component->dm_source_clip.track_ids = g_new0 (guint32, len); - - for (i = 0; i < len; i++) { - component->dm_source_clip.track_ids[i] = - GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" track id %u = %u", i, - component->dm_source_clip.track_ids[i]); - tag_data += 4; - tag_size -= 4; - } - break; - } - DFLT: - default: - if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size, - &component->other_tags)) - goto error; - break; - } - - next: - data += 4 + tag_size; - size -= 4 + tag_size; - } - - return TRUE; - -error: - GST_ERROR ("Invalid structural component"); - mxf_metadata_structural_component_reset (component); - - return FALSE; -} - -void mxf_metadata_structural_component_reset - (MXFMetadataStructuralComponent * component) -{ - g_return_if_fail (component != NULL); - - if (component->type == MXF_METADATA_DM_SEGMENT) { - g_free (component->dm_segment.event_comment); - g_free (component->dm_segment.track_ids); - } else if (component->type == MXF_METADATA_DM_SOURCE_CLIP) { - g_free (component->dm_source_clip.track_ids); - } - - if (component->other_tags) - g_hash_table_destroy (component->other_tags); - - memset (component, 0, sizeof (MXFMetadataStructuralComponent)); -} - -gboolean -mxf_metadata_descriptor_parse (const MXFUL * key, - MXFMetadataGenericDescriptor * descriptor, - const MXFPrimerPack * primer, guint16 type, - const guint8 * data, guint size, - MXFMetadataDescriptorHandleTag handle_tag, MXFMetadataDescriptorReset reset) -{ - guint16 tag, tag_size; - const guint8 *tag_data; - - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (key != NULL, FALSE); - g_return_val_if_fail (primer != NULL, FALSE); - g_return_val_if_fail (descriptor != NULL, FALSE); - g_return_val_if_fail (handle_tag != NULL, FALSE); - g_return_val_if_fail (reset != NULL, FALSE); - - reset (descriptor); - - descriptor->type = type; - - GST_DEBUG ("Parsing descriptor of type 0x%04x:", type); - - while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) { - if (tag_size == 0 || tag == 0x0000) - goto next; - - if (!handle_tag (descriptor, primer, tag, tag_data, tag_size)) - if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size, - &((MXFMetadataGenericDescriptor *) descriptor)->other_tags)) - goto next; - - next: - data += 4 + tag_size; - size -= 4 + tag_size; - } - return TRUE; -} - -gboolean -mxf_metadata_generic_descriptor_handle_tag (MXFMetadataGenericDescriptor * - descriptor, const MXFPrimerPack * primer, guint16 tag, - const guint8 * tag_data, guint16 tag_size) -{ - gboolean ret = FALSE; - gchar str[48]; - - switch (tag) { - case 0x3c0a: - if (tag_size != 16) - goto error; - memcpy (&descriptor->instance_uid, tag_data, 16); - GST_DEBUG (" instance uid = %s", - mxf_ul_to_string (&descriptor->instance_uid, str)); - ret = TRUE; - break; - case 0x0102: - if (tag_size != 16) - goto error; - memcpy (&descriptor->generation_uid, tag_data, 16); - GST_DEBUG (" generation uid = %s", - mxf_ul_to_string (&descriptor->generation_uid, str)); - ret = TRUE; - break; - case 0x2f01:{ - guint32 len; - guint i; - - if (tag_size < 8) - goto error; - - len = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" number of locators = %u", len); - if (len == 0) - return TRUE; - - if (GST_READ_UINT32_BE (tag_data + 4) != 16) - goto error; - - descriptor->locators_uids = g_new (MXFUL, len); - descriptor->n_locators = len; - for (i = 0; i < len; i++) { - memcpy (&descriptor->locators_uids[i], tag_data + 8 + i * 16, 16); - GST_DEBUG (" locator %u = %s", i, - mxf_ul_to_string (&descriptor->locators_uids[i], str)); - } - ret = TRUE; - break; - } - } - - return ret; - -error: - GST_ERROR ("Invalid generic descriptor tag 0x%04x of size %u", tag, tag_size); - - return TRUE; -} - -void mxf_metadata_generic_descriptor_reset - (MXFMetadataGenericDescriptor * descriptor) -{ - g_return_if_fail (descriptor != NULL); - - if (descriptor->locators_uids) - g_free (descriptor->locators_uids); - - if (descriptor->locators) - g_free (descriptor->locators); - - if (descriptor->other_tags) - g_hash_table_destroy (descriptor->other_tags); - - memset (descriptor, 0, sizeof (MXFMetadataGenericDescriptor)); -} - -gboolean -mxf_metadata_file_descriptor_handle_tag (MXFMetadataGenericDescriptor * d, - const MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, - guint16 tag_size) -{ - MXFMetadataFileDescriptor *descriptor = (MXFMetadataFileDescriptor *) d; - gboolean ret = FALSE; - gchar str[48]; - - switch (tag) { - case 0x3006: - if (tag_size != 4) - goto error; - descriptor->linked_track_id = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" linked track id = %u", descriptor->linked_track_id); - ret = TRUE; - break; - case 0x3001: - if (!mxf_fraction_parse (&descriptor->sample_rate, tag_data, tag_size)) - goto error; - GST_DEBUG (" sample rate = %d/%d", descriptor->sample_rate.n, - descriptor->sample_rate.d); - ret = TRUE; - break; - case 0x3002: - if (tag_size != 8) - goto error; - descriptor->container_duration = GST_READ_UINT64_BE (tag_data); - GST_DEBUG (" container duration = %" G_GINT64_FORMAT, - descriptor->container_duration); - ret = TRUE; - break; - case 0x3004: - if (tag_size != 16) - goto error; - memcpy (&descriptor->essence_container, tag_data, 16); - GST_DEBUG (" essence container = %s", - mxf_ul_to_string (&descriptor->essence_container, str)); - ret = TRUE; - break; - case 0x3005: - if (tag_size != 16) - goto error; - memcpy (&descriptor->codec, tag_data, 16); - GST_DEBUG (" codec = %s", mxf_ul_to_string (&descriptor->codec, str)); - ret = TRUE; - break; - default: - ret = - mxf_metadata_generic_descriptor_handle_tag (d, primer, tag, tag_data, - tag_size); - break; - } - - return ret; - -error: - GST_ERROR ("Invalid file descriptor tag 0x%04x of size %u", tag, tag_size); - - return TRUE; -} - -void -mxf_metadata_file_descriptor_reset (MXFMetadataFileDescriptor * descriptor) -{ - g_return_if_fail (descriptor != NULL); - - mxf_metadata_generic_descriptor_reset ((MXFMetadataGenericDescriptor *) - descriptor); - - MXF_METADATA_DESCRIPTOR_CLEAR (descriptor, MXFMetadataFileDescriptor, - MXFMetadataGenericDescriptor); - - descriptor->parent.is_file_descriptor = TRUE; -} - -gboolean - mxf_metadata_generic_sound_essence_descriptor_handle_tag - (MXFMetadataGenericDescriptor * d, const MXFPrimerPack * primer, - guint16 tag, const guint8 * tag_data, guint16 tag_size) -{ - MXFMetadataGenericSoundEssenceDescriptor *descriptor = - (MXFMetadataGenericSoundEssenceDescriptor *) d; - gboolean ret = FALSE; - gchar str[48]; - - switch (tag) { - case 0x3d03: - if (!mxf_fraction_parse (&descriptor->audio_sampling_rate, tag_data, - tag_size)) - goto error; - GST_DEBUG (" audio sampling rate = %d/%d", - descriptor->audio_sampling_rate.n, descriptor->audio_sampling_rate.d); - ret = TRUE; - break; - case 0x3d02: - if (tag_size != 1) - goto error; - descriptor->locked = (GST_READ_UINT8 (tag_data) != 0); - GST_DEBUG (" locked = %s", (descriptor->locked) ? "yes" : "no"); - ret = TRUE; - break; - case 0x3d04: - if (tag_size != 1) - goto error; - descriptor->audio_ref_level = GST_READ_UINT8 (tag_data); - GST_DEBUG (" audio ref level = %d", descriptor->audio_ref_level); - ret = TRUE; - break; - case 0x3d05: - if (tag_size != 1) - goto error; - descriptor->electro_spatial_formulation = GST_READ_UINT8 (tag_data); - GST_DEBUG (" electro spatial formulation = %u", - descriptor->electro_spatial_formulation); - ret = TRUE; - break; - case 0x3d07: - if (tag_size != 4) - goto error; - descriptor->channel_count = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" channel count = %u", descriptor->channel_count); - ret = TRUE; - break; - case 0x3d01: - if (tag_size != 4) - goto error; - descriptor->quantization_bits = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" quantization bits = %u", descriptor->quantization_bits); - ret = TRUE; - break; - case 0x3d0c: - if (tag_size != 1) - goto error; - descriptor->dial_norm = GST_READ_UINT8 (tag_data); - GST_DEBUG (" dial norm = %d", descriptor->dial_norm); - ret = TRUE; - break; - case 0x3d06: - if (tag_size != 16) - goto error; - memcpy (&descriptor->sound_essence_compression, tag_data, 16); - GST_DEBUG (" sound essence compression = %s", - mxf_ul_to_string (&descriptor->sound_essence_compression, str)); - ret = TRUE; - break; - default: - ret = - mxf_metadata_file_descriptor_handle_tag (d, primer, tag, tag_data, - tag_size); - break; - } - - return ret; - -error: - GST_ERROR ("Invalid generic sound essence descriptor tag 0x%04x of size %u", - tag, tag_size); - - return TRUE; -} - -void mxf_metadata_generic_sound_essence_descriptor_reset - (MXFMetadataGenericSoundEssenceDescriptor * descriptor) -{ - g_return_if_fail (descriptor != NULL); - - mxf_metadata_file_descriptor_reset ((MXFMetadataFileDescriptor *) descriptor); - - MXF_METADATA_DESCRIPTOR_CLEAR (descriptor, - MXFMetadataGenericSoundEssenceDescriptor, MXFMetadataFileDescriptor); - - descriptor->audio_sampling_rate.n = 48000; - descriptor->audio_sampling_rate.d = 1; -} - -gboolean - mxf_metadata_generic_picture_essence_descriptor_handle_tag - (MXFMetadataGenericDescriptor * d, const MXFPrimerPack * primer, - guint16 tag, const guint8 * tag_data, guint16 tag_size) -{ - MXFMetadataGenericPictureEssenceDescriptor *descriptor = - (MXFMetadataGenericPictureEssenceDescriptor *) d; - gboolean ret = FALSE; - gchar str[48]; - - switch (tag) { - case 0x3215: - if (tag_size != 1) - goto error; - descriptor->signal_standard = GST_READ_UINT8 (tag_data); - GST_DEBUG (" signal standard = %u", descriptor->signal_standard); - ret = TRUE; - break; - case 0x320c: - if (tag_size != 1) - goto error; - descriptor->frame_layout = GST_READ_UINT8 (tag_data); - GST_DEBUG (" frame layout = %u", descriptor->frame_layout); - ret = TRUE; - break; - case 0x3203: - if (tag_size != 4) - goto error; - descriptor->stored_width = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" stored width = %u", descriptor->stored_width); - ret = TRUE; - break; - case 0x3202: - if (tag_size != 4) - goto error; - descriptor->stored_height = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" stored height = %u", descriptor->stored_height); - ret = TRUE; - break; - case 0x3216: - if (tag_size != 4) - goto error; - descriptor->stored_f2_offset = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" stored f2 offset = %d", descriptor->stored_f2_offset); - ret = TRUE; - break; - case 0x3205: - if (tag_size != 4) - goto error; - descriptor->sampled_width = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" sampled width = %u", descriptor->sampled_width); - ret = TRUE; - break; - case 0x3204: - if (tag_size != 4) - goto error; - descriptor->sampled_height = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" sampled height = %u", descriptor->sampled_height); - ret = TRUE; - break; - case 0x3206: - if (tag_size != 4) - goto error; - descriptor->sampled_x_offset = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" sampled x offset = %d", descriptor->sampled_x_offset); - ret = TRUE; - break; - case 0x3207: - if (tag_size != 4) - goto error; - descriptor->sampled_y_offset = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" sampled y offset = %d", descriptor->sampled_y_offset); - ret = TRUE; - break; - case 0x3208: - if (tag_size != 4) - goto error; - descriptor->display_height = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" display height = %u", descriptor->display_height); - ret = TRUE; - break; - case 0x3209: - if (tag_size != 4) - goto error; - descriptor->display_width = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" display width = %u", descriptor->display_width); - ret = TRUE; - break; - case 0x320a: - if (tag_size != 4) - goto error; - descriptor->display_x_offset = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" display x offset = %d", descriptor->display_x_offset); - ret = TRUE; - break; - case 0x320b: - if (tag_size != 4) - goto error; - descriptor->display_y_offset = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" display y offset = %d", descriptor->display_y_offset); - ret = TRUE; - break; - case 0x3217: - if (tag_size != 4) - goto error; - descriptor->display_f2_offset = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" display f2 offset = %d", descriptor->display_f2_offset); - ret = TRUE; - break; - case 0x320e: - if (!mxf_fraction_parse (&descriptor->aspect_ratio, tag_data, tag_size)) - goto error; - GST_DEBUG (" aspect ratio = %d/%d", descriptor->aspect_ratio.n, - descriptor->aspect_ratio.d); - ret = TRUE; - break; - case 0x3218: - if (tag_size != 1) - goto error; - descriptor->active_format_descriptor = GST_READ_UINT8 (tag_data); - GST_DEBUG (" active format descriptor = %u", - descriptor->active_format_descriptor); - ret = TRUE; - break; - case 0x320d: - if (tag_size < 8) - goto error; - - if (GST_READ_UINT32_BE (tag_data) == 0) - return TRUE; - - if (GST_READ_UINT32_BE (tag_data) != 2 && - GST_READ_UINT32_BE (tag_data + 4) != 4) - goto error; - - if (tag_size != 16) - goto error; - - descriptor->video_line_map[0] = GST_READ_UINT32_BE (tag_data + 8); - descriptor->video_line_map[1] = GST_READ_UINT32_BE (tag_data + 12); - GST_DEBUG (" video line map = {%i, %i}", descriptor->video_line_map[0], - descriptor->video_line_map[1]); - ret = TRUE; - break; - case 0x320f: - if (tag_size != 1) - goto error; - descriptor->alpha_transparency = GST_READ_UINT8 (tag_data); - GST_DEBUG (" alpha transparency = %u", descriptor->alpha_transparency); - ret = TRUE; - break; - case 0x3210: - if (tag_size != 16) - goto error; - memcpy (&descriptor->capture_gamma, tag_data, 16); - GST_DEBUG (" capture gamma = %s", - mxf_ul_to_string (&descriptor->capture_gamma, str)); - ret = TRUE; - break; - case 0x3211: - if (tag_size != 4) - goto error; - descriptor->image_alignment_offset = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" image alignment offset = %u", - descriptor->image_alignment_offset); - ret = TRUE; - break; - case 0x3213: - if (tag_size != 4) - goto error; - descriptor->image_start_offset = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" image start offset = %u", descriptor->image_start_offset); - ret = TRUE; - break; - case 0x3214: - if (tag_size != 4) - goto error; - descriptor->image_end_offset = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" image end offset = %u", descriptor->image_end_offset); - ret = TRUE; - break; - case 0x3212: - if (tag_size != 1) - goto error; - descriptor->field_dominance = GST_READ_UINT8 (tag_data); - GST_DEBUG (" field dominance = %u", descriptor->field_dominance); - ret = TRUE; - break; - case 0x3201: - if (tag_size != 16) - goto error; - memcpy (&descriptor->picture_essence_coding, tag_data, 16); - GST_DEBUG (" picture essence coding = %s", - mxf_ul_to_string (&descriptor->picture_essence_coding, str)); - ret = TRUE; - break; - default: - ret = - mxf_metadata_file_descriptor_handle_tag (d, primer, tag, tag_data, - tag_size); - break; - } - - return ret; - -error: - GST_ERROR ("Invalid generic picture essence descriptor tag 0x%04x of size %u", - tag, tag_size); - - return TRUE; -} - -void mxf_metadata_generic_picture_essence_descriptor_reset - (MXFMetadataGenericPictureEssenceDescriptor * descriptor) -{ - g_return_if_fail (descriptor != NULL); - - mxf_metadata_file_descriptor_reset ((MXFMetadataFileDescriptor *) descriptor); - - MXF_METADATA_DESCRIPTOR_CLEAR (descriptor, - MXFMetadataGenericPictureEssenceDescriptor, MXFMetadataFileDescriptor); - - descriptor->signal_standard = 1; -} - -void mxf_metadata_generic_picture_essence_descriptor_set_caps - (MXFMetadataGenericPictureEssenceDescriptor * descriptor, GstCaps * caps) -{ - guint par_n, par_d; - guint width, height; - MXFMetadataFileDescriptor *f = (MXFMetadataFileDescriptor *) descriptor; - - g_return_if_fail (descriptor != NULL); - g_return_if_fail (GST_IS_CAPS (caps)); - - gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION, f->sample_rate.n, - f->sample_rate.d, NULL); - - width = descriptor->stored_width; - height = descriptor->stored_height; - - /* If the video is stored as separate fields the - * height is only the height of one field, i.e. - * half the height of the frame. - * - * See SMPTE 377M E2.2 and E1.2 - */ - if (descriptor->frame_layout != 0) - height *= 2; - - if (width == 0 || height == 0) - return; - - gst_caps_set_simple (caps, "width", G_TYPE_INT, width, "height", G_TYPE_INT, - height, NULL); - - if (descriptor->aspect_ratio.n == 0 || descriptor->aspect_ratio.d == 0) - return; - - par_n = height * descriptor->aspect_ratio.n; - par_d = width * descriptor->aspect_ratio.d; - - gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION, - par_n, par_d, NULL); -} - -gboolean - mxf_metadata_cdci_picture_essence_descriptor_handle_tag - (MXFMetadataGenericDescriptor * d, const MXFPrimerPack * primer, - guint16 tag, const guint8 * tag_data, guint16 tag_size) { - MXFMetadataCDCIPictureEssenceDescriptor *descriptor = - (MXFMetadataCDCIPictureEssenceDescriptor *) d; - gboolean ret = FALSE; - - switch (tag) { - case 0x3301: - if (tag_size != 4) - goto error; - descriptor->component_depth = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" component depth = %u", descriptor->component_depth); - ret = TRUE; - break; - case 0x3302: - if (tag_size != 4) - goto error; - descriptor->horizontal_subsampling = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" horizontal subsampling = %u", - descriptor->horizontal_subsampling); - ret = TRUE; - break; - case 0x3308: - if (tag_size != 4) - goto error; - descriptor->vertical_subsampling = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" vertical subsampling = %u", - descriptor->vertical_subsampling); - ret = TRUE; - break; - case 0x3303: - if (tag_size != 1) - goto error; - descriptor->color_siting = GST_READ_UINT8 (tag_data); - GST_DEBUG (" color siting = %u", descriptor->color_siting); - ret = TRUE; - break; - case 0x330b: - if (tag_size != 1) - goto error; - descriptor->reversed_byte_order = GST_READ_UINT8 (tag_data); - GST_DEBUG (" reversed byte order = %s", - (descriptor->reversed_byte_order) ? "yes" : "no"); - ret = TRUE; - break; - case 0x3307: - if (tag_size != 2) - goto error; - descriptor->padding_bits = GST_READ_UINT16_BE (tag_data); - GST_DEBUG (" padding bits = %d", descriptor->padding_bits); - ret = TRUE; - break; - case 0x3309: - if (tag_size != 4) - goto error; - descriptor->alpha_sample_depth = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" alpha sample depth = %u", descriptor->alpha_sample_depth); - ret = TRUE; - break; - case 0x3304: - if (tag_size != 4) - goto error; - descriptor->black_ref_level = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" black ref level = %u", descriptor->black_ref_level); - ret = TRUE; - break; - case 0x3305: - if (tag_size != 4) - goto error; - descriptor->white_ref_level = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" white ref level = %u", descriptor->white_ref_level); - ret = TRUE; - break; - case 0x3306: - if (tag_size != 4) - goto error; - descriptor->color_range = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" color range = %u", descriptor->color_range); - ret = TRUE; - break; - default: - ret = - mxf_metadata_generic_picture_essence_descriptor_handle_tag (d, primer, - tag, tag_data, tag_size); - break; - } - - return ret; - -error: - GST_ERROR ("Invalid CDCI picture essence descriptor tag 0x%04x of size %u", - tag, tag_size); - - return TRUE; -} - -void mxf_metadata_cdci_picture_essence_descriptor_reset - (MXFMetadataCDCIPictureEssenceDescriptor * descriptor) -{ - g_return_if_fail (descriptor != NULL); - - mxf_metadata_generic_picture_essence_descriptor_reset ( - (MXFMetadataGenericPictureEssenceDescriptor *) descriptor); - - MXF_METADATA_DESCRIPTOR_CLEAR (descriptor, - MXFMetadataCDCIPictureEssenceDescriptor, - MXFMetadataGenericPictureEssenceDescriptor); -} - -gboolean - mxf_metadata_rgba_picture_essence_descriptor_handle_tag - (MXFMetadataGenericDescriptor * d, const MXFPrimerPack * primer, - guint16 tag, const guint8 * tag_data, guint16 tag_size) -{ - MXFMetadataRGBAPictureEssenceDescriptor *descriptor = - (MXFMetadataRGBAPictureEssenceDescriptor *) d; - gboolean ret = FALSE; - - switch (tag) { - case 0x3406: - if (tag_size != 4) - goto error; - descriptor->component_max_ref = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" component max ref = %u", descriptor->component_max_ref); - ret = TRUE; - break; - case 0x3407: - if (tag_size != 4) - goto error; - descriptor->component_min_ref = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" component min ref = %u", descriptor->component_min_ref); - ret = TRUE; - break; - case 0x3408: - if (tag_size != 4) - goto error; - descriptor->alpha_max_ref = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" alpha max ref = %u", descriptor->alpha_max_ref); - ret = TRUE; - break; - case 0x3409: - if (tag_size != 4) - goto error; - descriptor->alpha_min_ref = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" alpha min ref = %u", descriptor->alpha_min_ref); - ret = TRUE; - break; - case 0x3405: - if (tag_size != 1) - goto error; - descriptor->scanning_direction = GST_READ_UINT8 (tag_data); - GST_DEBUG (" scanning direction = %u", descriptor->scanning_direction); - ret = TRUE; - break; - case 0x3401:{ - guint i, len; - - if (tag_size % 2 != 0) - goto error; - - i = 0; - while (tag_data[i] != 0 && tag_data[i + 1] != 0 && i + 2 <= tag_size) - i += 2; - len = i / 2; - - descriptor->n_pixel_layout = len; - GST_DEBUG (" number of pixel layouts = %u", len); - if (len == 0) - return TRUE; - - descriptor->pixel_layout = g_malloc0 (2 * len); - - for (i = 0; i < len; i++) { - descriptor->pixel_layout[2 * i] = tag_data[2 * i]; - descriptor->pixel_layout[2 * i + 1] = tag_data[2 * i + 1]; - GST_DEBUG (" pixel layout %u = %c : %u", i, - (gchar) descriptor->pixel_layout[2 * i], - descriptor->pixel_layout[2 * i + 1]); - } - - ret = TRUE; - break; - } - case 0x3403: - case 0x3404: - /* TODO: handle this */ - GST_WARNING (" tag 0x%04x not implemented yet", tag); - ret = TRUE; - break; - default: - ret = - mxf_metadata_generic_picture_essence_descriptor_handle_tag (d, primer, - tag, tag_data, tag_size); - break; - } - - return ret; - -error: - GST_ERROR ("Invalid RGBA picture essence descriptor tag 0x%04x of size %u", - tag, tag_size); - - return TRUE; -} - -void mxf_metadata_rgba_picture_essence_descriptor_reset - (MXFMetadataRGBAPictureEssenceDescriptor * descriptor) -{ - g_return_if_fail (descriptor != NULL); - - mxf_metadata_generic_picture_essence_descriptor_reset ( - (MXFMetadataGenericPictureEssenceDescriptor *) descriptor); - - g_free (descriptor->pixel_layout); - - MXF_METADATA_DESCRIPTOR_CLEAR (descriptor, - MXFMetadataRGBAPictureEssenceDescriptor, - MXFMetadataGenericPictureEssenceDescriptor); - - descriptor->component_max_ref = 255; - descriptor->alpha_max_ref = 255; -} - -gboolean - mxf_metadata_generic_data_essence_descriptor_handle_tag - (MXFMetadataGenericDescriptor * d, const MXFPrimerPack * primer, - guint16 tag, const guint8 * tag_data, guint16 tag_size) -{ - MXFMetadataGenericDataEssenceDescriptor *descriptor = - (MXFMetadataGenericDataEssenceDescriptor *) d; - gboolean ret = FALSE; - gchar str[48]; - - switch (tag) { - case 0x3e01: - if (tag_size != 16) - goto error; - memcpy (&descriptor->data_essence_compression, tag_data, 16); - GST_DEBUG (" data essence compression = %s", - mxf_ul_to_string (&descriptor->data_essence_compression, str)); - ret = TRUE; - break; - default: - ret = - mxf_metadata_file_descriptor_handle_tag (d, primer, tag, tag_data, - tag_size); - break; - } - - return ret; - -error: - GST_ERROR ("Invalid generic data essence descriptor tag 0x%04x of size %u", - tag, tag_size); - - return TRUE; -} - -void mxf_metadata_generic_data_essence_descriptor_reset - (MXFMetadataGenericDataEssenceDescriptor * descriptor) -{ - g_return_if_fail (descriptor != NULL); - - mxf_metadata_file_descriptor_reset ((MXFMetadataFileDescriptor *) descriptor); - - MXF_METADATA_DESCRIPTOR_CLEAR (descriptor, - MXFMetadataGenericDataEssenceDescriptor, MXFMetadataFileDescriptor); -} - -gboolean -mxf_metadata_multiple_descriptor_handle_tag (MXFMetadataGenericDescriptor * d, - const MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, - guint16 tag_size) -{ - MXFMetadataMultipleDescriptor *descriptor = - (MXFMetadataMultipleDescriptor *) d; - gboolean ret = FALSE; - gchar str[48]; - - switch (tag) { - case 0x3f01:{ - guint32 len; - guint i; - - if (tag_size < 8) - goto error; - len = GST_READ_UINT32_BE (tag_data); - GST_DEBUG (" number of sub descriptors = %u", len); - if (len == 0) - return TRUE; - - if (GST_READ_UINT32_BE (tag_data + 4) != 16) - goto error; - - descriptor->n_sub_descriptors = len; - descriptor->sub_descriptors_uids = g_new0 (MXFUL, len); - for (i = 0; i < len; i++) { - memcpy (&descriptor->sub_descriptors_uids[i], tag_data + 8 + i * 16, - 16); - GST_DEBUG (" sub descriptor %u = %s", i, - mxf_ul_to_string (&descriptor->sub_descriptors_uids[i], str)); - } - ret = TRUE; - break; - } - default: - ret = - mxf_metadata_file_descriptor_handle_tag (d, primer, tag, tag_data, - tag_size); - break; - } - - return ret; - -error: - GST_ERROR ("Invalid multiple descriptor tag 0x%04x of size %u", tag, - tag_size); - - return TRUE; -} - -void mxf_metadata_multiple_descriptor_reset - (MXFMetadataMultipleDescriptor * descriptor) -{ - g_return_if_fail (descriptor != NULL); - - g_free (descriptor->sub_descriptors_uids); - g_free (descriptor->sub_descriptors); - - mxf_metadata_file_descriptor_reset ((MXFMetadataFileDescriptor *) descriptor); - - MXF_METADATA_DESCRIPTOR_CLEAR (descriptor, MXFMetadataMultipleDescriptor, - MXFMetadataFileDescriptor); -} - -gboolean -mxf_metadata_locator_parse (const MXFUL * key, - MXFMetadataLocator * locator, const MXFPrimerPack * primer, - guint16 type, const guint8 * data, guint size) -{ - guint16 tag, tag_size; - const guint8 *tag_data; - gchar str[48]; - - g_return_val_if_fail (data != NULL, FALSE); - - memset (locator, 0, sizeof (MXFMetadataLocator)); - - locator->type = type; - - GST_DEBUG ("Parsing locator of type 0x%04x:", type); - - while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) { - if (tag_size == 0 || tag == 0x0000) - goto next; - - switch (tag) { - case 0x3c0a: - if (tag_size != 16) - goto error; - memcpy (&locator->instance_uid, tag_data, 16); - GST_DEBUG (" instance uid = %s", - mxf_ul_to_string (&locator->instance_uid, str)); - break; - case 0x0102: - if (tag_size != 16) - goto error; - memcpy (&locator->generation_uid, tag_data, 16); - GST_DEBUG (" generation uid = %s", - mxf_ul_to_string (&locator->generation_uid, str)); - break; - case 0x4101: - if (type != MXF_METADATA_TEXT_LOCATOR - && type != MXF_METADATA_NETWORK_LOCATOR) - goto DFLT; - locator->location = mxf_utf16_to_utf8 (tag_data, tag_size); - GST_DEBUG (" location = %s", GST_STR_NULL (locator->location)); - break; - DFLT: - default: - if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size, - &locator->other_tags)) - goto error; - break; - } - - next: - data += 4 + tag_size; - size -= 4 + tag_size; - } - - return TRUE; - -error: - GST_ERROR ("Invalid locator"); - mxf_metadata_locator_reset (locator); - - return FALSE; -} - -void -mxf_metadata_locator_reset (MXFMetadataLocator * locator) -{ - g_return_if_fail (locator != NULL); - - if (locator->location) - g_free (locator->location); - - if (locator->other_tags) - g_hash_table_destroy (locator->other_tags); - - memset (locator, 0, sizeof (MXFMetadataLocator)); -} diff --git a/gst/mxf/mxfparse.h b/gst/mxf/mxfparse.h index 200fc788..3e68f676 100644 --- a/gst/mxf/mxfparse.h +++ b/gst/mxf/mxfparse.h @@ -17,19 +17,18 @@ * Boston, MA 02111-1307, USA. */ +/* Handling of the basic MXF types */ + #ifndef __MXF_PARSE_H__ #define __MXF_PARSE_H__ #include <string.h> #include "mxftypes.h" +#include "mxfmetadata.h" typedef GstFlowReturn (*MXFEssenceElementHandler) (const MXFUL *key, GstBuffer *buffer, GstCaps *caps, MXFMetadataGenericPackage *package, MXFMetadataTrack *track, MXFMetadataStructuralComponent *component, gpointer mapping_data, GstBuffer **outbuf); -typedef gboolean (*MXFMetadataDescriptorHandleTag) (MXFMetadataGenericDescriptor *descriptor, - const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size); -typedef void (*MXFMetadataDescriptorReset) (MXFMetadataGenericDescriptor *descriptor); - gchar * mxf_ul_to_string (const MXFUL *ul, gchar str[48]); gboolean mxf_ul_is_equal (const MXFUL *a, const MXFUL *b); gboolean mxf_ul_is_zero (const MXFUL *ul); @@ -87,80 +86,9 @@ gboolean mxf_local_tag_parse (const guint8 * data, guint size, guint16 * tag, guint16 * tag_size, const guint8 ** tag_data); void gst_mxf_local_tag_free (MXFLocalTag *tag); -gboolean gst_metadata_add_custom_tag (const MXFPrimerPack *primer, +gboolean mxf_local_tag_add_to_hash_table (const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size, GHashTable **hash_table); -gboolean mxf_metadata_preface_parse (const MXFUL *key, MXFMetadataPreface *preface, const MXFPrimerPack *primer, const guint8 *data, guint size); -void mxf_metadata_preface_reset (MXFMetadataPreface *preface); - -gboolean mxf_metadata_identification_parse (const MXFUL *key, MXFMetadataIdentification *identification, const MXFPrimerPack *primer, const guint8 *data, guint size); -void mxf_metadata_identification_reset (MXFMetadataIdentification *identification); - -gboolean mxf_metadata_content_storage_parse (const MXFUL *key, MXFMetadataContentStorage *content_storage, const MXFPrimerPack *primer, const guint8 *data, guint size); -void mxf_metadata_content_storage_reset (MXFMetadataContentStorage *content_storage); - -gboolean mxf_metadata_essence_container_data_parse (const MXFUL *key, MXFMetadataEssenceContainerData *essence_container_data, const MXFPrimerPack *primer, const guint8 *data, guint size); -void mxf_metadata_essence_container_data_reset (MXFMetadataEssenceContainerData *essence_container_data); - -gboolean mxf_metadata_generic_package_parse (const MXFUL *key, MXFMetadataGenericPackage *generic_package, const MXFPrimerPack *primer, const guint8 *data, guint size); -void mxf_metadata_generic_package_reset (MXFMetadataGenericPackage *generic_package); - -gboolean mxf_metadata_track_parse (const MXFUL *key, MXFMetadataTrack *track, const MXFPrimerPack *primer, guint16 type, const guint8 *data, guint size); -void mxf_metadata_track_reset (MXFMetadataTrack *track); - -MXFMetadataTrackType mxf_metadata_track_identifier_parse (const MXFUL *track_identifier); - -gboolean mxf_metadata_sequence_parse (const MXFUL *key, MXFMetadataSequence *sequence, const MXFPrimerPack *primer, const guint8 *data, guint size); -void mxf_metadata_sequence_reset (MXFMetadataSequence *sequence); - -gboolean mxf_metadata_structural_component_parse (const MXFUL *key, MXFMetadataStructuralComponent *component, const MXFPrimerPack *primer, guint16 type, const guint8 *data, guint size); -void mxf_metadata_structural_component_reset (MXFMetadataStructuralComponent *component); - -gboolean -mxf_metadata_descriptor_parse (const MXFUL * key, MXFMetadataGenericDescriptor * descriptor, const MXFPrimerPack * primer, guint16 type, const guint8 * data, guint size, MXFMetadataDescriptorHandleTag handle_tag, MXFMetadataDescriptorReset reset); - -#define MXF_METADATA_DESCRIPTOR_CLEAR(descriptor, type, parent_type) \ - G_STMT_START { \ - guint8 *___data = (guint8 *) descriptor + sizeof (parent_type); \ - memset (___data, 0, sizeof (type) - sizeof (parent_type)); \ - } G_STMT_END - -gboolean mxf_metadata_generic_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor, - const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size); -void mxf_metadata_generic_descriptor_reset (MXFMetadataGenericDescriptor *descriptor); - -gboolean mxf_metadata_file_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor, - const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size); -void mxf_metadata_file_descriptor_reset (MXFMetadataFileDescriptor *descriptor); - -gboolean mxf_metadata_generic_sound_essence_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor, - const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size); -void mxf_metadata_generic_sound_essence_descriptor_reset (MXFMetadataGenericSoundEssenceDescriptor *descriptor); - -gboolean mxf_metadata_generic_picture_essence_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor, - const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size); -void mxf_metadata_generic_picture_essence_descriptor_reset (MXFMetadataGenericPictureEssenceDescriptor *descriptor); -void mxf_metadata_generic_picture_essence_descriptor_set_caps (MXFMetadataGenericPictureEssenceDescriptor *descriptor, GstCaps *caps); - -gboolean mxf_metadata_cdci_picture_essence_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor, - const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size); -void mxf_metadata_cdci_picture_essence_descriptor_reset (MXFMetadataCDCIPictureEssenceDescriptor *descriptor); - -gboolean mxf_metadata_rgba_picture_essence_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor, - const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size); -void mxf_metadata_rgba_picture_essence_descriptor_reset (MXFMetadataRGBAPictureEssenceDescriptor *descriptor); - -gboolean mxf_metadata_generic_data_essence_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor, - const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size); -void mxf_metadata_generic_data_essence_descriptor_reset (MXFMetadataGenericDataEssenceDescriptor *descriptor); - -gboolean mxf_metadata_multiple_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor, - const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size); -void mxf_metadata_multiple_descriptor_reset (MXFMetadataMultipleDescriptor *descriptor); - -gboolean mxf_metadata_locator_parse (const MXFUL *key, MXFMetadataLocator *locator, const MXFPrimerPack *primer, guint16 type, const guint8 *data, guint size); -void mxf_metadata_locator_reset (MXFMetadataLocator *locator); - #endif /* __MXF_PARSE_H__ */ diff --git a/gst/mxf/mxftypes.h b/gst/mxf/mxftypes.h index 241efd41..d6f374d5 100644 --- a/gst/mxf/mxftypes.h +++ b/gst/mxf/mxftypes.h @@ -17,6 +17,8 @@ * Boston, MA 02111-1307, USA. */ +/* Definitions of the basic MXF types, excluding structural metadata */ + #ifndef __MXF_TYPES_H__ #define __MXF_TYPES_H__ @@ -153,408 +155,4 @@ typedef struct { GHashTable *other_tags; } MXFIndexTableSegment; -/* SMPTE 377M 8.6 table 14 */ -#define MXF_METADATA_PREFACE (0x012f) -#define MXF_METADATA_IDENTIFICATION (0x0130) -#define MXF_METADATA_CONTENT_STORAGE (0x0118) -#define MXF_METADATA_ESSENCE_CONTAINER_DATA (0x0123) -#define MXF_METADATA_MATERIAL_PACKAGE (0x0136) -#define MXF_METADATA_SOURCE_PACKAGE (0x0137) -#define MXF_METADATA_TRACK (0x013b) -#define MXF_METADATA_EVENT_TRACK (0x0139) -#define MXF_METADATA_STATIC_TRACK (0x013a) -#define MXF_METADATA_SEQUENCE (0x010f) -#define MXF_METADATA_SOURCE_CLIP (0x0111) -#define MXF_METADATA_TIMECODE_COMPONENT (0x0114) -#define MXF_METADATA_DM_SEGMENT (0x0141) -#define MXF_METADATA_DM_SOURCE_CLIP (0x0145) -#define MXF_METADATA_FILE_DESCRIPTOR (0x0125) -#define MXF_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (0x0127) -#define MXF_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (0x0128) -#define MXF_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (0x0129) -#define MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (0x0142) -#define MXF_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR (0x0143) -#define MXF_METADATA_MULTIPLE_DESCRIPTOR (0x0144) -#define MXF_METADATA_NETWORK_LOCATOR (0x0132) -#define MXF_METADATA_TEXT_LOCATOR (0x0133) - -/* SMPTE 377M Annex A, B, C, D */ -typedef struct _MXFMetadataPreface MXFMetadataPreface; -typedef struct _MXFMetadataIdentification MXFMetadataIdentification; -typedef struct _MXFMetadataContentStorage MXFMetadataContentStorage; -typedef struct _MXFMetadataEssenceContainerData MXFMetadataEssenceContainerData; -typedef struct _MXFMetadataGenericPackage MXFMetadataGenericPackage; -typedef MXFMetadataGenericPackage MXFMetadataMaterialPackage; -typedef MXFMetadataGenericPackage MXFMetadataSourcePackage; -typedef struct _MXFMetadataTrack MXFMetadataTrack; -typedef struct _MXFMetadataSequence MXFMetadataSequence; -typedef struct _MXFMetadataStructuralComponent MXFMetadataStructuralComponent; -typedef struct _MXFMetadataGenericDescriptor MXFMetadataGenericDescriptor; -typedef struct _MXFMetadataFileDescriptor MXFMetadataFileDescriptor; -typedef struct _MXFMetadataGenericPictureEssenceDescriptor MXFMetadataGenericPictureEssenceDescriptor; -typedef struct _MXFMetadataCDCIPictureEssenceDescriptor MXFMetadataCDCIPictureEssenceDescriptor; -typedef struct _MXFMetadataRGBAPictureEssenceDescriptor MXFMetadataRGBAPictureEssenceDescriptor; -typedef struct _MXFMetadataGenericSoundEssenceDescriptor MXFMetadataGenericSoundEssenceDescriptor; -typedef struct _MXFMetadataGenericDataEssenceDescriptor MXFMetadataGenericDataEssenceDescriptor; -typedef struct _MXFMetadataMultipleDescriptor MXFMetadataMultipleDescriptor; -typedef struct _MXFMetadataLocator MXFMetadataLocator; - -struct _MXFMetadataPreface { - MXFUL instance_uid; - MXFUL generation_uid; - - MXFTimestamp last_modified_date; - guint16 version; - - guint32 object_model_version; - - MXFUL primary_package_uid; - MXFMetadataGenericPackage *primary_package; - - guint32 n_identifications; - MXFUL *identifications_uids; - MXFMetadataIdentification **identifications; - - MXFUL content_storage_uid; - MXFMetadataContentStorage *content_storage; - - MXFUL operational_pattern; - - guint32 n_essence_containers; - MXFUL *essence_containers; - - guint32 n_dm_schemes; - MXFUL *dm_schemes; - - GHashTable *other_tags; -}; - -struct _MXFMetadataIdentification { - MXFUL instance_uid; - MXFUL generation_uid; - - gchar *company_name; - - gchar *product_name; - MXFProductVersion product_version; - - gchar *version_string; - - MXFUL product_uid; - - MXFTimestamp modification_date; - - MXFProductVersion toolkit_version; - - gchar *platform; - - GHashTable *other_tags; -}; - -struct _MXFMetadataContentStorage { - MXFUL instance_uid; - MXFUL generation_uid; - - guint32 n_packages; - MXFUL *packages_uids; - MXFMetadataGenericPackage **packages; - - guint32 n_essence_container_data; - MXFUL *essence_container_data_uids; - MXFMetadataEssenceContainerData **essence_container_data; - - GHashTable *other_tags; -}; - -struct _MXFMetadataEssenceContainerData { - MXFUL instance_uid; - - MXFUMID linked_package_uid; - MXFMetadataGenericPackage *linked_package; - - MXFUL generation_uid; - - guint32 index_sid; - guint32 body_sid; - - GHashTable *other_tags; -}; - -typedef enum { - MXF_METADATA_GENERIC_PACKAGE_SOURCE = 0, - MXF_METADATA_GENERIC_PACKAGE_MATERIAL = 1, - MXF_METADATA_GENERIC_PACKAGE_TOP_LEVEL_SOURCE = 2 -} MXFMetadataGenericPackageType; - -struct _MXFMetadataGenericPackage { - MXFUL instance_uid; - MXFUMID package_uid; - MXFUL generation_uid; - - MXFMetadataGenericPackageType type; - - gchar *name; - MXFTimestamp package_creation_date; - MXFTimestamp package_modified_date; - - guint32 n_tracks; - MXFUL *tracks_uids; - MXFMetadataTrack **tracks; - - guint n_timecode_tracks; - guint n_metadata_tracks; - guint n_essence_tracks; - guint n_other_tracks; - - /* Only in Source packages */ - MXFUL descriptors_uid; - guint32 n_descriptors; - MXFMetadataGenericDescriptor **descriptors; - - GHashTable *other_tags; -}; - -typedef enum { - MXF_METADATA_TRACK_UNKNOWN = 0x00, - MXF_METADATA_TRACK_TIMECODE_12M_INACTIVE = 0x10, - MXF_METADATA_TRACK_TIMECODE_12M_ACTIVE = 0x11, - MXF_METADATA_TRACK_TIMECODE_309M = 0x12, - MXF_METADATA_TRACK_METADATA = 0x20, - MXF_METADATA_TRACK_PICTURE_ESSENCE = 0x30, - MXF_METADATA_TRACK_SOUND_ESSENCE = 0x31, - MXF_METADATA_TRACK_DATA_ESSENCE = 0x32, - MXF_METADATA_TRACK_AUXILIARY_DATA = 0x40, - MXF_METADATA_TRACK_PARSED_TEXT = 0x41 -} MXFMetadataTrackType; - -typedef enum { - MXF_METADATA_TRACK_VARIANT_TIMELINE, - MXF_METADATA_TRACK_VARIANT_EVENT, - MXF_METADATA_TRACK_VARIANT_STATIC -} MXFMetadataTrackVariant; - -struct _MXFMetadataTrack { - MXFUL instance_uid; - MXFUL generation_uid; - - guint32 track_id; - guint32 track_number; - - MXFMetadataTrackType type; - MXFMetadataTrackVariant variant; - - gchar *track_name; - - MXFFraction edit_rate; - - gint64 origin; - - MXFUL sequence_uid; - MXFMetadataSequence *sequence; - - MXFMetadataFileDescriptor **descriptor; - guint n_descriptor; - - GHashTable *other_tags; -}; - -struct _MXFMetadataSequence { - MXFUL instance_uid; - MXFUL generation_uid; - - MXFUL data_definition; - - gint64 duration; - - guint32 n_structural_components; - MXFUL *structural_components_uids; - MXFMetadataStructuralComponent **structural_components; - - GHashTable *other_tags; -}; - -struct _MXFMetadataStructuralComponent { - guint16 type; - - MXFUL instance_uid; - MXFUL generation_uid; - - MXFUL data_definition; - - gint64 duration; - - union { - struct { - gint64 start_timecode; - guint16 rounded_timecode_base; - gboolean drop_frame; - } timecode_component; - - struct { - gint64 start_position; - MXFUMID source_package_id; - MXFMetadataGenericPackage *source_package; - - guint32 source_track_id; - } source_clip; - - struct { - gint64 event_start_position; - gchar *event_comment; - - guint32 n_track_ids; - guint32 *track_ids; - - MXFUL dm_framework; - } dm_segment; - - struct { - gint64 start_position; - MXFUMID source_package_id; - MXFMetadataGenericPackage *source_package; - - guint32 source_track_id; - - guint32 n_track_ids; - guint32 *track_ids; - } dm_source_clip; - }; - - GHashTable *other_tags; -}; - -struct _MXFMetadataGenericDescriptor { - guint16 type; - - MXFUL instance_uid; - MXFUL generation_uid; - - guint32 n_locators; - MXFUL *locators_uids; - MXFMetadataLocator **locators; - - gboolean is_file_descriptor; - - GHashTable *other_tags; -}; - -struct _MXFMetadataFileDescriptor { - MXFMetadataGenericDescriptor parent; - - guint32 linked_track_id; - - MXFFraction sample_rate; - gint64 container_duration; - MXFUL essence_container; - MXFUL codec; -}; - -struct _MXFMetadataGenericPictureEssenceDescriptor { - MXFMetadataFileDescriptor parent; - - guint8 signal_standard; - guint8 frame_layout; - - guint32 stored_width; - guint32 stored_height; - gint32 stored_f2_offset; - guint32 sampled_width; - guint32 sampled_height; - gint32 sampled_x_offset; - gint32 sampled_y_offset; - guint32 display_height; - guint32 display_width; - gint32 display_x_offset; - gint32 display_y_offset; - gint32 display_f2_offset; - MXFFraction aspect_ratio; - - guint8 active_format_descriptor; - gint32 video_line_map[2]; - guint8 alpha_transparency; - MXFUL capture_gamma; - - guint32 image_alignment_offset; - guint32 image_start_offset; - guint32 image_end_offset; - - guint8 field_dominance; - - MXFUL picture_essence_coding; -}; - -struct _MXFMetadataCDCIPictureEssenceDescriptor { - MXFMetadataGenericPictureEssenceDescriptor parent; - - guint32 component_depth; - guint32 horizontal_subsampling; - guint32 vertical_subsampling; - guint8 color_siting; - gboolean reversed_byte_order; - gint16 padding_bits; - guint32 alpha_sample_depth; - guint32 black_ref_level; - guint32 white_ref_level; - guint32 color_range; -}; - -struct _MXFMetadataRGBAPictureEssenceDescriptor { - MXFMetadataGenericPictureEssenceDescriptor parent; - - guint32 component_max_ref; - guint32 component_min_ref; - guint32 alpha_max_ref; - guint32 alpha_min_ref; - guint8 scanning_direction; - - guint32 n_pixel_layout; - guint8 *pixel_layout; - - /* TODO: palette & palette layout */ -}; - -struct _MXFMetadataGenericSoundEssenceDescriptor { - MXFMetadataFileDescriptor parent; - - MXFFraction audio_sampling_rate; - - gboolean locked; - - gint8 audio_ref_level; - - guint8 electro_spatial_formulation; - - guint32 channel_count; - guint32 quantization_bits; - - gint8 dial_norm; - - MXFUL sound_essence_compression; -}; - -struct _MXFMetadataGenericDataEssenceDescriptor { - MXFMetadataFileDescriptor parent; - - MXFUL data_essence_compression; -}; - -struct _MXFMetadataMultipleDescriptor { - MXFMetadataFileDescriptor parent; - - MXFUL *sub_descriptors_uids; - guint32 n_sub_descriptors; - MXFMetadataGenericDescriptor **sub_descriptors; -}; - -struct _MXFMetadataLocator { - guint16 type; - - MXFUL instance_uid; - MXFUL generation_uid; - - gchar *location; - - GHashTable *other_tags; -}; - #endif /* __MXF_TYPES_H__ */ diff --git a/gst/mxf/mxfup.c b/gst/mxf/mxfup.c index 3b5259e6..38270428 100644 --- a/gst/mxf/mxfup.c +++ b/gst/mxf/mxfup.c @@ -61,7 +61,12 @@ mxf_is_up_essence_track (const MXFMetadataTrack * track) for (i = 0; i < track->n_descriptor; i++) { MXFMetadataFileDescriptor *d = track->descriptor[i]; - MXFUL *key = &d->essence_container; + MXFUL *key; + + if (!d) + continue; + + key = &d->essence_container; /* SMPTE 384M 8 */ if (mxf_is_generic_container_essence_container_label (key) && key->u[12] == 0x02 && key->u[13] == 0x05 && key->u[15] <= 0x03) @@ -216,13 +221,15 @@ mxf_up_create_caps (MXFMetadataGenericPackage * package, } for (i = 0; i < track->n_descriptor; i++) { - if (((MXFMetadataGenericDescriptor *) track->descriptor[i])->type == - MXF_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR) { + if (!track->descriptor[i]) + continue; + + if (MXF_IS_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (track->descriptor[i])) { p = (MXFMetadataGenericPictureEssenceDescriptor *) track->descriptor[i]; r = (MXFMetadataRGBAPictureEssenceDescriptor *) track->descriptor[i]; break; - } else if (((MXFMetadataGenericDescriptor *) track->descriptor[i])->type == - MXF_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR) { + } else if (MXF_IS_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (track-> + descriptor[i])) { p = (MXFMetadataGenericPictureEssenceDescriptor *) track->descriptor[i]; c = (MXFMetadataCDCIPictureEssenceDescriptor *) track->descriptor[i]; } @@ -250,3 +257,8 @@ mxf_up_create_caps (MXFMetadataGenericPackage * package, return caps; } + +void +mxf_up_init (void) +{ +} diff --git a/gst/mxf/mxfup.h b/gst/mxf/mxfup.h index 66fc849d..b575811a 100644 --- a/gst/mxf/mxfup.h +++ b/gst/mxf/mxfup.h @@ -33,4 +33,6 @@ gboolean mxf_is_up_essence_track (const MXFMetadataTrack *track); GstCaps * mxf_up_create_caps (MXFMetadataGenericPackage *package, MXFMetadataTrack *track, GstTagList **tags, MXFEssenceElementHandler *handler, gpointer *mapping_data); +void mxf_up_init (void); + #endif /* __MXF_UP_H__ */ |