diff options
author | Sebastian Dröge <slomo@circular-chaos.org> | 2009-01-22 11:37:22 +0100 |
---|---|---|
committer | Sebastian Dröge <slomo@circular-chaos.org> | 2009-01-22 13:12:59 +0100 |
commit | cd80f534f5c22faefd191c8b9f716b4d4b34a64d (patch) | |
tree | 5d1ba26af1af24e43ac0234b6ec4844e0f495f50 /gst | |
parent | 1b49a094feecae976611933269562f83d837b009 (diff) | |
download | gst-plugins-bad-cd80f534f5c22faefd191c8b9f716b4d4b34a64d.tar.gz gst-plugins-bad-cd80f534f5c22faefd191c8b9f716b4d4b34a64d.tar.bz2 gst-plugins-bad-cd80f534f5c22faefd191c8b9f716b4d4b34a64d.zip |
Implement parsing of DMS1 (SMPTE S380M)
Diffstat (limited to 'gst')
-rw-r--r-- | gst/mxf/mxf.c | 2 | ||||
-rw-r--r-- | gst/mxf/mxfalaw.c | 8 | ||||
-rw-r--r-- | gst/mxf/mxfd10.c | 16 | ||||
-rw-r--r-- | gst/mxf/mxfdemux.c | 38 | ||||
-rw-r--r-- | gst/mxf/mxfdms1.c | 6088 | ||||
-rw-r--r-- | gst/mxf/mxfdms1.h | 914 | ||||
-rw-r--r-- | gst/mxf/mxfjpeg2000.c | 8 | ||||
-rw-r--r-- | gst/mxf/mxfmetadata.c | 253 | ||||
-rw-r--r-- | gst/mxf/mxfmetadata.h | 73 | ||||
-rw-r--r-- | gst/mxf/mxfmpeg.c | 16 | ||||
-rw-r--r-- | gst/mxf/mxfup.c | 24 | ||||
-rw-r--r-- | gst/mxf/mxfvc3.c | 8 |
12 files changed, 7261 insertions, 187 deletions
diff --git a/gst/mxf/mxf.c b/gst/mxf/mxf.c index 655faf3a..236e8358 100644 --- a/gst/mxf/mxf.c +++ b/gst/mxf/mxf.c @@ -31,6 +31,7 @@ #include "mxfd10.h" #include "mxfup.h" #include "mxfvc3.h" +#include "mxfdms1.h" GST_DEBUG_CATEGORY (mxf_debug); #define GST_CAT_DEFAULT mxf_debug @@ -47,6 +48,7 @@ plugin_init (GstPlugin * plugin) mxf_d10_init (); mxf_up_init (); mxf_vc3_init (); + mxf_dms1_initialize (); if (!gst_element_register (plugin, "mxfdemux", GST_RANK_PRIMARY, GST_TYPE_MXF_DEMUX)) diff --git a/gst/mxf/mxfalaw.c b/gst/mxf/mxfalaw.c index a5ba98fb..18903770 100644 --- a/gst/mxf/mxfalaw.c +++ b/gst/mxf/mxfalaw.c @@ -100,10 +100,10 @@ mxf_alaw_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, if (!track->parent.descriptor[i]) continue; - if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->parent. - descriptor[i])) { - s = (MXFMetadataGenericSoundEssenceDescriptor *) track->parent. - descriptor[i]; + if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track-> + parent.descriptor[i])) { + s = (MXFMetadataGenericSoundEssenceDescriptor *) track-> + parent.descriptor[i]; break; } } diff --git a/gst/mxf/mxfd10.c b/gst/mxf/mxfd10.c index 6af96006..43d68d0e 100644 --- a/gst/mxf/mxfd10.c +++ b/gst/mxf/mxfd10.c @@ -173,15 +173,15 @@ mxf_d10_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, if (!track->parent.descriptor[i]) continue; - if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track->parent. - descriptor[i])) { - p = (MXFMetadataGenericPictureEssenceDescriptor *) track-> - parent.descriptor[i]; + if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track-> + parent.descriptor[i])) { + p = (MXFMetadataGenericPictureEssenceDescriptor *) track->parent. + descriptor[i]; break; - } else if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->parent. - descriptor[i])) { - s = (MXFMetadataGenericSoundEssenceDescriptor *) track-> - parent.descriptor[i]; + } else if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track-> + parent.descriptor[i])) { + s = (MXFMetadataGenericSoundEssenceDescriptor *) track->parent. + descriptor[i]; break; } } diff --git a/gst/mxf/mxfdemux.c b/gst/mxf/mxfdemux.c index 2ddc9d3e..8d3505e1 100644 --- a/gst/mxf/mxfdemux.c +++ b/gst/mxf/mxfdemux.c @@ -558,11 +558,11 @@ gst_mxf_demux_choose_package (GstMXFDemux * demux) 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])) { + MXF_IS_METADATA_MATERIAL_PACKAGE (demux->preface-> + content_storage->packages[i])) { ret = - MXF_METADATA_GENERIC_PACKAGE (demux->preface->content_storage-> - packages[i]); + MXF_METADATA_GENERIC_PACKAGE (demux->preface-> + content_storage->packages[i]); break; } } @@ -908,6 +908,7 @@ gst_mxf_demux_handle_descriptive_metadata (GstMXFDemux * demux, guint32 type; guint8 scheme; GstFlowReturn ret = GST_FLOW_OK; + MXFDescriptiveMetadata *m = NULL; scheme = GST_READ_UINT8 (key->u + 12); type = GST_READ_UINT24_BE (key->u + 13); @@ -933,14 +934,23 @@ gst_mxf_demux_handle_descriptive_metadata (GstMXFDemux * demux, return GST_FLOW_OK; } - switch (type) { - default: - GST_WARNING_OBJECT (demux, - "Unknown or unhandled descriptive metadata of scheme 0x%02x and type 0x%06x", - scheme, type); - break; + + m = mxf_descriptive_metadata_new (scheme, type, &demux->primer, + GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer)); + + if (!m) { + GST_WARNING_OBJECT (demux, + "Unknown or unhandled descriptive metadata of scheme 0x%02x and type 0x%06x", + scheme, type); + return GST_FLOW_OK; } + if (!demux->metadata) + demux->metadata = g_ptr_array_new (); + + g_ptr_array_add (demux->metadata, m); + + return ret; } @@ -975,8 +985,8 @@ gst_mxf_demux_pad_next_component (GstMXFDemux * demux, GstMXFDemuxPad * pad) GST_DEBUG_OBJECT (demux, "Switching to component %u", pad->current_component); pad->component = - MXF_METADATA_SOURCE_CLIP (sequence->structural_components[pad-> - current_component]); + MXF_METADATA_SOURCE_CLIP (sequence-> + structural_components[pad->current_component]); if (pad->component == NULL) { GST_ERROR_OBJECT (demux, "No such structural component"); return GST_FLOW_ERROR; @@ -984,8 +994,8 @@ gst_mxf_demux_pad_next_component (GstMXFDemux * demux, GstMXFDemuxPad * pad) if (!pad->component->source_package || !pad->component->source_package->top_level - || !MXF_METADATA_GENERIC_PACKAGE (pad->component-> - source_package)->tracks) { + || !MXF_METADATA_GENERIC_PACKAGE (pad->component->source_package)-> + tracks) { GST_ERROR_OBJECT (demux, "Invalid component"); return GST_FLOW_ERROR; } diff --git a/gst/mxf/mxfdms1.c b/gst/mxf/mxfdms1.c index 89ef14a9..a0ffe11d 100644 --- a/gst/mxf/mxfdms1.c +++ b/gst/mxf/mxfdms1.c @@ -19,6 +19,11 @@ /* Implementation of SMPTE S380M - Descriptive Metadata Scheme-1 */ +/* TODO: + * - What are the "locators"? + * - Create sensible tags from this + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -27,3 +32,6086 @@ #include <string.h> #include "mxfdms1.h" +#include "mxfparse.h" + +GST_DEBUG_CATEGORY_EXTERN (mxf_debug); +#define GST_CAT_DEFAULT mxf_debug + +G_DEFINE_TYPE (MXFDMS1, mxf_dms1, MXF_TYPE_DESCRIPTIVE_METADATA); + +static gboolean +mxf_dms1_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer, + guint16 tag, const guint8 * tag_data, guint tag_size) +{ + MXFDMS1 *self = MXF_DMS1 (metadata); + gboolean ret = TRUE; +#ifndef GST_DISABLE_GST_DEBUG + gchar str[48]; +#endif + MXFUL *tag_ul = NULL; + static const guint8 instance_uid_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x15, 0x02, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 generation_uid_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, 0x05, + 0x20, 0x07, 0x01, 0x08, 0x00, 0x00, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &instance_uid_ul, 16) == 0) { + if (tag_size != 16) + goto error; + memcpy (&MXF_METADATA_BASE (self)->instance_uid, tag_data, 16); + GST_DEBUG (" instance uid = %s", + mxf_ul_to_string (&MXF_METADATA_BASE (self)->instance_uid, str)); + } else if (memcmp (tag_ul, &generation_uid_ul, 16) == 0) { + if (tag_size != 16) + goto error; + memcpy (&MXF_METADATA_BASE (self)->generation_uid, tag_data, 16); + GST_DEBUG (" generation uid = %s", + mxf_ul_to_string (&MXF_METADATA_BASE (self)->generation_uid, str)); + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 local tag 0x%04x of size %u", tag, tag_size); + + return FALSE; +} + +static void +mxf_dms1_init (MXFDMS1 * self) +{ +} + +static void +mxf_dms1_class_init (MXFDMS1Class * klass) +{ + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + metadatabase_class->handle_tag = mxf_dms1_handle_tag; +} + +G_DEFINE_ABSTRACT_TYPE (MXFDMS1TextLanguage, mxf_dms1_text_language, + MXF_TYPE_DMS1); + +static gboolean +mxf_dms1_text_language_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1TextLanguage *self = MXF_DMS1_TEXT_LANGUAGE (metadata); + gboolean ret = TRUE; + MXFUL *tag_ul = NULL; + static const guint8 extended_text_language_code_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x03, + 0x01, 0x01, 0x02, 0x02, 0x11, 0x00, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &extended_text_language_code_ul, 16) == 0) { + if (tag_size > 12) + goto error; + + memcpy (self->extended_text_language_code, tag_data, tag_size); + GST_DEBUG (" extended text language code = %s", + self->extended_text_language_code); + } else { + ret = + MXF_METADATA_BASE_CLASS + (mxf_dms1_text_language_parent_class)->handle_tag (metadata, primer, + tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 text language local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_dms1_text_language_init (MXFDMS1TextLanguage * self) +{ +} + +static void +mxf_dms1_text_language_class_init (MXFDMS1TextLanguageClass * klass) +{ + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + metadatabase_class->handle_tag = mxf_dms1_text_language_handle_tag; +} + +G_DEFINE_ABSTRACT_TYPE (MXFDMS1Thesaurus, mxf_dms1_thesaurus, + MXF_TYPE_DMS1_TEXT_LANGUAGE); + +static void +mxf_dms1_thesaurus_finalize (GstMiniObject * object) +{ + MXFDMS1Thesaurus *self = MXF_DMS1_THESAURUS (object); + + g_free (self->thesaurus_name); + self->thesaurus_name = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_thesaurus_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_thesaurus_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1Thesaurus *self = MXF_DMS1_THESAURUS (metadata); + gboolean ret = TRUE; + MXFUL *tag_ul = NULL; + static const guint8 thesaurus_name_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x01, 0x00, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &thesaurus_name_ul, 16) == 0) { + self->thesaurus_name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" thesaurus name = %s", GST_STR_NULL (self->thesaurus_name)); + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_thesaurus_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; +} + +static void +mxf_dms1_thesaurus_init (MXFDMS1Thesaurus * self) +{ +} + +static void +mxf_dms1_thesaurus_class_init (MXFDMS1ThesaurusClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_thesaurus_finalize; + metadatabase_class->handle_tag = mxf_dms1_thesaurus_handle_tag; +} + +static void +mxf_dms1_framework_interface_init (gpointer g_iface, gpointer iface_data) +{ +} + +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MXFDMS1Framework, mxf_dms1_framework, + MXF_TYPE_DMS1, + G_IMPLEMENT_INTERFACE (MXF_TYPE_DESCRIPTIVE_METADATA_FRAMEWORK, + mxf_dms1_framework_interface_init)); + +static void +mxf_dms1_framework_finalize (GstMiniObject * object) +{ + MXFDMS1Framework *self = MXF_DMS1_FRAMEWORK (object); + + g_free (self->framework_thesaurus_name); + self->framework_thesaurus_name = NULL; + + g_free (self->framework_title); + self->framework_title = NULL; + + g_free (self->metadata_server_locators_uids); + self->metadata_server_locators_uids = NULL; + + g_free (self->titles_sets_uids); + self->titles_sets_uids = NULL; + + g_free (self->titles_sets); + self->titles_sets = NULL; + + g_free (self->annotations_sets_uids); + self->annotations_sets_uids = NULL; + + g_free (self->annotations_sets); + self->annotations_sets = NULL; + + g_free (self->participant_sets_uids); + self->participant_sets_uids = NULL; + + g_free (self->participant_sets); + self->participant_sets = NULL; + + g_free (self->location_sets_uids); + self->location_sets_uids = NULL; + + g_free (self->location_sets); + self->location_sets = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_framework_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_framework_resolve (MXFMetadataBase * m, MXFMetadataBase ** metadata) +{ + MXFDMS1Framework *self = MXF_DMS1_FRAMEWORK (m); + MXFMetadataBase **p = metadata, *current = NULL; + guint i; + + self->titles_sets = g_new0 (MXFDMS1Titles *, self->n_titles_sets); + self->annotations_sets = + g_new0 (MXFDMS1Annotation *, self->n_annotations_sets); + self->participant_sets = + g_new0 (MXFDMS1Participant *, self->n_participant_sets); + self->location_sets = g_new0 (MXFDMS1Location *, self->n_location_sets); + while (*p != NULL) { + current = *p; + + if (MXF_IS_DMS1_TITLES (current)) { + for (i = 0; i < self->n_titles_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->titles_sets_uids[i])) { + self->titles_sets[i] = MXF_DMS1_TITLES (current); + break; + } + } + } + + if (MXF_IS_DMS1_ANNOTATION (current)) { + for (i = 0; i < self->n_annotations_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->annotations_sets_uids[i])) { + self->annotations_sets[i] = MXF_DMS1_ANNOTATION (current); + break; + } + } + } + + if (MXF_IS_DMS1_PARTICIPANT (current)) { + for (i = 0; i < self->n_participant_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->participant_sets_uids[i])) { + self->participant_sets[i] = MXF_DMS1_PARTICIPANT (current); + break; + } + } + } + + if (MXF_IS_DMS1_CONTACTS_LIST (current)) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->contacts_list_set_uid)) { + self->contacts_list_set = MXF_DMS1_CONTACTS_LIST (current); + } + } + + if (MXF_IS_DMS1_LOCATION (current)) { + for (i = 0; i < self->n_location_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->location_sets_uids[i])) { + self->location_sets[i] = MXF_DMS1_LOCATION (current); + break; + } + } + } + + p++; + } + + return MXF_METADATA_BASE_CLASS (mxf_dms1_framework_parent_class)->resolve (m, + metadata); +} + +static gboolean +mxf_dms1_framework_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1Framework *self = MXF_DMS1_FRAMEWORK (metadata); + gboolean ret = TRUE; +#ifndef GST_DISABLE_GST_DEBUG + gchar str[48]; +#endif + MXFUL *tag_ul = NULL; + static const guint8 framework_extended_text_language_code_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x03, + 0x01, 0x01, 0x02, 0x02, 0x13, 0x00, 0x00 + }; + static const guint8 framework_thesaurus_name_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03, + 0x02, 0x01, 0x02, 0x15, 0x01, 0x00, 0x00 + }; + static const guint8 framework_title_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x01, + 0x05, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 primary_extended_spoken_language_code_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x03, + 0x01, 0x01, 0x02, 0x03, 0x11, 0x00, 0x00 + }; + static const guint8 secondary_extended_spoken_language_code_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x03, + 0x01, 0x01, 0x02, 0x03, 0x12, 0x00, 0x00 + }; + static const guint8 original_extended_spoken_language_code_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x03, + 0x01, 0x01, 0x02, 0x03, 0x13, 0x00, 0x00 + }; + static const guint8 metadata_server_locators_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x06, 0x0C, 0x00, 0x00 + }; + static const guint8 titles_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x04, 0x00 + }; + static const guint8 annotation_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x0d, 0x00 + }; + static const guint8 participant_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x13, 0x00 + }; + static const guint8 contacts_list_set_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x02, 0x40, 0x22, 0x00 + }; + static const guint8 location_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x03, 0x40, 0x16, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &framework_extended_text_language_code_ul, 16) == 0) { + if (tag_size > 12) + goto error; + memcpy (&self->framework_extended_text_language_code, tag_data, tag_size); + GST_DEBUG (" framework extended text language code = %s", + self->framework_extended_text_language_code); + } else if (memcmp (tag_ul, &framework_thesaurus_name_ul, 16) == 0) { + self->framework_thesaurus_name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" framework thesaurus name = %s", + GST_STR_NULL (self->framework_thesaurus_name)); + } else if (memcmp (tag_ul, &framework_title_ul, 16) == 0) { + self->framework_title = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" framework title = %s", GST_STR_NULL (self->framework_title)); + } else if (memcmp (tag_ul, &primary_extended_spoken_language_code_ul, + 16) == 0) { + if (tag_size > 12) + goto error; + memcpy (&self->primary_extended_spoken_language_code, tag_data, tag_size); + GST_DEBUG (" primary extended spoken language code = %s", + self->primary_extended_spoken_language_code); + } else if (memcmp (tag_ul, &secondary_extended_spoken_language_code_ul, + 16) == 0) { + if (tag_size > 12) + goto error; + memcpy (&self->secondary_extended_spoken_language_code, tag_data, tag_size); + GST_DEBUG (" secondary extended spoken language code = %s", + self->secondary_extended_spoken_language_code); + } else if (memcmp (tag_ul, &original_extended_spoken_language_code_ul, + 16) == 0) { + if (tag_size > 12) + goto error; + memcpy (&self->original_extended_spoken_language_code, tag_data, tag_size); + GST_DEBUG (" original extended spoken language code = %s", + self->original_extended_spoken_language_code); + } else if (memcmp (tag_ul, &metadata_server_locators_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of metadata server locators = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_metadata_server_locators = len; + self->metadata_server_locators_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->metadata_server_locators_uids[i], tag_data, 16); + GST_DEBUG (" metadata server locator %u = %s", i, + mxf_ul_to_string (&self->metadata_server_locators_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &titles_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of titles sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_titles_sets = len; + self->titles_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->titles_sets_uids[i], tag_data, 16); + GST_DEBUG (" titles sets %u = %s", i, + mxf_ul_to_string (&self->titles_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &annotation_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of annotation sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_annotations_sets = len; + self->annotations_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->annotations_sets_uids[i], tag_data, 16); + GST_DEBUG (" annotation sets %u = %s", i, + mxf_ul_to_string (&self->annotations_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &participant_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of participant sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_participant_sets = len; + self->participant_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->participant_sets_uids[i], tag_data, 16); + GST_DEBUG (" participant sets %u = %s", i, + mxf_ul_to_string (&self->participant_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &contacts_list_set_ul, 16) == 0) { + if (tag_size != 16) + goto error; + + memcpy (&self->contacts_list_set_uid, tag_data, 16); + GST_DEBUG (" contacts list = %s", + mxf_ul_to_string (&self->contacts_list_set_uid, str)); + } else if (memcmp (tag_ul, &location_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of location sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_location_sets = len; + self->location_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->location_sets_uids[i], tag_data, 16); + GST_DEBUG (" location sets %u = %s", i, + mxf_ul_to_string (&self->location_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_framework_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 framework local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_dms1_framework_init (MXFDMS1Framework * self) +{ +} + +static void +mxf_dms1_framework_class_init (MXFDMS1FrameworkClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_framework_finalize; + metadatabase_class->handle_tag = mxf_dms1_framework_handle_tag; + metadatabase_class->resolve = mxf_dms1_framework_resolve; +} + +G_DEFINE_ABSTRACT_TYPE (MXFDMS1ProductionClipFramework, + mxf_dms1_production_clip_framework, MXF_TYPE_DMS1_FRAMEWORK); + +static void +mxf_dms1_production_clip_framework_finalize (GstMiniObject * object) +{ + MXFDMS1ProductionClipFramework *self = + MXF_DMS1_PRODUCTION_CLIP_FRAMEWORK (object); + + g_free (self->captions_description_sets_uids); + self->captions_description_sets_uids = NULL; + + g_free (self->captions_description_sets); + self->captions_description_sets = NULL; + + g_free (self->contract_sets_uids); + self->contract_sets_uids = NULL; + + g_free (self->contract_sets); + self->contract_sets = NULL; + + GST_MINI_OBJECT_CLASS + (mxf_dms1_production_clip_framework_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_production_clip_framework_resolve (MXFMetadataBase * m, + MXFMetadataBase ** metadata) +{ + MXFDMS1ProductionClipFramework *self = MXF_DMS1_PRODUCTION_CLIP_FRAMEWORK (m); + MXFMetadataBase **p = metadata, *current = NULL; + guint i; + + self->captions_description_sets = + g_new0 (MXFDMS1CaptionsDescription *, self->n_captions_description_sets); + self->contract_sets = g_new0 (MXFDMS1Contract *, self->n_contract_sets); + while (*p) { + current = *p; + + if (MXF_IS_DMS1_PICTURE_FORMAT (current)) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->picture_format_set_uid)) { + self->picture_format = MXF_DMS1_PICTURE_FORMAT (current); + } + } + + if (MXF_IS_DMS1_CAPTIONS_DESCRIPTION (current)) { + for (i = 0; i < self->n_captions_description_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->captions_description_sets_uids[i])) { + self->captions_description_sets[i] = + MXF_DMS1_CAPTIONS_DESCRIPTION (current); + break; + } + } + } + + if (MXF_IS_DMS1_CONTRACT (current)) { + for (i = 0; i < self->n_contract_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->contract_sets_uids[i])) { + self->contract_sets[i] = MXF_DMS1_CONTRACT (current); + break; + } + } + } + + if (MXF_IS_DMS1_PROJECT (current)) { + if (mxf_ul_is_equal (¤t->instance_uid, &self->project_set_uid)) { + self->project_set = MXF_DMS1_PROJECT (current); + } + } + + p++; + } + + return + MXF_METADATA_BASE_CLASS + (mxf_dms1_production_clip_framework_parent_class)->resolve (m, metadata); +} + +static gboolean +mxf_dms1_production_clip_framework_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1ProductionClipFramework *self = + MXF_DMS1_PRODUCTION_CLIP_FRAMEWORK (metadata); + gboolean ret = TRUE; +#ifndef GST_DISABLE_GST_DEBUG + gchar str[48]; +#endif + MXFUL *tag_ul = NULL; + static const guint8 picture_format_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x02, 0x40, 0x1d, 0x00 + }; + static const guint8 captions_description_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x0c, 0x00 + }; + static const guint8 contract_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x19, 0x00 + }; + static const guint8 project_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x02, 0x40, 0x21, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &picture_format_ul, 16) == 0) { + if (tag_size != 16) + goto error; + + memcpy (&self->picture_format_set_uid, tag_data, 16); + GST_DEBUG (" picture format set = %s", + mxf_ul_to_string (&self->picture_format_set_uid, str)); + } else if (memcmp (tag_ul, &captions_description_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of captions description sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_captions_description_sets = len; + self->captions_description_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->captions_description_sets_uids[i], tag_data, 16); + GST_DEBUG (" captions description sets %u = %s", i, + mxf_ul_to_string (&self->captions_description_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &contract_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of contract sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_contract_sets = len; + self->contract_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->contract_sets_uids[i], tag_data, 16); + GST_DEBUG (" contract sets %u = %s", i, + mxf_ul_to_string (&self->contract_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &project_ul, 16) == 0) { + if (tag_size != 16) + goto error; + + memcpy (&self->project_set_uid, tag_data, 16); + GST_DEBUG (" project set = %s", mxf_ul_to_string (&self->project_set_uid, + str)); + } else { + ret = + MXF_METADATA_BASE_CLASS + (mxf_dms1_production_clip_framework_parent_class)->handle_tag (metadata, + primer, tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR + ("Invalid DMS1 production-clip framework local tag 0x%04x of size %u", + tag, tag_size); + + return FALSE; +} + +static void +mxf_dms1_production_clip_framework_init (MXFDMS1ProductionClipFramework * self) +{ +} + +static void + mxf_dms1_production_clip_framework_class_init + (MXFDMS1ProductionClipFrameworkClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_production_clip_framework_finalize; + metadatabase_class->handle_tag = + mxf_dms1_production_clip_framework_handle_tag; + metadatabase_class->resolve = mxf_dms1_production_clip_framework_resolve; +} + +G_DEFINE_TYPE (MXFDMS1ProductionFramework, mxf_dms1_production_framework, + MXF_TYPE_DMS1_PRODUCTION_CLIP_FRAMEWORK); + +static void +mxf_dms1_production_framework_finalize (GstMiniObject * object) +{ + MXFDMS1ProductionFramework *self = MXF_DMS1_PRODUCTION_FRAMEWORK (object); + + g_free (self->integration_indication); + self->integration_indication = NULL; + + g_free (self->identification_sets_uids); + self->identification_sets_uids = NULL; + + g_free (self->identification_sets); + self->identification_sets = NULL; + + g_free (self->group_relationship_sets_uids); + self->group_relationship_sets_uids = NULL; + + g_free (self->group_relationship_sets); + self->group_relationship_sets = NULL; + + g_free (self->branding_sets_uids); + self->branding_sets_uids = NULL; + + g_free (self->branding_sets); + self->branding_sets = NULL; + + g_free (self->event_sets_uids); + self->event_sets_uids = NULL; + + g_free (self->event_sets); + self->event_sets = NULL; + + g_free (self->award_sets_uids); + self->award_sets_uids = NULL; + + g_free (self->award_sets); + self->award_sets = NULL; + + g_free (self->setting_period_sets_uids); + self->setting_period_sets_uids = NULL; + + g_free (self->setting_period_sets); + self->setting_period_sets = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_production_framework_parent_class)->finalize + (object); +} + +static gboolean +mxf_dms1_production_framework_resolve (MXFMetadataBase * m, + MXFMetadataBase ** metadata) +{ + MXFDMS1ProductionFramework *self = MXF_DMS1_PRODUCTION_FRAMEWORK (m); + MXFMetadataBase **p = metadata, *current = NULL; + guint i; + + self->identification_sets = + g_new0 (MXFDMS1Identification *, self->n_identification_sets); + self->group_relationship_sets = + g_new0 (MXFDMS1GroupRelationship *, self->n_group_relationship_sets); + self->branding_sets = g_new0 (MXFDMS1Branding *, self->n_branding_sets); + self->event_sets = g_new0 (MXFDMS1Event *, self->n_event_sets); + self->award_sets = g_new0 (MXFDMS1Award *, self->n_award_sets); + self->setting_period_sets = + g_new0 (MXFDMS1SettingPeriod *, self->n_setting_period_sets); + while (*p) { + current = *p; + + if (MXF_IS_DMS1_IDENTIFICATION (current)) { + for (i = 0; i < self->n_identification_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->identification_sets_uids[i])) { + self->identification_sets[i] = MXF_DMS1_IDENTIFICATION (current); + } + } + } + + if (MXF_IS_DMS1_GROUP_RELATIONSHIP (current)) { + for (i = 0; i < self->n_group_relationship_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->group_relationship_sets_uids[i])) { + self->group_relationship_sets[i] = + MXF_DMS1_GROUP_RELATIONSHIP (current); + } + } + } + + if (MXF_IS_DMS1_BRANDING (current)) { + for (i = 0; i < self->n_branding_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->branding_sets_uids[i])) { + self->branding_sets[i] = MXF_DMS1_BRANDING (current); + } + } + } + + if (MXF_IS_DMS1_EVENT (current)) { + for (i = 0; i < self->n_event_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, &self->event_sets_uids[i])) { + self->event_sets[i] = MXF_DMS1_EVENT (current); + } + } + } + + if (MXF_IS_DMS1_AWARD (current)) { + for (i = 0; i < self->n_award_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, &self->award_sets_uids[i])) { + self->award_sets[i] = MXF_DMS1_AWARD (current); + } + } + } + + if (MXF_IS_DMS1_SETTING_PERIOD (current)) { + for (i = 0; i < self->n_setting_period_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->setting_period_sets_uids[i])) { + self->setting_period_sets[i] = MXF_DMS1_SETTING_PERIOD (current); + } + } + } + + p++; + } + + return + MXF_METADATA_BASE_CLASS + (mxf_dms1_production_framework_parent_class)->resolve (m, metadata); +} + +static gboolean +mxf_dms1_production_framework_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1ProductionFramework *self = MXF_DMS1_PRODUCTION_FRAMEWORK (metadata); + gboolean ret = TRUE; +#ifndef GST_DISABLE_GST_DEBUG + gchar str[48]; +#endif + MXFUL *tag_ul = NULL; + static const guint8 integration_indication_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x05, + 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00 + }; + static const guint8 identification_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x06, 0x00 + }; + static const guint8 group_relationship_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x05, 0x00 + }; + static const guint8 branding_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x08, 0x00 + }; + static const guint8 event_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x09, 0x00 + }; + static const guint8 award_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x0b, 0x00 + }; + static const guint8 setting_period_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x0e, 0x01 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &integration_indication_ul, 16) == 0) { + self->integration_indication = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" integration indication = %s", + GST_STR_NULL (self->integration_indication)); + } else if (memcmp (tag_ul, &identification_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of identification sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_identification_sets = len; + self->identification_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->identification_sets_uids[i], tag_data, 16); + GST_DEBUG (" identification sets %u = %s", i, + mxf_ul_to_string (&self->identification_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &group_relationship_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of group relationship sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_group_relationship_sets = len; + self->group_relationship_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->group_relationship_sets_uids[i], tag_data, 16); + GST_DEBUG (" group relationship sets %u = %s", i, + mxf_ul_to_string (&self->group_relationship_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &branding_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of branding sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_branding_sets = len; + self->branding_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->branding_sets_uids[i], tag_data, 16); + GST_DEBUG (" branding sets %u = %s", i, + mxf_ul_to_string (&self->branding_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &event_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of event sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_event_sets = len; + self->event_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->event_sets_uids[i], tag_data, 16); + GST_DEBUG (" event sets %u = %s", i, + mxf_ul_to_string (&self->event_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &award_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of award sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_award_sets = len; + self->award_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->award_sets_uids[i], tag_data, 16); + GST_DEBUG (" award sets %u = %s", i, + mxf_ul_to_string (&self->award_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &setting_period_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of setting period sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_setting_period_sets = len; + self->setting_period_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->setting_period_sets_uids[i], tag_data, 16); + GST_DEBUG (" setting period sets %u = %s", i, + mxf_ul_to_string (&self->setting_period_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else { + ret = + MXF_METADATA_BASE_CLASS + (mxf_dms1_production_framework_parent_class)->handle_tag (metadata, + primer, tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 production framework local tag 0x%04x of size %u", + tag, tag_size); + + return FALSE; +} + +static void +mxf_dms1_production_framework_init (MXFDMS1ProductionFramework * self) +{ +} + +static void +mxf_dms1_production_framework_class_init (MXFDMS1ProductionFrameworkClass * + klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_production_framework_finalize; + metadatabase_class->handle_tag = mxf_dms1_production_framework_handle_tag; + metadatabase_class->resolve = mxf_dms1_production_framework_resolve; +} + +G_DEFINE_TYPE (MXFDMS1ClipFramework, mxf_dms1_clip_framework, + MXF_TYPE_DMS1_PRODUCTION_CLIP_FRAMEWORK); + +static void +mxf_dms1_clip_framework_finalize (GstMiniObject * object) +{ + MXFDMS1ClipFramework *self = MXF_DMS1_CLIP_FRAMEWORK (object); + + g_free (self->clip_kind); + self->clip_kind = NULL; + + g_free (self->slate_information); + self->slate_information = NULL; + + g_free (self->scripting_sets_uids); + self->scripting_sets_uids = NULL; + + g_free (self->scripting_sets); + self->scripting_sets = NULL; + + g_free (self->shot_sets_uids); + self->shot_sets_uids = NULL; + + g_free (self->shot_sets); + self->shot_sets = NULL; + + g_free (self->device_parameters_sets_uids); + self->device_parameters_sets_uids = NULL; + + g_free (self->device_parameters_sets); + self->device_parameters_sets = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_clip_framework_parent_class)->finalize + (object); +} + +static gboolean +mxf_dms1_clip_framework_resolve (MXFMetadataBase * m, + MXFMetadataBase ** metadata) +{ + MXFDMS1ClipFramework *self = MXF_DMS1_CLIP_FRAMEWORK (m); + MXFMetadataBase **p = metadata, *current = NULL; + guint i; + + self->scripting_sets = g_new0 (MXFDMS1Scripting *, self->n_scripting_sets); + self->shot_sets = g_new0 (MXFDMS1Shot *, self->n_shot_sets); + self->device_parameters_sets = + g_new0 (MXFDMS1DeviceParameters *, self->n_device_parameters_sets); + + while (*p) { + current = *p; + + if (MXF_IS_DMS1_SCRIPTING (current)) { + for (i = 0; i < self->n_scripting_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->scripting_sets_uids[i])) { + self->scripting_sets[i] = MXF_DMS1_SCRIPTING (current); + break; + } + } + } + + if (MXF_IS_DMS1_SHOT (current)) { + for (i = 0; i < self->n_shot_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, &self->shot_sets_uids[i])) { + self->shot_sets[i] = MXF_DMS1_SHOT (current); + break; + } + } + } + + if (MXF_IS_DMS1_DEVICE_PARAMETERS (current)) { + for (i = 0; i < self->n_device_parameters_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->device_parameters_sets_uids[i])) { + self->device_parameters_sets[i] = + MXF_DMS1_DEVICE_PARAMETERS (current); + break; + } + } + } + + if (MXF_IS_DMS1_PROCESSING (current)) { + if (mxf_ul_is_equal (¤t->instance_uid, &self->processing_set_uid)) { + self->processing_set = MXF_DMS1_PROCESSING (current); + } + } + + p++; + } + + return + MXF_METADATA_BASE_CLASS (mxf_dms1_clip_framework_parent_class)->resolve + (m, metadata); +} + +static gboolean +mxf_dms1_clip_framework_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1ClipFramework *self = MXF_DMS1_CLIP_FRAMEWORK (metadata); + gboolean ret = TRUE; +#ifndef GST_DISABLE_GST_DEBUG + gchar str[96]; +#endif + MXFUL *tag_ul = NULL; + static const guint8 clip_kind_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03, + 0x02, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 clip_number_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x01, + 0x05, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 extended_clip_id_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x01, + 0x01, 0x15, 0x09, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 clip_creation_date_and_time_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x07, + 0x02, 0x01, 0x10, 0x01, 0x04, 0x00, 0x00 + }; + static const guint8 take_number_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x05, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 slate_information_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x03, + 0x02, 0x05, 0x03, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 scripting_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x0f, 0x00 + }; + static const guint8 shot_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x11, 0x02 + }; + static const guint8 device_parameters_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x1e, 0x00 + }; + static const guint8 processing_set_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x02, 0x40, 0x20, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &clip_kind_ul, 16) == 0) { + self->clip_kind = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" clip kind = %s", GST_STR_NULL (self->clip_kind)); + } else if (memcmp (tag_ul, &clip_number_ul, 16) == 0) { + if (tag_size > 32) + goto error; + + memcpy (self->clip_number, tag_data, tag_size); + GST_DEBUG (" clip number = %s", self->clip_number); + } else if (memcmp (tag_ul, &extended_clip_id_ul, 16) == 0) { + if (tag_size != 32 && tag_size != 64) + goto error; + + memcpy (self->extended_clip_id, tag_data, tag_size); + self->extended_clip_id_full = (tag_size == 64); + + GST_DEBUG (" extended clip id (1) = %s", + mxf_umid_to_string ((MXFUMID *) & self->extended_clip_id, str)); + if (tag_size == 64) + GST_DEBUG (" extended clip id (2) = %s", + mxf_umid_to_string ((MXFUMID *) & self->extended_clip_id[32], str)); + } else if (memcmp (tag_ul, &clip_creation_date_and_time_ul, 16) == 0) { + if (!mxf_timestamp_parse (&self->clip_creation_date_and_time, tag_data, + tag_size)) + goto error; + GST_DEBUG (" clip creation date and time = %d/%u/%u %u:%u:%u.%u", + self->clip_creation_date_and_time.year, + self->clip_creation_date_and_time.month, + self->clip_creation_date_and_time.day, + self->clip_creation_date_and_time.hour, + self->clip_creation_date_and_time.minute, + self->clip_creation_date_and_time.second, + (self->clip_creation_date_and_time.quarter_msecond * 1000) / 256); + } else if (memcmp (tag_ul, &take_number_ul, 16) == 0) { + if (tag_size != 2) + goto error; + + self->take_number = GST_READ_UINT16_BE (tag_data); + GST_DEBUG (" take number = %u", self->take_number); + } else if (memcmp (tag_ul, &slate_information_ul, 16) == 0) { + self->slate_information = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" slate information = %s", + GST_STR_NULL (self->slate_information)); + } else if (memcmp (tag_ul, &scripting_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of scripting sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_scripting_sets = len; + self->scripting_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->scripting_sets_uids[i], tag_data, 16); + GST_DEBUG (" scripting sets %u = %s", i, + mxf_ul_to_string (&self->scripting_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &shot_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of shot sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_shot_sets = len; + self->shot_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->shot_sets_uids[i], tag_data, 16); + GST_DEBUG (" shot sets %u = %s", i, + mxf_ul_to_string (&self->shot_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &device_parameters_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of device parameters sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_device_parameters_sets = len; + self->device_parameters_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->device_parameters_sets_uids[i], tag_data, 16); + GST_DEBUG (" device parameters sets %u = %s", i, + mxf_ul_to_string (&self->device_parameters_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &processing_set_ul, 16) == 0) { + if (tag_size != 16) + goto error; + + memcpy (&self->processing_set_uid, tag_data, 16); + GST_DEBUG (" processing set = %s", + mxf_ul_to_string (&self->processing_set_uid, str)); + } else { + ret = + MXF_METADATA_BASE_CLASS + (mxf_dms1_clip_framework_parent_class)->handle_tag (metadata, primer, + tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 clip framework local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_dms1_clip_framework_init (MXFDMS1ClipFramework * self) +{ +} + +static void +mxf_dms1_clip_framework_class_init (MXFDMS1ClipFrameworkClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_clip_framework_finalize; + metadatabase_class->handle_tag = mxf_dms1_clip_framework_handle_tag; + metadatabase_class->resolve = mxf_dms1_clip_framework_resolve; +} + +G_DEFINE_TYPE (MXFDMS1SceneFramework, mxf_dms1_scene_framework, + MXF_TYPE_DMS1_FRAMEWORK); + +static void +mxf_dms1_scene_framework_finalize (GstMiniObject * object) +{ + MXFDMS1SceneFramework *self = MXF_DMS1_SCENE_FRAMEWORK (object); + + g_free (self->setting_period_sets_uids); + self->setting_period_sets_uids = NULL; + + g_free (self->setting_period_sets); + self->setting_period_sets = NULL; + + g_free (self->shot_scene_sets_uids); + self->shot_scene_sets_uids = NULL; + + g_free (self->shot_scene_sets); + self->shot_scene_sets = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_scene_framework_parent_class)->finalize + (object); +} + +static gboolean +mxf_dms1_scene_framework_resolve (MXFMetadataBase * m, + MXFMetadataBase ** metadata) +{ + MXFDMS1SceneFramework *self = MXF_DMS1_SCENE_FRAMEWORK (m); + MXFMetadataBase **p = metadata, *current = NULL; + guint i; + + self->setting_period_sets = + g_new0 (MXFDMS1SettingPeriod *, self->n_setting_period_sets); + self->shot_scene_sets = g_new0 (MXFDMS1Shot *, self->n_shot_scene_sets); + + while (*p) { + current = *p; + + if (MXF_IS_DMS1_SETTING_PERIOD (current)) { + for (i = 0; i < self->n_setting_period_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->setting_period_sets_uids[i])) { + self->setting_period_sets[i] = MXF_DMS1_SETTING_PERIOD (current); + break; + } + } + } + + if (MXF_IS_DMS1_SHOT (current)) { + for (i = 0; i < self->n_shot_scene_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->shot_scene_sets_uids[i])) { + self->shot_scene_sets[i] = MXF_DMS1_SHOT (current); + break; + } + } + } + + p++; + } + + return + MXF_METADATA_BASE_CLASS (mxf_dms1_scene_framework_parent_class)->resolve + (m, metadata); +} + +static gboolean +mxf_dms1_scene_framework_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1SceneFramework *self = MXF_DMS1_SCENE_FRAMEWORK (metadata); + gboolean ret = TRUE; +#ifndef GST_DISABLE_GST_DEBUG + gchar str[48]; +#endif + MXFUL *tag_ul = NULL; + static const guint8 scene_number_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 setting_period_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x0e, 0x02 + }; + static const guint8 shot_scene_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x11, 0x01 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &scene_number_ul, 16) == 0) { + if (tag_size > 32) + goto error; + + memcpy (self->scene_number, tag_data, tag_size); + GST_DEBUG (" scene number = %s", self->scene_number); + } else if (memcmp (tag_ul, &setting_period_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of setting period sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_setting_period_sets = len; + self->setting_period_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->setting_period_sets_uids[i], tag_data, 16); + GST_DEBUG (" setting period sets %u = %s", i, + mxf_ul_to_string (&self->setting_period_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &shot_scene_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of shot sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_shot_scene_sets = len; + self->shot_scene_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->shot_scene_sets_uids[i], tag_data, 16); + GST_DEBUG (" shot sets %u = %s", i, + mxf_ul_to_string (&self->shot_scene_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else { + ret = + MXF_METADATA_BASE_CLASS + (mxf_dms1_scene_framework_parent_class)->handle_tag (metadata, primer, + tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 scene framework local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_dms1_scene_framework_init (MXFDMS1SceneFramework * self) +{ +} + +static void +mxf_dms1_scene_framework_class_init (MXFDMS1SceneFrameworkClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_scene_framework_finalize; + metadatabase_class->handle_tag = mxf_dms1_scene_framework_handle_tag; + metadatabase_class->resolve = mxf_dms1_scene_framework_resolve; +} + +G_DEFINE_TYPE (MXFDMS1Titles, mxf_dms1_titles, MXF_TYPE_DMS1_TEXT_LANGUAGE); + +static void +mxf_dms1_titles_finalize (GstMiniObject * object) +{ + MXFDMS1Titles *self = MXF_DMS1_TITLES (object); + + g_free (self->main_title); + self->main_title = NULL; + + g_free (self->secondary_title); + self->secondary_title = NULL; + + g_free (self->working_title); + self->working_title = NULL; + + g_free (self->original_title); + self->original_title = NULL; + + g_free (self->version_title); + self->version_title = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_titles_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_titles_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer, + guint16 tag, const guint8 * tag_data, guint tag_size) +{ + MXFDMS1Titles *self = MXF_DMS1_TITLES (metadata); + gboolean ret = TRUE; + MXFUL *tag_ul = NULL; + static const guint8 main_title_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x01, + 0x05, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 secondary_title_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x01, + 0x05, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 working_title_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x01, + 0x05, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 original_title_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x01, + 0x05, 0x0b, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 version_title_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x01, + 0x05, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &main_title_ul, 16) == 0) { + self->main_title = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" main title = %s", GST_STR_NULL (self->main_title)); + } else if (memcmp (tag_ul, &secondary_title_ul, 16) == 0) { + self->secondary_title = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" secondary title = %s", GST_STR_NULL (self->secondary_title)); + } else if (memcmp (tag_ul, &working_title_ul, 16) == 0) { + self->working_title = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" working title = %s", GST_STR_NULL (self->working_title)); + } else if (memcmp (tag_ul, &original_title_ul, 16) == 0) { + self->original_title = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" original title = %s", GST_STR_NULL (self->original_title)); + } else if (memcmp (tag_ul, &version_title_ul, 16) == 0) { + self->version_title = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" version title = %s", GST_STR_NULL (self->version_title)); + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_titles_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; +} + +static void +mxf_dms1_titles_init (MXFDMS1Titles * self) +{ +} + +static void +mxf_dms1_titles_class_init (MXFDMS1TitlesClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_titles_finalize; + metadatabase_class->handle_tag = mxf_dms1_titles_handle_tag; +} + +G_DEFINE_TYPE (MXFDMS1Identification, mxf_dms1_identification, + MXF_TYPE_DMS1_THESAURUS); + +static void +mxf_dms1_identification_finalize (GstMiniObject * object) +{ + MXFDMS1Identification *self = MXF_DMS1_IDENTIFICATION (object); + + g_free (self->identifier_value); + self->identifier_value = NULL; + + g_free (self->identification_issuing_authority); + self->identification_issuing_authority = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_identification_parent_class)->finalize + (object); +} + +static gboolean +mxf_dms1_identification_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1Identification *self = MXF_DMS1_IDENTIFICATION (metadata); +#ifndef GST_DISABLE_GST_DEBUG + gchar str[48]; +#endif + gboolean ret = TRUE; + MXFUL *tag_ul = NULL; + static const guint8 identifier_kind_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x01, + 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 identifier_value_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x01, + 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 identification_locator_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x01, + 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 identification_issuing_authority_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x02, + 0x0a, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &identifier_kind_ul, 16) == 0) { + if (tag_size > 32) + goto error; + + memcpy (self->identifier_kind, tag_data, tag_size); + GST_DEBUG (" identifier kind = %s", self->identifier_kind); + } else if (memcmp (tag_ul, &identifier_value_ul, 16) == 0) { + self->identifier_value = g_memdup (tag_data, tag_size); + self->identifier_value_length = tag_size; + GST_DEBUG (" identifier value length = %u", tag_size); + } else if (memcmp (tag_ul, &identification_locator_ul, 16) == 0) { + if (tag_size != 16) + goto error; + + memcpy (&self->identification_locator, tag_data, 16); + + GST_DEBUG (" identification locator = %s", + mxf_ul_to_string (&self->identification_locator, str)); + } else if (memcmp (tag_ul, &identification_issuing_authority_ul, 16) == 0) { + self->identification_issuing_authority = + mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" identification issuing authority = %s", + GST_STR_NULL (self->identification_issuing_authority)); + } else { + ret = + MXF_METADATA_BASE_CLASS + (mxf_dms1_identification_parent_class)->handle_tag (metadata, primer, + tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 identification local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_dms1_identification_init (MXFDMS1Identification * self) +{ +} + +static void +mxf_dms1_identification_class_init (MXFDMS1IdentificationClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_identification_finalize; + metadatabase_class->handle_tag = mxf_dms1_identification_handle_tag; +} + +G_DEFINE_TYPE (MXFDMS1GroupRelationship, mxf_dms1_group_relationship, + MXF_TYPE_DMS1_THESAURUS); + +static void +mxf_dms1_group_relationship_finalize (GstMiniObject * object) +{ + MXFDMS1GroupRelationship *self = MXF_DMS1_GROUP_RELATIONSHIP (object); + + g_free (self->programming_group_kind); + self->programming_group_kind = NULL; + + g_free (self->programming_group_title); + self->programming_group_title = NULL; + + g_free (self->group_synopsis); + self->group_synopsis = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_group_relationship_parent_class)->finalize + (object); +} + +static gboolean +mxf_dms1_group_relationship_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1GroupRelationship *self = MXF_DMS1_GROUP_RELATIONSHIP (metadata); + gboolean ret = TRUE; + MXFUL *tag_ul = NULL; + static const guint8 programming_group_kind_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x02, + 0x02, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 programming_group_title_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x02, + 0x02, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 group_synopsis_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03, + 0x02, 0x01, 0x06, 0x08, 0x01, 0x00, 0x00 + }; + static const guint8 numerical_position_in_sequence_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x06, + 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 total_number_in_the_sequence_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 episodic_start_number_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x02, + 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 episodic_end_number_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x02, + 0x02, 0x05, 0x02, 0x03, 0x01, 0x00, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &programming_group_kind_ul, 16) == 0) { + self->programming_group_kind = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" programming group kind = %s", + GST_STR_NULL (self->programming_group_kind)); + } else if (memcmp (tag_ul, &programming_group_title_ul, 16) == 0) { + self->programming_group_title = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" programming group title = %s", + GST_STR_NULL (self->programming_group_title)); + } else if (memcmp (tag_ul, &group_synopsis_ul, 16) == 0) { + self->group_synopsis = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" group synopsis = %s", GST_STR_NULL (self->group_synopsis)); + } else if (memcmp (tag_ul, &numerical_position_in_sequence_ul, 16) == 0) { + if (tag_size != 4) + goto error; + + self->numerical_position_in_sequence = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" numerical position in sequence = %u", + self->numerical_position_in_sequence); + } else if (memcmp (tag_ul, &total_number_in_the_sequence_ul, 16) == 0) { + if (tag_size != 4) + goto error; + + self->total_number_in_the_sequence = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" total number in the sequence = %u", + self->total_number_in_the_sequence); + } else if (memcmp (tag_ul, &episodic_start_number_ul, 16) == 0) { + if (tag_size != 2) + goto error; + + self->episodic_start_number = GST_READ_UINT16_BE (tag_data); + GST_DEBUG (" episodic start number = %u", self->episodic_start_number); + } else if (memcmp (tag_ul, &episodic_end_number_ul, 16) == 0) { + if (tag_size != 2) + goto error; + + self->episodic_end_number = GST_READ_UINT16_BE (tag_data); + GST_DEBUG (" episodic end number = %u", self->episodic_end_number); + } else { + ret = + MXF_METADATA_BASE_CLASS + (mxf_dms1_group_relationship_parent_class)->handle_tag (metadata, + primer, tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 group relationship local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_dms1_group_relationship_init (MXFDMS1GroupRelationship * self) +{ +} + +static void +mxf_dms1_group_relationship_class_init (MXFDMS1GroupRelationshipClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_group_relationship_finalize; + metadatabase_class->handle_tag = mxf_dms1_group_relationship_handle_tag; +} + +G_DEFINE_TYPE (MXFDMS1Branding, mxf_dms1_branding, MXF_TYPE_DMS1_TEXT_LANGUAGE); + +static void +mxf_dms1_branding_finalize (GstMiniObject * object) +{ + MXFDMS1Branding *self = MXF_DMS1_BRANDING (object); + + g_free (self->brand_main_title); + self->brand_main_title = NULL; + + g_free (self->brand_original_title); + self->brand_original_title = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_branding_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_branding_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1Branding *self = MXF_DMS1_BRANDING (metadata); + gboolean ret = TRUE; + MXFUL *tag_ul = NULL; + static const guint8 brand_main_title_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x01, + 0x05, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 brand_original_title_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x01, + 0x05, 0x0E, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &brand_main_title_ul, 16) == 0) { + self->brand_main_title = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" brand main title = %s", + GST_STR_NULL (self->brand_main_title)); + } else if (memcmp (tag_ul, &brand_original_title_ul, 16) == 0) { + self->brand_original_title = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" brand original title = %s", + GST_STR_NULL (self->brand_original_title)); + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_branding_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; +} + +static void +mxf_dms1_branding_init (MXFDMS1Branding * self) +{ +} + +static void +mxf_dms1_branding_class_init (MXFDMS1BrandingClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_branding_finalize; + metadatabase_class->handle_tag = mxf_dms1_branding_handle_tag; +} + +G_DEFINE_TYPE (MXFDMS1Event, mxf_dms1_event, MXF_TYPE_DMS1_THESAURUS); + +static void +mxf_dms1_event_finalize (GstMiniObject * object) +{ + MXFDMS1Event *self = MXF_DMS1_EVENT (object); + + g_free (self->event_indication); + self->event_indication = NULL; + + g_free (self->publication_sets_uids); + self->publication_sets_uids = NULL; + + g_free (self->publication_sets); + self->publication_sets = NULL; + + g_free (self->annotation_sets_uids); + self->annotation_sets_uids = NULL; + + g_free (self->annotation_sets); + self->annotation_sets = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_event_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_event_resolve (MXFMetadataBase * m, MXFMetadataBase ** metadata) +{ + MXFDMS1Event *self = MXF_DMS1_EVENT (m); + MXFMetadataBase **p = metadata, *current = NULL; + guint i; + + self->publication_sets = + g_new0 (MXFDMS1Publication *, self->n_publication_sets); + self->annotation_sets = g_new0 (MXFDMS1Annotation *, self->n_annotation_sets); + + while (*p) { + current = *p; + + if (MXF_IS_DMS1_PUBLICATION (current)) { + for (i = 0; i < self->n_publication_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->publication_sets_uids[i])) { + self->publication_sets[i] = MXF_DMS1_PUBLICATION (current); + break; + } + } + } + + if (MXF_IS_DMS1_ANNOTATION (current)) { + for (i = 0; i < self->n_annotation_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->annotation_sets_uids[i])) { + self->annotation_sets[i] = MXF_DMS1_ANNOTATION (current); + break; + } + } + } + + p++; + } + + return MXF_METADATA_BASE_CLASS (mxf_dms1_event_parent_class)->resolve (m, + metadata); +} + +static gboolean +mxf_dms1_event_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer, + guint16 tag, const guint8 * tag_data, guint tag_size) +{ + MXFDMS1Event *self = MXF_DMS1_EVENT (metadata); + gboolean ret = TRUE; +#ifndef GST_DISABLE_GST_DEBUG + gchar str[48]; +#endif + MXFUL *tag_ul = NULL; + static const guint8 event_indication_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x05, + 0x01, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00 + }; + static const guint8 event_start_date_and_time_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x07, + 0x02, 0x01, 0x02, 0x07, 0x02, 0x00, 0x00 + }; + static const guint8 event_end_date_and_time_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x07, + 0x02, 0x01, 0x02, 0x09, 0x02, 0x00, 0x00 + }; + static const guint8 publication_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x0a, 0x00 + }; + static const guint8 annotation_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x0d, 0x01 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &event_indication_ul, 16) == 0) { + self->event_indication = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" event indication = %s", + GST_STR_NULL (self->event_indication)); + } else if (memcmp (tag_ul, &event_start_date_and_time_ul, 16) == 0) { + if (tag_size > 32) + goto error; + + memcpy (self->event_start_date_and_time, tag_data, tag_size); + GST_DEBUG (" event start date and time = %s", + self->event_start_date_and_time); + } else if (memcmp (tag_ul, &event_end_date_and_time_ul, 16) == 0) { + if (tag_size > 32) + goto error; + + memcpy (self->event_end_date_and_time, tag_data, tag_size); + GST_DEBUG (" event end date and time = %s", self->event_end_date_and_time); + } else if (memcmp (tag_ul, &publication_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of publication sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_publication_sets = len; + self->publication_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->publication_sets_uids[i], tag_data, 16); + GST_DEBUG (" publication sets %u = %s", i, + mxf_ul_to_string (&self->publication_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &annotation_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of annotation sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_annotation_sets = len; + self->annotation_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->annotation_sets_uids[i], tag_data, 16); + GST_DEBUG (" annotation sets %u = %s", i, + mxf_ul_to_string (&self->annotation_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_event_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 event local tag 0x%04x of size %u", tag, tag_size); + + return FALSE; +} + +static void +mxf_dms1_event_init (MXFDMS1Event * self) +{ +} + +static void +mxf_dms1_event_class_init (MXFDMS1EventClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_event_finalize; + metadatabase_class->handle_tag = mxf_dms1_event_handle_tag; + metadatabase_class->resolve = mxf_dms1_event_resolve; +} + +G_DEFINE_TYPE (MXFDMS1Publication, mxf_dms1_publication, MXF_TYPE_DMS1); + +static void +mxf_dms1_publication_finalize (GstMiniObject * object) +{ + MXFDMS1Publication *self = MXF_DMS1_PUBLICATION (object); + + g_free (self->publication_organisation_name); + self->publication_organisation_name = NULL; + + g_free (self->publication_service_name); + self->publication_service_name = NULL; + + g_free (self->publication_medium); + self->publication_medium = NULL; + + g_free (self->publication_region); + self->publication_region = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_publication_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_publication_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1Publication *self = MXF_DMS1_PUBLICATION (metadata); + gboolean ret = TRUE; + MXFUL *tag_ul = NULL; + static const guint8 publication_organisation_name_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x02, + 0x10, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00 + }; + static const guint8 publication_service_name_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x02, + 0x10, 0x02, 0x01, 0x02, 0x01, 0x00, 0x00 + }; + static const guint8 publication_medium_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x02, + 0x10, 0x02, 0x01, 0x03, 0x01, 0x00, 0x00 + }; + static const guint8 publication_region_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x02, + 0x10, 0x02, 0x01, 0x04, 0x01, 0x00, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &publication_organisation_name_ul, 16) == 0) { + self->publication_organisation_name = + mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" publication organisation name = %s", + GST_STR_NULL (self->publication_organisation_name)); + } else if (memcmp (tag_ul, &publication_service_name_ul, 16) == 0) { + self->publication_service_name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" publication service name = %s", + GST_STR_NULL (self->publication_service_name)); + } else if (memcmp (tag_ul, &publication_medium_ul, 16) == 0) { + self->publication_medium = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" publication medium = %s", + GST_STR_NULL (self->publication_medium)); + } else if (memcmp (tag_ul, &publication_region_ul, 16) == 0) { + self->publication_region = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" publication region = %s", + GST_STR_NULL (self->publication_region)); + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_publication_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; +} + +static void +mxf_dms1_publication_init (MXFDMS1Publication * self) +{ +} + +static void +mxf_dms1_publication_class_init (MXFDMS1PublicationClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_publication_finalize; + metadatabase_class->handle_tag = mxf_dms1_publication_handle_tag; +} + +G_DEFINE_TYPE (MXFDMS1Award, mxf_dms1_award, MXF_TYPE_DMS1_THESAURUS); + +static void +mxf_dms1_award_finalize (GstMiniObject * object) +{ + MXFDMS1Award *self = MXF_DMS1_AWARD (object); + + g_free (self->festival); + self->festival = NULL; + + g_free (self->award_name); + self->award_name = NULL; + + g_free (self->award_classification); + self->award_classification = NULL; + + g_free (self->nomination_category); + self->nomination_category = NULL; + + g_free (self->participant_sets_uids); + self->participant_sets_uids = NULL; + + g_free (self->participant_sets); + self->participant_sets = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_award_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_award_resolve (MXFMetadataBase * m, MXFMetadataBase ** metadata) +{ + MXFDMS1Award *self = MXF_DMS1_AWARD (m); + MXFMetadataBase **p = metadata, *current = NULL; + guint i; + + self->participant_sets = + g_new0 (MXFDMS1Participant *, self->n_participant_sets); + while (*p) { + current = *p; + + if (MXF_IS_DMS1_PARTICIPANT (current)) { + for (i = 0; i < self->n_participant_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->participant_sets_uids[i])) { + self->participant_sets[i] = MXF_DMS1_PARTICIPANT (current); + break; + } + } + } + + p++; + } + + return MXF_METADATA_BASE_CLASS (mxf_dms1_award_parent_class)->resolve (m, + metadata); +} + +static gboolean +mxf_dms1_award_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer, + guint16 tag, const guint8 * tag_data, guint tag_size) +{ + MXFDMS1Award *self = MXF_DMS1_AWARD (metadata); + gboolean ret = TRUE; +#ifndef GST_DISABLE_GST_DEBUG + gchar str[48]; +#endif + MXFUL *tag_ul = NULL; + static const guint8 festival_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x03, + 0x02, 0x02, 0x01, 0x03, 0x01, 0x00, 0x00 + }; + static const guint8 festival_date_and_time_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x07, + 0x02, 0x01, 0x02, 0x07, 0x10, 0x01, 0x00 + }; + static const guint8 award_name_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x03, + 0x02, 0x02, 0x01, 0x04, 0x01, 0x00, 0x00 + }; + static const guint8 award_classification_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x03, + 0x02, 0x02, 0x01, 0x05, 0x01, 0x00, 0x00 + }; + static const guint8 nomination_category_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x03, + 0x02, 0x02, 0x01, 0x06, 0x01, 0x00, 0x00 + }; + static const guint8 participant_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x03, 0x40, 0x13, 0x01 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &festival_ul, 16) == 0) { + self->festival = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" festival = %s", GST_STR_NULL (self->festival)); + } else if (memcmp (tag_ul, &festival_date_and_time_ul, 16) == 0) { + if (tag_size > 32) + goto error; + + memcpy (self->festival_date_and_time, tag_data, tag_size); + GST_DEBUG (" festival date and time = %s", + GST_STR_NULL (self->festival_date_and_time)); + } else if (memcmp (tag_ul, &award_name_ul, 16) == 0) { + self->award_name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" award name = %s", GST_STR_NULL (self->award_name)); + } else if (memcmp (tag_ul, &award_classification_ul, 16) == 0) { + self->award_classification = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" award classification = %s", + GST_STR_NULL (self->award_classification)); + } else if (memcmp (tag_ul, &nomination_category_ul, 16) == 0) { + self->nomination_category = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" nomination category = %s", + GST_STR_NULL (self->nomination_category)); + } else if (memcmp (tag_ul, &participant_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of participant sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_participant_sets = len; + self->participant_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->participant_sets_uids[i], tag_data, 16); + GST_DEBUG (" participant sets %u = %s", i, + mxf_ul_to_string (&self->participant_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_award_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 award local tag 0x%04x of size %u", tag, tag_size); + + return FALSE; +} + +static void +mxf_dms1_award_init (MXFDMS1Award * self) +{ +} + +static void +mxf_dms1_award_class_init (MXFDMS1AwardClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_award_finalize; + metadatabase_class->handle_tag = mxf_dms1_award_handle_tag; + metadatabase_class->resolve = mxf_dms1_award_resolve; +} + +G_DEFINE_TYPE (MXFDMS1CaptionsDescription, mxf_dms1_captions_description, + MXF_TYPE_DMS1_THESAURUS); + +static void +mxf_dms1_captions_description_finalize (GstMiniObject * object) +{ + MXFDMS1CaptionsDescription *self = MXF_DMS1_CAPTIONS_DESCRIPTION (object); + + g_free (self->caption_kind); + self->caption_kind = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_captions_description_parent_class)->finalize + (object); +} + +static gboolean +mxf_dms1_captions_description_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1CaptionsDescription *self = MXF_DMS1_CAPTIONS_DESCRIPTION (metadata); + gboolean ret = TRUE; + MXFUL *tag_ul = NULL; + static const guint8 extended_captions_language_code_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x03, + 0x01, 0x01, 0x02, 0x02, 0x12, 0x00, 0x00 + }; + static const guint8 caption_kind_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x04, + 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &extended_captions_language_code_ul, 16) == 0) { + if (tag_size > 12) + goto error; + + memcpy (self->extended_captions_language_code, tag_data, tag_size); + GST_DEBUG (" extended captions language code = %s", + self->extended_captions_language_code); + } else if (memcmp (tag_ul, &caption_kind_ul, 16) == 0) { + self->caption_kind = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" caption kind = %s", GST_STR_NULL (self->caption_kind)); + } else { + ret = + MXF_METADATA_BASE_CLASS + (mxf_dms1_captions_description_parent_class)->handle_tag (metadata, + primer, tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 captions description local tag 0x%04x of size %u", + tag, tag_size); + + return FALSE; +} + +static void +mxf_dms1_captions_description_init (MXFDMS1CaptionsDescription * self) +{ +} + +static void +mxf_dms1_captions_description_class_init (MXFDMS1CaptionsDescriptionClass * + klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_captions_description_finalize; + metadatabase_class->handle_tag = mxf_dms1_captions_description_handle_tag; +} + +G_DEFINE_TYPE (MXFDMS1Annotation, mxf_dms1_annotation, MXF_TYPE_DMS1_THESAURUS); + +static void +mxf_dms1_annotation_finalize (GstMiniObject * object) +{ + MXFDMS1Annotation *self = MXF_DMS1_ANNOTATION (object); + + g_free (self->annotation_kind); + self->annotation_kind = NULL; + + g_free (self->annotation_synopsis); + self->annotation_synopsis = NULL; + + g_free (self->annotation_description); + self->annotation_description = NULL; + + g_free (self->related_material_description); + self->related_material_description = NULL; + + g_free (self->classification_sets_uids); + self->classification_sets_uids = NULL; + + g_free (self->classification_sets); + self->classification_sets = NULL; + + g_free (self->related_material_locators); + self->related_material_locators = NULL; + + g_free (self->participant_sets_uids); + self->participant_sets_uids = NULL; + + g_free (self->participant_sets); + self->participant_sets = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_annotation_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_annotation_resolve (MXFMetadataBase * m, MXFMetadataBase ** metadata) +{ + MXFDMS1Annotation *self = MXF_DMS1_ANNOTATION (m); + MXFMetadataBase **p = metadata, *current = NULL; + guint i; + + self->classification_sets = + g_new0 (MXFDMS1Classification *, self->n_classification_sets); + self->participant_sets = + g_new0 (MXFDMS1Participant *, self->n_participant_sets); + + while (*p) { + current = *p; + + if (MXF_IS_DMS1_CLASSIFICATION (current)) { + for (i = 0; i < self->n_classification_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->classification_sets_uids[i])) { + self->classification_sets[i] = MXF_DMS1_CLASSIFICATION (current); + break; + } + } + } + + if (MXF_IS_DMS1_CUE_WORDS (current)) { + if (mxf_ul_is_equal (¤t->instance_uid, &self->cue_words_set_uid)) { + self->cue_words_set = MXF_DMS1_CUE_WORDS (current); + } + } + + if (MXF_IS_DMS1_PARTICIPANT (current)) { + for (i = 0; i < self->n_participant_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->participant_sets_uids[i])) { + self->participant_sets[i] = MXF_DMS1_PARTICIPANT (current); + break; + } + } + } + + p++; + } + + return MXF_METADATA_BASE_CLASS (mxf_dms1_annotation_parent_class)->resolve (m, + metadata); +} + +static gboolean +mxf_dms1_annotation_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1Annotation *self = MXF_DMS1_ANNOTATION (metadata); + gboolean ret = TRUE; +#ifndef GST_DISABLE_GST_DEBUG + gchar str[48]; +#endif + MXFUL *tag_ul = NULL; + static const guint8 annotation_kind_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03, + 0x02, 0x01, 0x06, 0x0e, 0x01, 0x00, 0x00 + }; + static const guint8 annotation_synopsis_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03, + 0x02, 0x01, 0x06, 0x09, 0x01, 0x00, 0x00 + }; + static const guint8 annotation_description_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03, + 0x02, 0x01, 0x06, 0x0a, 0x01, 0x00, 0x00 + }; + static const guint8 related_material_description_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03, + 0x02, 0x01, 0x06, 0x0f, 0x01, 0x00, 0x00 + }; + static const guint8 classification_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x10, 0x00 + }; + static const guint8 cue_words_set_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x02, 0x40, 0x23, 0x01 + }; + static const guint8 related_material_locators_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x06, 0x0d, 0x00, 0x00 + }; + static const guint8 participant_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x06, + 0x01, 0x01, 0x04, 0x03, 0x40, 0x13, 0x03 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &annotation_kind_ul, 16) == 0) { + self->annotation_kind = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" annotation kind = %s", GST_STR_NULL (self->annotation_kind)); + } else if (memcmp (tag_ul, &annotation_synopsis_ul, 16) == 0) { + self->annotation_synopsis = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" annotation synopsis = %s", + GST_STR_NULL (self->annotation_synopsis)); + } else if (memcmp (tag_ul, &annotation_description_ul, 16) == 0) { + self->annotation_description = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" annotation description = %s", + GST_STR_NULL (self->annotation_description)); + } else if (memcmp (tag_ul, &related_material_description_ul, 16) == 0) { + self->related_material_description = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" related material description = %s", + GST_STR_NULL (self->related_material_description)); + } else if (memcmp (tag_ul, &classification_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of classification sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_classification_sets = len; + self->classification_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->classification_sets_uids[i], tag_data, 16); + GST_DEBUG (" classification sets %u = %s", i, + mxf_ul_to_string (&self->classification_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &cue_words_set_ul, 16) == 0) { + if (tag_size != 16) + goto error; + + memcpy (&self->cue_words_set_uid, tag_data, 16); + GST_DEBUG (" cue words set = %s", + mxf_ul_to_string (&self->cue_words_set_uid, str)); + } else if (memcmp (tag_ul, &related_material_locators_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of related material locators = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_related_material_locators = len; + self->related_material_locators = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->related_material_locators[i], tag_data, 16); + GST_DEBUG (" related material locators %u = %s", i, + mxf_ul_to_string (&self->related_material_locators[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &participant_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of participant sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_participant_sets = len; + self->participant_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->participant_sets_uids[i], tag_data, 16); + GST_DEBUG (" participant sets %u = %s", i, + mxf_ul_to_string (&self->participant_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_annotation_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 annotation local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_dms1_annotation_init (MXFDMS1Annotation * self) +{ +} + +static void +mxf_dms1_annotation_class_init (MXFDMS1AnnotationClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_annotation_finalize; + metadatabase_class->handle_tag = mxf_dms1_annotation_handle_tag; + metadatabase_class->resolve = mxf_dms1_annotation_resolve; +} + +G_DEFINE_TYPE (MXFDMS1SettingPeriod, mxf_dms1_setting_period, + MXF_TYPE_DMS1_THESAURUS); + +static void +mxf_dms1_setting_period_finalize (GstMiniObject * object) +{ + MXFDMS1SettingPeriod *self = MXF_DMS1_SETTING_PERIOD (object); + + g_free (self->time_period_keyword); + self->time_period_keyword = NULL; + + g_free (self->setting_period_description); + self->setting_period_description = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_setting_period_parent_class)->finalize + (object); +} + +static gboolean +mxf_dms1_setting_period_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1SettingPeriod *self = MXF_DMS1_SETTING_PERIOD (metadata); + gboolean ret = TRUE; + MXFUL *tag_ul = NULL; + static const guint8 setting_date_and_time_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x07, + 0x02, 0x01, 0x08, 0x02, 0x00, 0x00, 0x00 + }; + static const guint8 time_period_keyword_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x07, + 0x02, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00 + }; + static const guint8 setting_period_description_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x07, + 0x02, 0x01, 0x08, 0x03, 0x01, 0x00, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &setting_date_and_time_ul, 16) == 0) { + if (!mxf_timestamp_parse (&self->setting_date_and_time, tag_data, tag_size)) + goto error; + + GST_DEBUG (" last modified date = %d/%u/%u %u:%u:%u.%u", + self->setting_date_and_time.year, self->setting_date_and_time.month, + self->setting_date_and_time.day, self->setting_date_and_time.hour, + self->setting_date_and_time.minute, + self->setting_date_and_time.second, + (self->setting_date_and_time.quarter_msecond * 1000) / 256); + } else if (memcmp (tag_ul, &time_period_keyword_ul, 16) == 0) { + self->time_period_keyword = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" time period keyword = %s", + GST_STR_NULL (self->time_period_keyword)); + } else if (memcmp (tag_ul, &setting_period_description_ul, 16) == 0) { + self->setting_period_description = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" setting period description = %s", + GST_STR_NULL (self->setting_period_description)); + } else { + ret = + MXF_METADATA_BASE_CLASS + (mxf_dms1_setting_period_parent_class)->handle_tag (metadata, primer, + tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 setting period local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_dms1_setting_period_init (MXFDMS1SettingPeriod * self) +{ +} + +static void +mxf_dms1_setting_period_class_init (MXFDMS1SettingPeriodClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_setting_period_finalize; + metadatabase_class->handle_tag = mxf_dms1_setting_period_handle_tag; +} + +G_DEFINE_TYPE (MXFDMS1Scripting, mxf_dms1_scripting, MXF_TYPE_DMS1_THESAURUS); + +static void +mxf_dms1_scripting_finalize (GstMiniObject * object) +{ + MXFDMS1Scripting *self = MXF_DMS1_SCRIPTING (object); + + g_free (self->scripting_kind); + self->scripting_kind = NULL; + + g_free (self->scripting_text); + self->scripting_text = NULL; + + g_free (self->scripting_locators); + self->scripting_locators = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_scripting_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_scripting_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1Scripting *self = MXF_DMS1_SCRIPTING (metadata); + gboolean ret = TRUE; +#ifndef GST_DISABLE_GST_DEBUG + gchar str[48]; +#endif + MXFUL *tag_ul = NULL; + static const guint8 scripting_kind_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03, + 0x02, 0x01, 0x06, 0x0b, 0x01, 0x00, 0x00 + }; + static const guint8 scripting_text_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03, + 0x02, 0x01, 0x06, 0x0c, 0x01, 0x00, 0x00 + }; + static const guint8 scripting_locators_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08, 0x06, + 0x01, 0x01, 0x04, 0x06, 0x0e, 0x00, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &scripting_kind_ul, 16) == 0) { + self->scripting_kind = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" scripting kind = %s", GST_STR_NULL (self->scripting_kind)); + } else if (memcmp (tag_ul, &scripting_text_ul, 16) == 0) { + self->scripting_text = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" scripting description = %s", + GST_STR_NULL (self->scripting_text)); + } else if (memcmp (tag_ul, &scripting_locators_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of scripting locators = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_scripting_locators = len; + self->scripting_locators = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->scripting_locators[i], tag_data, 16); + GST_DEBUG (" scripting locators %u = %s", i, + mxf_ul_to_string (&self->scripting_locators[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_scripting_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 scripting local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_dms1_scripting_init (MXFDMS1Scripting * self) +{ +} + +static void +mxf_dms1_scripting_class_init (MXFDMS1ScriptingClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_scripting_finalize; + metadatabase_class->handle_tag = mxf_dms1_scripting_handle_tag; +} + +G_DEFINE_TYPE (MXFDMS1Classification, mxf_dms1_classification, + MXF_TYPE_DMS1_THESAURUS); + +static void +mxf_dms1_classification_finalize (GstMiniObject * object) +{ + MXFDMS1Classification *self = MXF_DMS1_CLASSIFICATION (object); + + g_free (self->name_value_sets_uids); + self->name_value_sets_uids = NULL; + + g_free (self->name_value_sets); + self->name_value_sets = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_classification_parent_class)->finalize + (object); +} + +static gboolean +mxf_dms1_classification_resolve (MXFMetadataBase * m, + MXFMetadataBase ** metadata) +{ + MXFDMS1Classification *self = MXF_DMS1_CLASSIFICATION (m); + MXFMetadataBase **p = metadata, *current = NULL; + guint i; + + self->name_value_sets = g_new0 (MXFDMS1NameValue *, self->n_name_value_sets); + + while (*p) { + current = *p; + + if (MXF_IS_DMS1_NAME_VALUE (current)) { + for (i = 0; i < self->n_name_value_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->name_value_sets_uids[i])) { + self->name_value_sets[i] = MXF_DMS1_NAME_VALUE (current); + break; + } + } + } + + p++; + } + + return + MXF_METADATA_BASE_CLASS (mxf_dms1_classification_parent_class)->resolve + (m, metadata); +} + +static gboolean +mxf_dms1_classification_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1Classification *self = MXF_DMS1_CLASSIFICATION (metadata); + gboolean ret = TRUE; +#ifndef GST_DISABLE_GST_DEBUG + gchar str[48]; +#endif + MXFUL *tag_ul = NULL; + static const guint8 content_classification_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x03, + 0x02, 0x01, 0x03, 0x04, 0x00, 0x00, 0x00 + }; + static const guint8 name_value_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x1f, 0x01 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &content_classification_ul, 16) == 0) { + if (tag_size > 127) + goto error; + + memcpy (self->content_classification, tag_data, tag_size); + GST_DEBUG (" content classification = %s", self->content_classification); + } else if (memcmp (tag_ul, &name_value_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of name-value sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_name_value_sets = len; + self->name_value_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->name_value_sets_uids[i], tag_data, 16); + GST_DEBUG (" name-value sets %u = %s", i, + mxf_ul_to_string (&self->name_value_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else { + ret = + MXF_METADATA_BASE_CLASS + (mxf_dms1_classification_parent_class)->handle_tag (metadata, primer, + tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 classification local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_dms1_classification_init (MXFDMS1Classification * self) +{ +} + +static void +mxf_dms1_classification_class_init (MXFDMS1ClassificationClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_classification_finalize; + metadatabase_class->handle_tag = mxf_dms1_classification_handle_tag; + metadatabase_class->resolve = mxf_dms1_classification_resolve; +} + +G_DEFINE_TYPE (MXFDMS1Shot, mxf_dms1_shot, MXF_TYPE_DMS1_TEXT_LANGUAGE); + +static void +mxf_dms1_shot_finalize (GstMiniObject * object) +{ + MXFDMS1Shot *self = MXF_DMS1_SHOT (object); + + g_free (self->shot_track_ids); + self->shot_track_ids = NULL; + + g_free (self->shot_description); + self->shot_description = NULL; + + g_free (self->shot_comment_kind); + self->shot_comment_kind = NULL; + + g_free (self->shot_comment); + self->shot_comment = NULL; + + g_free (self->key_point_sets_uids); + self->key_point_sets_uids = NULL; + + g_free (self->key_point_sets); + self->key_point_sets = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_shot_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_shot_resolve (MXFMetadataBase * m, MXFMetadataBase ** metadata) +{ + MXFDMS1Shot *self = MXF_DMS1_SHOT (m); + MXFMetadataBase **p = metadata, *current = NULL; + guint i; + + self->key_point_sets = g_new0 (MXFDMS1KeyPoint *, self->n_key_point_sets); + + while (*p) { + current = *p; + + if (MXF_IS_DMS1_CUE_WORDS (current)) { + if (mxf_ul_is_equal (¤t->instance_uid, &self->cue_words_set_uid)) { + self->cue_words_set = MXF_DMS1_CUE_WORDS (current); + } + } + + if (MXF_IS_DMS1_KEY_POINT (current)) { + for (i = 0; i < self->n_key_point_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->key_point_sets_uids[i])) { + self->key_point_sets[i] = MXF_DMS1_KEY_POINT (current); + break; + } + } + } + + p++; + } + + return MXF_METADATA_BASE_CLASS (mxf_dms1_shot_parent_class)->resolve (m, + metadata); +} + +static gboolean +mxf_dms1_shot_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer, + guint16 tag, const guint8 * tag_data, guint tag_size) +{ + MXFDMS1Shot *self = MXF_DMS1_SHOT (metadata); + gboolean ret = TRUE; +#ifndef GST_DISABLE_GST_DEBUG + gchar str[48]; +#endif + MXFUL *tag_ul = NULL; + static const guint8 shot_start_position_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x07, + 0x02, 0x01, 0x03, 0x01, 0x09, 0x00, 0x00 + }; + static const guint8 shot_duration_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x07, + 0x02, 0x02, 0x01, 0x02, 0x04, 0x00, 0x00 + }; + static const guint8 shot_track_ids_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x01, + 0x07, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 shot_description_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03, + 0x02, 0x01, 0x06, 0x0d, 0x01, 0x00, 0x00 + }; + static const guint8 shot_comment_kind_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x03, + 0x02, 0x05, 0x01, 0x01, 0x00, 0x00, 0x00 + }; + static const guint8 shot_comment_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x03, + 0x02, 0x05, 0x02, 0x01, 0x00, 0x00, 0x00 + }; + static const guint8 cue_words_set_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x02, 0x40, 0x23, 0x01 + }; + static const guint8 key_point_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x12, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &shot_start_position_ul, 16) == 0) { + if (tag_size != 8) + goto error; + + self->shot_start_position = GST_READ_UINT64_BE (tag_data); + GST_DEBUG (" shot start position = %" G_GINT64_FORMAT, + self->shot_start_position); + } else if (memcmp (tag_ul, &shot_duration_ul, 16) == 0) { + if (tag_size != 8) + goto error; + + self->shot_duration = GST_READ_UINT64_BE (tag_data); + GST_DEBUG (" shot duration = %" G_GINT64_FORMAT, self->shot_duration); + } else if (memcmp (tag_ul, &shot_track_ids_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of shot track ids = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 4) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 4 * len) + goto error; + + self->n_shot_track_ids = len; + self->shot_track_ids = g_new0 (guint32, len); + + for (i = 0; i < len; i++) { + self->shot_track_ids[i] = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" shot track ids %u = %u", i, self->shot_track_ids[i]); + tag_data += 4; + tag_size -= 4; + } + } else if (memcmp (tag_ul, &shot_description_ul, 16) == 0) { + self->shot_description = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" shot description = %s", + GST_STR_NULL (self->shot_description)); + } else if (memcmp (tag_ul, &shot_comment_kind_ul, 16) == 0) { + self->shot_comment_kind = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" shot comment kind = %s", + GST_STR_NULL (self->shot_comment_kind)); + } else if (memcmp (tag_ul, &shot_comment_ul, 16) == 0) { + self->shot_comment = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" shot comment = %s", GST_STR_NULL (self->shot_comment)); + } else if (memcmp (tag_ul, &cue_words_set_ul, 16) == 0) { + if (tag_size != 16) + goto error; + + memcpy (&self->cue_words_set_uid, tag_data, 16); + GST_DEBUG (" cue words set = %s", + mxf_ul_to_string (&self->cue_words_set_uid, str)); + } else if (memcmp (tag_ul, &key_point_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of key point sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_key_point_sets = len; + self->key_point_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->key_point_sets_uids[i], tag_data, 16); + GST_DEBUG (" key point sets %u = %s", i, + mxf_ul_to_string (&self->key_point_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_shot_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 shot local tag 0x%04x of size %u", tag, tag_size); + + return FALSE; +} + +static void +mxf_dms1_shot_init (MXFDMS1Shot * self) +{ +} + +static void +mxf_dms1_shot_class_init (MXFDMS1ShotClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_shot_finalize; + metadatabase_class->handle_tag = mxf_dms1_shot_handle_tag; + metadatabase_class->resolve = mxf_dms1_shot_resolve; +} + +G_DEFINE_TYPE (MXFDMS1KeyPoint, mxf_dms1_key_point, MXF_TYPE_DMS1_THESAURUS); + +static void +mxf_dms1_key_point_finalize (GstMiniObject * object) +{ + MXFDMS1KeyPoint *self = MXF_DMS1_KEY_POINT (object); + + g_free (self->keypoint_kind); + self->keypoint_kind = NULL; + + g_free (self->keypoint_value); + self->keypoint_value = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_key_point_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_key_point_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1KeyPoint *self = MXF_DMS1_KEY_POINT (metadata); + gboolean ret = TRUE; + MXFUL *tag_ul = NULL; + static const guint8 keypoint_kind_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x03, + 0x02, 0x01, 0x02, 0x10, 0x01, 0x00, 0x00 + }; + static const guint8 keypoint_value_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x03, + 0x02, 0x01, 0x02, 0x11, 0x01, 0x00, 0x00 + }; + static const guint8 keypoint_position_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x07, + 0x02, 0x01, 0x03, 0x01, 0x07, 0x00, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &keypoint_kind_ul, 16) == 0) { + self->keypoint_kind = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" keypoint kind = %s", GST_STR_NULL (self->keypoint_kind)); + } else if (memcmp (tag_ul, &keypoint_value_ul, 16) == 0) { + self->keypoint_value = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" keypoint value = %s", GST_STR_NULL (self->keypoint_value)); + } else if (memcmp (tag_ul, &keypoint_position_ul, 16) == 0) { + if (tag_size != 8) + goto error; + + self->keypoint_position = GST_READ_UINT64_BE (tag_data); + GST_DEBUG (" keypoint position = %" G_GINT64_FORMAT, + self->keypoint_position); + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_key_point_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 key point local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_dms1_key_point_init (MXFDMS1KeyPoint * self) +{ +} + +static void +mxf_dms1_key_point_class_init (MXFDMS1KeyPointClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_key_point_finalize; + metadatabase_class->handle_tag = mxf_dms1_key_point_handle_tag; +} + +G_DEFINE_TYPE (MXFDMS1Participant, mxf_dms1_participant, + MXF_TYPE_DMS1_THESAURUS); + +static void +mxf_dms1_participant_finalize (GstMiniObject * object) +{ + MXFDMS1Participant *self = MXF_DMS1_PARTICIPANT (object); + + g_free (self->contribution_status); + self->contribution_status = NULL; + + g_free (self->job_function); + self->job_function = NULL; + + g_free (self->role_or_identity_name); + self->role_or_identity_name = NULL; + + g_free (self->person_sets_uids); + self->person_sets_uids = NULL; + + g_free (self->person_sets); + self->person_sets = NULL; + + g_free (self->organisation_sets_uids); + self->organisation_sets_uids = NULL; + + g_free (self->organisation_sets); + self->organisation_sets = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_participant_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_participant_resolve (MXFMetadataBase * m, MXFMetadataBase ** metadata) +{ + MXFDMS1Participant *self = MXF_DMS1_PARTICIPANT (m); + MXFMetadataBase **p = metadata, *current = NULL; + guint i; + + self->person_sets = g_new0 (MXFDMS1Person *, self->n_person_sets); + self->organisation_sets = + g_new0 (MXFDMS1Organisation *, self->n_organisation_sets); + + while (*p) { + current = *p; + + if (MXF_IS_DMS1_PERSON (current)) { + for (i = 0; i < self->n_person_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->person_sets_uids[i])) { + self->person_sets[i] = MXF_DMS1_PERSON (current); + break; + } + } + } + + if (MXF_IS_DMS1_ORGANISATION (current)) { + for (i = 0; i < self->n_organisation_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->organisation_sets_uids[i])) { + self->organisation_sets[i] = MXF_DMS1_ORGANISATION (current); + break; + } + } + } + + p++; + } + + return + MXF_METADATA_BASE_CLASS (mxf_dms1_participant_parent_class)->resolve (m, + metadata); +} + +static gboolean +mxf_dms1_participant_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1Participant *self = MXF_DMS1_PARTICIPANT (metadata); + gboolean ret = TRUE; +#ifndef GST_DISABLE_GST_DEBUG + gchar str[48]; +#endif + MXFUL *tag_ul = NULL; + static const guint8 participant_uid_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08, 0x01, + 0x01, 0x15, 0x40, 0x01, 0x01, 0x00, 0x00 + }; + static const guint8 contribution_status_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02, + 0x30, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00 + }; + static const guint8 job_function_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02, + 0x30, 0x05, 0x01, 0x01, 0x00, 0x00, 0x00 + }; + static const guint8 job_function_code_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02, + 0x30, 0x05, 0x01, 0x02, 0x00, 0x00, 0x00 + }; + static const guint8 role_or_identity_name_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02, + 0x30, 0x05, 0x02, 0x01, 0x00, 0x00, 0x00 + }; + static const guint8 person_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x03, 0x40, 0x14, 0x00 + }; + static const guint8 organisation_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x03, 0x40, 0x15, 0x02 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &participant_uid_ul, 16) == 0) { + if (tag_size != 16) + goto error; + + memcpy (&self->participant_uid, tag_data, 16); + GST_DEBUG (" participant uid = %s", + mxf_ul_to_string (&self->participant_uid, str)); + } else if (memcmp (tag_ul, &contribution_status_ul, 16) == 0) { + self->contribution_status = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" contribution status = %s", + GST_STR_NULL (self->contribution_status)); + } else if (memcmp (tag_ul, &job_function_ul, 16) == 0) { + self->job_function = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" job function = %s", GST_STR_NULL (self->job_function)); + } else if (memcmp (tag_ul, &job_function_code_ul, 16) == 0) { + if (tag_size > 32) + goto error; + + memcpy (self->job_function_code, tag_data, tag_size); + GST_DEBUG (" job function code = %s", self->job_function_code); + } else if (memcmp (tag_ul, &role_or_identity_name_ul, 16) == 0) { + self->role_or_identity_name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" role or identity name = %s", + GST_STR_NULL (self->role_or_identity_name)); + } else if (memcmp (tag_ul, &person_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of person sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_person_sets = len; + self->person_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->person_sets_uids[i], tag_data, 16); + GST_DEBUG (" person sets %u = %s", i, + mxf_ul_to_string (&self->person_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &organisation_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of organisation sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_organisation_sets = len; + self->organisation_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->organisation_sets_uids[i], tag_data, 16); + GST_DEBUG (" organisation sets %u = %s", i, + mxf_ul_to_string (&self->organisation_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_participant_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 participant local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_dms1_participant_init (MXFDMS1Participant * self) +{ +} + +static void +mxf_dms1_participant_class_init (MXFDMS1ParticipantClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_participant_finalize; + metadatabase_class->handle_tag = mxf_dms1_participant_handle_tag; + metadatabase_class->resolve = mxf_dms1_participant_resolve; +} + +G_DEFINE_ABSTRACT_TYPE (MXFDMS1Contact, mxf_dms1_contact, + MXF_TYPE_DMS1_THESAURUS); + +static void +mxf_dms1_contact_finalize (GstMiniObject * object) +{ + MXFDMS1Contact *self = MXF_DMS1_CONTACT (object); + + g_free (self->name_value_sets_uids); + self->name_value_sets_uids = NULL; + + g_free (self->name_value_sets); + self->name_value_sets = NULL; + + g_free (self->address_sets_uids); + self->address_sets_uids = NULL; + + g_free (self->address_sets); + self->address_sets = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_contact_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_contact_resolve (MXFMetadataBase * m, MXFMetadataBase ** metadata) +{ + MXFDMS1Contact *self = MXF_DMS1_CONTACT (m); + MXFMetadataBase **p = metadata, *current = NULL; + guint i; + + self->name_value_sets = g_new0 (MXFDMS1NameValue *, self->n_name_value_sets); + self->address_sets = g_new0 (MXFDMS1Address *, self->n_address_sets); + + while (*p) { + current = *p; + + if (MXF_IS_DMS1_NAME_VALUE (current)) { + for (i = 0; i < self->n_name_value_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->name_value_sets_uids[i])) { + self->name_value_sets[i] = MXF_DMS1_NAME_VALUE (current); + break; + } + } + } + + if (MXF_IS_DMS1_ADDRESS (current)) { + for (i = 0; i < self->n_address_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->address_sets_uids[i])) { + self->address_sets[i] = MXF_DMS1_ADDRESS (current); + break; + } + } + } + + p++; + } + + return MXF_METADATA_BASE_CLASS (mxf_dms1_contact_parent_class)->resolve (m, + metadata); +} + +static gboolean +mxf_dms1_contact_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer, + guint16 tag, const guint8 * tag_data, guint tag_size) +{ + MXFDMS1Contact *self = MXF_DMS1_CONTACT (metadata); + gboolean ret = TRUE; +#ifndef GST_DISABLE_GST_DEBUG + gchar str[48]; +#endif + MXFUL *tag_ul = NULL; + static const guint8 contact_uid_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08, 0x01, + 0x01, 0x15, 0x40, 0x01, 0x02, 0x00, 0x00 + }; + static const guint8 name_value_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x1f, 0x02 + }; + static const guint8 address_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x17, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &contact_uid_ul, 16) == 0) { + if (tag_size != 16) + goto error; + + memcpy (&self->contact_uid, tag_data, 16); + GST_DEBUG (" contact uid = %s", mxf_ul_to_string (&self->contact_uid, + str)); + } else if (memcmp (tag_ul, &name_value_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of name-value sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_name_value_sets = len; + self->name_value_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->name_value_sets_uids[i], tag_data, 16); + GST_DEBUG (" name-value sets %u = %s", i, + mxf_ul_to_string (&self->name_value_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &address_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of address sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_address_sets = len; + self->address_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->address_sets_uids[i], tag_data, 16); + GST_DEBUG (" address sets %u = %s", i, + mxf_ul_to_string (&self->address_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_contact_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 contact local tag 0x%04x of size %u", tag, tag_size); + + return FALSE; +} + +static void +mxf_dms1_contact_init (MXFDMS1Contact * self) +{ +} + +static void +mxf_dms1_contact_class_init (MXFDMS1ContactClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_contact_finalize; + metadatabase_class->handle_tag = mxf_dms1_contact_handle_tag; + metadatabase_class->resolve = mxf_dms1_contact_resolve; +} + +G_DEFINE_TYPE (MXFDMS1Person, mxf_dms1_person, MXF_TYPE_DMS1_CONTACT); + +static void +mxf_dms1_person_finalize (GstMiniObject * object) +{ + MXFDMS1Person *self = MXF_DMS1_PERSON (object); + + g_free (self->family_name); + self->family_name = NULL; + + g_free (self->first_given_name); + self->first_given_name = NULL; + + g_free (self->other_given_names); + self->other_given_names = NULL; + + g_free (self->linking_name); + self->linking_name = NULL; + + g_free (self->salutation); + self->salutation = NULL; + + g_free (self->name_suffix); + self->name_suffix = NULL; + + g_free (self->honours_qualifications); + self->honours_qualifications = NULL; + + g_free (self->former_family_name); + self->former_family_name = NULL; + + g_free (self->person_description); + self->person_description = NULL; + + g_free (self->alternate_name); + self->alternate_name = NULL; + + g_free (self->nationality); + self->nationality = NULL; + + g_free (self->citizenship); + self->citizenship = NULL; + + g_free (self->organisation_sets_uids); + self->organisation_sets_uids = NULL; + + g_free (self->organisation_sets); + self->organisation_sets = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_person_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_person_resolve (MXFMetadataBase * m, MXFMetadataBase ** metadata) +{ + MXFDMS1Person *self = MXF_DMS1_PERSON (m); + MXFMetadataBase **p = metadata, *current = NULL; + guint i; + + self->organisation_sets = + g_new0 (MXFDMS1Organisation *, self->n_organisation_sets); + + while (*p) { + current = *p; + + if (MXF_IS_DMS1_ORGANISATION (current)) { + for (i = 0; i < self->n_organisation_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->organisation_sets_uids[i])) { + self->organisation_sets[i] = MXF_DMS1_ORGANISATION (current); + break; + } + } + } + + p++; + } + + return MXF_METADATA_BASE_CLASS (mxf_dms1_person_parent_class)->resolve (m, + metadata); +} + +static gboolean +mxf_dms1_person_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer, + guint16 tag, const guint8 * tag_data, guint tag_size) +{ + MXFDMS1Person *self = MXF_DMS1_PERSON (metadata); + gboolean ret = TRUE; +#ifndef GST_DISABLE_GST_DEBUG + gchar str[48]; +#endif + MXFUL *tag_ul = NULL; + static const guint8 family_name_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02, + 0x30, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00 + }; + static const guint8 first_given_name_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x02, + 0x30, 0x06, 0x03, 0x01, 0x02, 0x01, 0x00 + }; + static const guint8 other_given_names_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x02, + 0x30, 0x06, 0x03, 0x01, 0x08, 0x01, 0x00 + }; + static const guint8 linking_name_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x02, + 0x30, 0x06, 0x03, 0x01, 0x0a, 0x01, 0x00 + }; + static const guint8 salutation_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x02, + 0x30, 0x06, 0x03, 0x01, 0x05, 0x01, 0x00 + }; + static const guint8 name_suffix_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x02, + 0x30, 0x06, 0x03, 0x01, 0x0b, 0x01, 0x00 + }; + static const guint8 honours_qualifications_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x02, + 0x30, 0x06, 0x03, 0x01, 0x06, 0x01, 0x00 + }; + static const guint8 former_family_name_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x02, + 0x30, 0x06, 0x03, 0x01, 0x0c, 0x01, 0x00 + }; + static const guint8 person_description_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02, + 0x30, 0x06, 0x03, 0x01, 0x07, 0x01, 0x00 + }; + static const guint8 alternate_name_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x02, + 0x30, 0x06, 0x03, 0x01, 0x09, 0x01, 0x00 + }; + static const guint8 nationality_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x02, + 0x30, 0x06, 0x03, 0x01, 0x0d, 0x01, 0x00 + }; + static const guint8 citizenship_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x02, + 0x30, 0x06, 0x03, 0x01, 0x0e, 0x01, 0x00 + }; + static const guint8 organisation_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x03, 0x40, 0x15, 0x02 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &family_name_ul, 16) == 0) { + self->family_name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" family name = %s", GST_STR_NULL (self->family_name)); + } else if (memcmp (tag_ul, &first_given_name_ul, 16) == 0) { + self->first_given_name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" first given name = %s", + GST_STR_NULL (self->first_given_name)); + } else if (memcmp (tag_ul, &other_given_names_ul, 16) == 0) { + self->other_given_names = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" other given names = %s", + GST_STR_NULL (self->other_given_names)); + } else if (memcmp (tag_ul, &linking_name_ul, 16) == 0) { + self->linking_name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" linking name = %s", GST_STR_NULL (self->linking_name)); + } else if (memcmp (tag_ul, &salutation_ul, 16) == 0) { + self->salutation = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" salutation = %s", GST_STR_NULL (self->salutation)); + } else if (memcmp (tag_ul, &name_suffix_ul, 16) == 0) { + self->name_suffix = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" name suffix = %s", GST_STR_NULL (self->name_suffix)); + } else if (memcmp (tag_ul, &honours_qualifications_ul, 16) == 0) { + self->honours_qualifications = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" honours & qualifications = %s", + GST_STR_NULL (self->honours_qualifications)); + } else if (memcmp (tag_ul, &former_family_name_ul, 16) == 0) { + self->former_family_name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" former family name = %s", + GST_STR_NULL (self->former_family_name)); + } else if (memcmp (tag_ul, &person_description_ul, 16) == 0) { + self->person_description = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" person description = %s", + GST_STR_NULL (self->person_description)); + } else if (memcmp (tag_ul, &alternate_name_ul, 16) == 0) { + self->alternate_name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" alternate name = %s", GST_STR_NULL (self->alternate_name)); + } else if (memcmp (tag_ul, &nationality_ul, 16) == 0) { + self->nationality = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" nationality = %s", GST_STR_NULL (self->nationality)); + } else if (memcmp (tag_ul, &citizenship_ul, 16) == 0) { + self->citizenship = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" citizenship = %s", GST_STR_NULL (self->citizenship)); + } else if (memcmp (tag_ul, &organisation_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of organisation sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_organisation_sets = len; + self->organisation_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->organisation_sets_uids[i], tag_data, 16); + GST_DEBUG (" organisation sets %u = %s", i, + mxf_ul_to_string (&self->organisation_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_person_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 person local tag 0x%04x of size %u", tag, tag_size); + + return FALSE; +} + +static void +mxf_dms1_person_init (MXFDMS1Person * self) +{ +} + +static void +mxf_dms1_person_class_init (MXFDMS1PersonClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_person_finalize; + metadatabase_class->handle_tag = mxf_dms1_person_handle_tag; + metadatabase_class->resolve = mxf_dms1_person_resolve; +} + +G_DEFINE_TYPE (MXFDMS1Organisation, mxf_dms1_organisation, + MXF_TYPE_DMS1_CONTACT); + +static void +mxf_dms1_organisation_finalize (GstMiniObject * object) +{ + MXFDMS1Organisation *self = MXF_DMS1_ORGANISATION (object); + + g_free (self->nature_of_organisation); + self->nature_of_organisation = NULL; + + g_free (self->organisation_main_name); + self->organisation_main_name = NULL; + + g_free (self->organisation_code); + self->organisation_code = NULL; + + g_free (self->contact_department); + self->contact_department = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_organisation_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_organisation_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1Organisation *self = MXF_DMS1_ORGANISATION (metadata); + gboolean ret = TRUE; + MXFUL *tag_ul = NULL; + static const guint8 nature_of_organisation_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02, + 0x30, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00 + }; + static const guint8 organisation_main_name_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02, + 0x30, 0x06, 0x03, 0x03, 0x01, 0x01, 0x00 + }; + static const guint8 organisation_code_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x01, + 0x0a, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00 + }; + static const guint8 contact_department_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02, + 0x30, 0x06, 0x02, 0x01, 0x00, 0x00, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &nature_of_organisation_ul, 16) == 0) { + self->nature_of_organisation = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" nature of organisation = %s", + GST_STR_NULL (self->nature_of_organisation)); + } else if (memcmp (tag_ul, &organisation_main_name_ul, 16) == 0) { + self->organisation_main_name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" organisation main name = %s", + GST_STR_NULL (self->organisation_main_name)); + } else if (memcmp (tag_ul, &organisation_code_ul, 16) == 0) { + self->organisation_code = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" organisation code = %s", + GST_STR_NULL (self->organisation_code)); + } else if (memcmp (tag_ul, &contact_department_ul, 16) == 0) { + self->contact_department = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" contact department = %s", + GST_STR_NULL (self->contact_department)); + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_organisation_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; +} + +static void +mxf_dms1_organisation_init (MXFDMS1Organisation * self) +{ +} + +static void +mxf_dms1_organisation_class_init (MXFDMS1OrganisationClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_organisation_finalize; + metadatabase_class->handle_tag = mxf_dms1_organisation_handle_tag; +} + +G_DEFINE_TYPE (MXFDMS1Location, mxf_dms1_location, MXF_TYPE_DMS1_CONTACT); + +static void +mxf_dms1_location_finalize (GstMiniObject * object) +{ + MXFDMS1Location *self = MXF_DMS1_LOCATION (object); + + g_free (self->location_kind); + self->location_kind = NULL; + + g_free (self->location_description); + self->location_description = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_location_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_location_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1Location *self = MXF_DMS1_LOCATION (metadata); + gboolean ret = TRUE; + MXFUL *tag_ul = NULL; + static const guint8 location_kind_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x07, + 0x01, 0x20, 0x02, 0x03, 0x01, 0x00, 0x00 + }; + static const guint8 location_description_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x07, + 0x01, 0x20, 0x02, 0x02, 0x01, 0x00, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &location_kind_ul, 16) == 0) { + self->location_kind = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" location kind = %s", GST_STR_NULL (self->location_kind)); + } else if (memcmp (tag_ul, &location_description_ul, 16) == 0) { + self->location_description = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" location description = %s", + GST_STR_NULL (self->location_description)); + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_location_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; +} + +static void +mxf_dms1_location_init (MXFDMS1Location * self) +{ +} + +static void +mxf_dms1_location_class_init (MXFDMS1LocationClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_location_finalize; + metadatabase_class->handle_tag = mxf_dms1_location_handle_tag; +} + +G_DEFINE_TYPE (MXFDMS1Address, mxf_dms1_address, MXF_TYPE_DMS1); + +static void +mxf_dms1_address_finalize (GstMiniObject * object) +{ + MXFDMS1Address *self = MXF_DMS1_ADDRESS (object); + + g_free (self->room_or_suite_number); + self->room_or_suite_number = NULL; + + g_free (self->room_or_suite_name); + self->room_or_suite_name = NULL; + + g_free (self->building_name); + self->building_name = NULL; + + g_free (self->street_number); + self->street_number = NULL; + + g_free (self->street_name); + self->street_name = NULL; + + g_free (self->postal_town); + self->postal_town = NULL; + + g_free (self->city); + self->city = NULL; + + g_free (self->state_or_province_or_country); + self->state_or_province_or_country = NULL; + + g_free (self->postal_code); + self->postal_code = NULL; + + g_free (self->country); + self->country = NULL; + + g_free (self->astronomical_body_name); + self->astronomical_body_name = NULL; + + g_free (self->communications_sets_uids); + self->communications_sets_uids = NULL; + + g_free (self->communications_sets); + self->communications_sets = NULL; + + g_free (self->name_value_sets_uids); + self->name_value_sets_uids = NULL; + + g_free (self->name_value_sets); + self->name_value_sets = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_address_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_address_resolve (MXFMetadataBase * m, MXFMetadataBase ** metadata) +{ + MXFDMS1Address *self = MXF_DMS1_ADDRESS (m); + MXFMetadataBase **p = metadata, *current = NULL; + guint i; + + self->communications_sets = + g_new0 (MXFDMS1Communications *, self->n_communications_sets); + self->name_value_sets = g_new0 (MXFDMS1NameValue *, self->n_name_value_sets); + while (*p != NULL) { + current = *p; + + if (MXF_IS_DMS1_COMMUNICATIONS (current)) { + for (i = 0; i < self->n_communications_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->communications_sets_uids[i])) { + self->communications_sets[i] = MXF_DMS1_COMMUNICATIONS (self); + break; + } + } + } + + if (MXF_IS_DMS1_NAME_VALUE (current)) { + for (i = 0; i < self->n_name_value_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->name_value_sets_uids[i])) { + self->name_value_sets[i] = MXF_DMS1_NAME_VALUE (self); + break; + } + } + } + + p++; + } + + return MXF_METADATA_BASE_CLASS (mxf_dms1_address_parent_class)->resolve (m, + metadata); +} + +static gboolean +mxf_dms1_address_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer, + guint16 tag, const guint8 * tag_data, guint tag_size) +{ + MXFDMS1Address *self = MXF_DMS1_ADDRESS (metadata); + gboolean ret = TRUE; +#ifndef GST_DISABLE_GST_DEBUG + gchar str[48]; +#endif + MXFUL *tag_ul = NULL; + static const guint8 room_or_suite_number_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x07, + 0x01, 0x20, 0x01, 0x04, 0x01, 0x01, 0x01 + }; + static const guint8 room_or_suite_name_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x07, + 0x01, 0x20, 0x01, 0x04, 0x01, 0x11, 0x01 + }; + static const guint8 building_name_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x07, + 0x01, 0x20, 0x01, 0x04, 0x01, 0x12, 0x01 + }; + static const guint8 place_name_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x07, + 0x01, 0x20, 0x01, 0x04, 0x01, 0x14, 0x01 + }; + static const guint8 street_number_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x07, + 0x01, 0x20, 0x01, 0x04, 0x01, 0x02, 0x01 + }; + static const guint8 street_name_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x07, + 0x01, 0x20, 0x01, 0x04, 0x01, 0x03, 0x01 + }; + static const guint8 postal_town_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x07, + 0x01, 0x20, 0x01, 0x04, 0x01, 0x04, 0x01 + }; + static const guint8 city_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x07, + 0x01, 0x20, 0x01, 0x04, 0x01, 0x05, 0x01 + }; + static const guint8 state_or_province_or_country_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x07, + 0x01, 0x20, 0x01, 0x04, 0x01, 0x06, 0x01 + }; + static const guint8 postal_code_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x07, + 0x01, 0x20, 0x01, 0x04, 0x01, 0x07, 0x01 + }; + static const guint8 country_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x07, + 0x01, 0x20, 0x01, 0x04, 0x01, 0x08, 0x01 + }; + static const guint8 geographical_coordinate_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x07, + 0x01, 0x20, 0x01, 0x04, 0x01, 0x15, 0x01 + }; + static const guint8 astronomical_body_name_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x07, + 0x01, 0x20, 0x01, 0x04, 0x01, 0x16, 0x01 + }; + static const guint8 communications_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x19, 0x00 + }; + static const guint8 name_value_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x1f, 0x04 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &room_or_suite_name_ul, 16) == 0) { + self->room_or_suite_name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" room or suite name = %s", + GST_STR_NULL (self->room_or_suite_name)); + } else if (memcmp (tag_ul, &room_or_suite_number_ul, 16) == 0) { + self->room_or_suite_number = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" room or suite number = %s", + GST_STR_NULL (self->room_or_suite_number)); + } else if (memcmp (tag_ul, &building_name_ul, 16) == 0) { + self->building_name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" building name = %s", GST_STR_NULL (self->building_name)); + } else if (memcmp (tag_ul, &place_name_ul, 16) == 0) { + self->place_name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" place name = %s", GST_STR_NULL (self->place_name)); + } else if (memcmp (tag_ul, &street_number_ul, 16) == 0) { + self->street_number = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" street number = %s", GST_STR_NULL (self->street_number)); + } else if (memcmp (tag_ul, &street_name_ul, 16) == 0) { + self->street_name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" street name = %s", GST_STR_NULL (self->street_name)); + } else if (memcmp (tag_ul, &postal_town_ul, 16) == 0) { + self->postal_town = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" postal town = %s", GST_STR_NULL (self->postal_town)); + } else if (memcmp (tag_ul, &city_ul, 16) == 0) { + self->city = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" city = %s", GST_STR_NULL (self->city)); + } else if (memcmp (tag_ul, &state_or_province_or_country_ul, 16) == 0) { + self->state_or_province_or_country = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" state or province or country = %s", + GST_STR_NULL (self->state_or_province_or_country)); + } else if (memcmp (tag_ul, &postal_code_ul, 16) == 0) { + self->postal_code = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" postal code = %s", GST_STR_NULL (self->postal_code)); + } else if (memcmp (tag_ul, &country_ul, 16) == 0) { + self->country = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" country = %s", GST_STR_NULL (self->country)); + } else if (memcmp (tag_ul, &geographical_coordinate_ul, 16) == 0) { + if (tag_size != 12) + goto error; + + memcpy (&self->geographical_coordinate, tag_data, 12); + /* TODO implement */ + } else if (memcmp (tag_ul, &astronomical_body_name_ul, 16) == 0) { + self->astronomical_body_name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" astronomical body name = %s", + GST_STR_NULL (self->astronomical_body_name)); + } else if (memcmp (tag_ul, &communications_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of communications sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_communications_sets = len; + self->communications_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->communications_sets_uids[i], tag_data, 16); + GST_DEBUG (" communications sets %u = %s", i, + mxf_ul_to_string (&self->communications_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &name_value_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of name-value sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_name_value_sets = len; + self->name_value_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->name_value_sets_uids[i], tag_data, 16); + GST_DEBUG (" name-value sets %u = %s", i, + mxf_ul_to_string (&self->name_value_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_address_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 address local tag 0x%04x of size %u", tag, tag_size); + + return FALSE; +} + +static void +mxf_dms1_address_init (MXFDMS1Address * self) +{ +} + +static void +mxf_dms1_address_class_init (MXFDMS1AddressClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_address_finalize; + metadatabase_class->handle_tag = mxf_dms1_address_handle_tag; + metadatabase_class->resolve = mxf_dms1_address_resolve; +} + +G_DEFINE_TYPE (MXFDMS1Communications, mxf_dms1_communications, MXF_TYPE_DMS1); + +static void +mxf_dms1_communications_finalize (GstMiniObject * object) +{ + MXFDMS1Communications *self = MXF_DMS1_COMMUNICATIONS (object); + + g_free (self->email_address); + self->email_address = NULL; + + g_free (self->web_page); + self->web_page = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_communications_parent_class)->finalize + (object); +} + +static gboolean +mxf_dms1_communications_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1Communications *self = MXF_DMS1_COMMUNICATIONS (metadata); + gboolean ret = TRUE; + MXFUL *tag_ul = NULL; + static const guint8 central_telephone_number_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x07, + 0x01, 0x20, 0x01, 0x10, 0x03, 0x04, 0x00 + }; + static const guint8 telephone_number_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x07, + 0x01, 0x20, 0x01, 0x10, 0x03, 0x01, 0x00 + }; + static const guint8 mobile_telephone_number_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x07, + 0x01, 0x20, 0x01, 0x10, 0x03, 0x05, 0x00 + }; + static const guint8 fax_number_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x07, + 0x01, 0x20, 0x01, 0x10, 0x03, 0x02, 0x00 + }; + static const guint8 email_address_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x07, + 0x01, 0x20, 0x01, 0x10, 0x03, 0x03, 0x01 + }; + static const guint8 web_page_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x07, + 0x01, 0x20, 0x01, 0x10, 0x03, 0x06, 0x01 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, ¢ral_telephone_number_ul, 16) == 0) { + if (tag_size > 32) + goto error; + memcpy (self->central_telephone_number, tag_data, tag_size); + + GST_DEBUG (" central telephone number = %s", + self->central_telephone_number); + } else if (memcmp (tag_ul, &telephone_number_ul, 16) == 0) { + if (tag_size > 32) + goto error; + memcpy (self->telephone_number, tag_data, tag_size); + + GST_DEBUG (" telephone number = %s", self->telephone_number); + } else if (memcmp (tag_ul, &mobile_telephone_number_ul, 16) == 0) { + if (tag_size > 32) + goto error; + memcpy (self->mobile_telephone_number, tag_data, tag_size); + + GST_DEBUG (" mobile telephone number = %s", self->mobile_telephone_number); + } else if (memcmp (tag_ul, &fax_number_ul, 16) == 0) { + if (tag_size > 32) + goto error; + memcpy (self->fax_number, tag_data, tag_size); + + GST_DEBUG (" fax number = %s", self->fax_number); + } else if (memcmp (tag_ul, &email_address_ul, 16) == 0) { + self->email_address = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" email address = %s", GST_STR_NULL (self->email_address)); + } else if (memcmp (tag_ul, &web_page_ul, 16) == 0) { + self->web_page = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" web page = %s", GST_STR_NULL (self->web_page)); + } else { + ret = + MXF_METADATA_BASE_CLASS + (mxf_dms1_communications_parent_class)->handle_tag (metadata, primer, + tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 communications local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_dms1_communications_init (MXFDMS1Communications * self) +{ +} + +static void +mxf_dms1_communications_class_init (MXFDMS1CommunicationsClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_communications_finalize; + metadatabase_class->handle_tag = mxf_dms1_communications_handle_tag; +} + +G_DEFINE_TYPE (MXFDMS1Contract, mxf_dms1_contract, MXF_TYPE_DMS1_THESAURUS); + +static void +mxf_dms1_contract_finalize (GstMiniObject * object) +{ + MXFDMS1Contract *self = MXF_DMS1_CONTRACT (object); + + g_free (self->rights_sets_uids); + self->rights_sets_uids = NULL; + + g_free (self->rights_sets); + self->rights_sets = NULL; + + g_free (self->participant_sets_uids); + self->participant_sets_uids = NULL; + + g_free (self->participant_sets); + self->participant_sets = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_contract_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_contract_resolve (MXFMetadataBase * m, MXFMetadataBase ** metadata) +{ + MXFDMS1Contract *self = MXF_DMS1_CONTRACT (m); + MXFMetadataBase **p = metadata, *current = NULL; + guint i; + + self->rights_sets = g_new0 (MXFDMS1Rights *, self->n_rights_sets); + self->participant_sets = + g_new0 (MXFDMS1Participant *, self->n_participant_sets); + while (*p) { + current = *p; + + if (MXF_IS_DMS1_RIGHTS (current)) { + for (i = 0; i < self->n_rights_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->rights_sets_uids[i])) { + self->rights_sets[i] = MXF_DMS1_RIGHTS (current); + break; + } + } + } + + if (MXF_IS_DMS1_PARTICIPANT (current)) { + for (i = 0; i < self->n_participant_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->participant_sets_uids[i])) { + self->participant_sets[i] = MXF_DMS1_PARTICIPANT (current); + break; + } + } + } + + p++; + } + + return MXF_METADATA_BASE_CLASS (mxf_dms1_contract_parent_class)->resolve (m, + metadata); +} + +static gboolean +mxf_dms1_contract_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1Contract *self = MXF_DMS1_CONTRACT (metadata); + gboolean ret = TRUE; +#ifndef GST_DISABLE_GST_DEBUG + gchar str[48]; +#endif + MXFUL *tag_ul = NULL; + static const guint8 supply_contract_number_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x02, + 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 rights_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x1a, 0x00 + }; + static const guint8 participant_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x03, 0x40, 0x13, 0x02 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &supply_contract_number_ul, 16) == 0) { + if (tag_size > 32) + goto error; + + memcpy (self->supply_contract_number, tag_data, tag_size); + GST_DEBUG (" supply contract number = %s", self->supply_contract_number); + } else if (memcmp (tag_ul, &rights_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of rights sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_rights_sets = len; + self->rights_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->rights_sets_uids[i], tag_data, 16); + GST_DEBUG (" rights sets %u = %s", i, + mxf_ul_to_string (&self->rights_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &participant_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of participant sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_participant_sets = len; + self->participant_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->participant_sets_uids[i], tag_data, 16); + GST_DEBUG (" participant sets %u = %s", i, + mxf_ul_to_string (&self->participant_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_contract_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 contract local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_dms1_contract_init (MXFDMS1Contract * self) +{ +} + +static void +mxf_dms1_contract_class_init (MXFDMS1ContractClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_contract_finalize; + metadatabase_class->handle_tag = mxf_dms1_contract_handle_tag; + metadatabase_class->resolve = mxf_dms1_contract_resolve; +} + +G_DEFINE_TYPE (MXFDMS1Rights, mxf_dms1_rights, MXF_TYPE_DMS1_THESAURUS); + +static void +mxf_dms1_rights_finalize (GstMiniObject * object) +{ + MXFDMS1Rights *self = MXF_DMS1_RIGHTS (object); + + g_free (self->copyright_owner); + self->copyright_owner = NULL; + + g_free (self->rights_holder); + self->rights_holder = NULL; + + g_free (self->rights_managment_authority); + self->rights_managment_authority = NULL; + + g_free (self->region_or_area_of_ip_license); + self->region_or_area_of_ip_license = NULL; + + g_free (self->intellectual_property_type); + self->intellectual_property_type = NULL; + + g_free (self->right_condition); + self->right_condition = NULL; + + g_free (self->right_remarks); + self->right_remarks = NULL; + + g_free (self->intellectual_property_right); + self->intellectual_property_right = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_rights_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_rights_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer, + guint16 tag, const guint8 * tag_data, guint tag_size) +{ + MXFDMS1Rights *self = MXF_DMS1_RIGHTS (metadata); + gboolean ret = TRUE; + MXFUL *tag_ul = NULL; + static const guint8 copyright_owner_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02, + 0x05, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00 + }; + static const guint8 rights_holder_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02, + 0x05, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00 + }; + static const guint8 rights_managment_authority_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02, + 0x05, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00 + }; + static const guint8 region_or_area_of_ip_license_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x07, + 0x01, 0x20, 0x01, 0x03, 0x05, 0x01, 0x00 + }; + static const guint8 intellectual_property_type_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02, + 0x05, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00 + }; + static const guint8 right_condition_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02, + 0x05, 0x04, 0x03, 0x01, 0x00, 0x00, 0x00 + }; + static const guint8 right_remarks_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08, 0x02, + 0x05, 0x04, 0x04, 0x01, 0x00, 0x00, 0x00 + }; + static const guint8 intellectual_property_right_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02, + 0x05, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00 + }; + static const guint8 rights_start_date_and_time_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x07, + 0x02, 0x01, 0x20, 0x02, 0x00, 0x00, 0x00 + }; + static const guint8 rights_stop_date_and_time_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x07, + 0x02, 0x01, 0x20, 0x03, 0x00, 0x00, 0x00 + }; + static const guint8 maximum_number_of_usages_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x02, + 0x05, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, ©right_owner_ul, 16) == 0) { + self->copyright_owner = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" copyright owner = %s", GST_STR_NULL (self->copyright_owner)); + } else if (memcmp (tag_ul, &rights_holder_ul, 16) == 0) { + self->rights_holder = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" rights holder = %s", GST_STR_NULL (self->rights_holder)); + } else if (memcmp (tag_ul, &rights_managment_authority_ul, 16) == 0) { + self->rights_managment_authority = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" rights managment authority = %s", + GST_STR_NULL (self->rights_managment_authority)); + } else if (memcmp (tag_ul, ®ion_or_area_of_ip_license_ul, 16) == 0) { + self->region_or_area_of_ip_license = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" region or area of ip license = %s", + GST_STR_NULL (self->region_or_area_of_ip_license)); + } else if (memcmp (tag_ul, &intellectual_property_type_ul, 16) == 0) { + self->intellectual_property_type = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" intellectual property type = %s", + GST_STR_NULL (self->intellectual_property_type)); + } else if (memcmp (tag_ul, &right_condition_ul, 16) == 0) { + self->right_condition = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" right condition = %s", GST_STR_NULL (self->right_condition)); + } else if (memcmp (tag_ul, &right_remarks_ul, 16) == 0) { + self->right_remarks = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" right remarks = %s", GST_STR_NULL (self->right_remarks)); + } else if (memcmp (tag_ul, &intellectual_property_right_ul, 16) == 0) { + self->intellectual_property_right = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" intellectual property right = %s", + GST_STR_NULL (self->intellectual_property_right)); + } else if (memcmp (tag_ul, &rights_start_date_and_time_ul, 16) == 0) { + if (!mxf_timestamp_parse (&self->rights_start_date_and_time, tag_data, + tag_size)) + goto error; + + GST_DEBUG (" rights start date and time = %d/%u/%u %u:%u:%u.%u", + self->rights_start_date_and_time.year, + self->rights_start_date_and_time.month, + self->rights_start_date_and_time.day, + self->rights_start_date_and_time.hour, + self->rights_start_date_and_time.minute, + self->rights_start_date_and_time.second, + (self->rights_start_date_and_time.quarter_msecond * 1000) / 256); + } else if (memcmp (tag_ul, &rights_stop_date_and_time_ul, 16) == 0) { + if (!mxf_timestamp_parse (&self->rights_start_date_and_time, tag_data, + tag_size)) + goto error; + + GST_DEBUG (" rights stop date and time = %d/%u/%u %u:%u:%u.%u", + self->rights_stop_date_and_time.year, + self->rights_stop_date_and_time.month, + self->rights_stop_date_and_time.day, + self->rights_stop_date_and_time.hour, + self->rights_stop_date_and_time.minute, + self->rights_stop_date_and_time.second, + (self->rights_stop_date_and_time.quarter_msecond * 1000) / 256); + } else if (memcmp (tag_ul, &maximum_number_of_usages_ul, 16) == 0) { + if (tag_size != 2) + goto error; + + self->maximum_number_of_usages = GST_READ_UINT16_BE (tag_data); + GST_DEBUG (" maximum number of usages = %u", + self->maximum_number_of_usages); + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_rights_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 rights local tag 0x%04x of size %u", tag, tag_size); + + return FALSE; +} + +static void +mxf_dms1_rights_init (MXFDMS1Rights * self) +{ +} + +static void +mxf_dms1_rights_class_init (MXFDMS1RightsClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_rights_finalize; + metadatabase_class->handle_tag = mxf_dms1_rights_handle_tag; +} + +G_DEFINE_TYPE (MXFDMS1PictureFormat, mxf_dms1_picture_format, MXF_TYPE_DMS1); + +static void +mxf_dms1_picture_format_finalize (GstMiniObject * object) +{ + MXFDMS1PictureFormat *self = MXF_DMS1_PICTURE_FORMAT (object); + + g_free (self->colour_descriptor); + self->colour_descriptor = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_picture_format_parent_class)->finalize + (object); +} + +static gboolean +mxf_dms1_picture_format_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1PictureFormat *self = MXF_DMS1_PICTURE_FORMAT (metadata); + gboolean ret = TRUE; + MXFUL *tag_ul = NULL; + static const guint8 viewport_aspect_ratio_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, 0x04, + 0x01, 0x01, 0x01, 0x03, 0x00, 0x00, 0x00 + }; + static const guint8 perceived_display_format_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x04, + 0x01, 0x01, 0x01, 0x08, 0x00, 0x00, 0x00 + }; + static const guint8 colour_descriptor_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x03, + 0x02, 0x01, 0x06, 0x04, 0x01, 0x00, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &viewport_aspect_ratio_ul, 16) == 0) { + if (!mxf_fraction_parse (&self->viewport_aspect_ratio, tag_data, tag_size)) + goto error; + + GST_DEBUG (" viewport aspect ratio = %u/%u", self->viewport_aspect_ratio.n, + self->viewport_aspect_ratio.d); + } else if (memcmp (tag_ul, &perceived_display_format_ul, 16) == 0) { + if (tag_size > 32) + goto error; + + memcpy (self->perceived_display_format, tag_data, tag_size); + GST_DEBUG (" perceived display format = %s", + self->perceived_display_format); + } else if (memcmp (tag_ul, &colour_descriptor_ul, 16) == 0) { + self->colour_descriptor = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" colour descriptor = %s", + GST_STR_NULL (self->colour_descriptor)); + } else { + ret = + MXF_METADATA_BASE_CLASS + (mxf_dms1_picture_format_parent_class)->handle_tag (metadata, primer, + tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 picture format local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_dms1_picture_format_init (MXFDMS1PictureFormat * self) +{ +} + +static void +mxf_dms1_picture_format_class_init (MXFDMS1PictureFormatClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_picture_format_finalize; + metadatabase_class->handle_tag = mxf_dms1_picture_format_handle_tag; +} + +G_DEFINE_TYPE (MXFDMS1DeviceParameters, mxf_dms1_device_parameters, + MXF_TYPE_DMS1_THESAURUS); + +static void +mxf_dms1_device_parameters_finalize (GstMiniObject * object) +{ + MXFDMS1DeviceParameters *self = MXF_DMS1_DEVICE_PARAMETERS (object); + + g_free (self->device_type); + self->device_type = NULL; + + g_free (self->manufacturer); + self->manufacturer = NULL; + + g_free (self->device_model); + self->device_model = NULL; + + g_free (self->device_serial_number); + self->device_serial_number = NULL; + + g_free (self->device_usage_description); + self->device_usage_description = NULL; + + g_free (self->name_value_sets_uids); + self->name_value_sets_uids = NULL; + + g_free (self->name_value_sets); + self->name_value_sets = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_device_parameters_parent_class)->finalize + (object); +} + +static gboolean +mxf_dms1_device_parameters_resolve (MXFMetadataBase * m, + MXFMetadataBase ** metadata) +{ + MXFDMS1DeviceParameters *self = MXF_DMS1_DEVICE_PARAMETERS (m); + MXFMetadataBase **p = metadata, *current = NULL; + guint i; + + self->name_value_sets = g_new0 (MXFDMS1NameValue *, self->n_name_value_sets); + while (*p) { + current = *p; + + if (MXF_IS_DMS1_NAME_VALUE (current)) { + for (i = 0; i < self->n_name_value_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->name_value_sets_uids[i])) { + self->name_value_sets[i] = MXF_DMS1_NAME_VALUE (current); + break; + } + } + } + + p++; + } + + return + MXF_METADATA_BASE_CLASS (mxf_dms1_device_parameters_parent_class)->resolve + (m, metadata); +} + +static gboolean +mxf_dms1_device_parameters_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1DeviceParameters *self = MXF_DMS1_DEVICE_PARAMETERS (metadata); + gboolean ret = TRUE; +#ifndef GST_DISABLE_GST_DEBUG + gchar str[48]; +#endif + MXFUL *tag_ul = NULL; + static const guint8 device_type_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x01, + 0x01, 0x20, 0x08, 0x01, 0x00, 0x00, 0x00 + }; + static const guint8 device_designation_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 device_asset_number_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x01, + 0x01, 0x20, 0x0c, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 ieee_device_identifier_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, 0x01, + 0x01, 0x20, 0x05, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 manufacturer_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, 0x01, + 0x0a, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00 + }; + static const guint8 device_model_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 device_serial_number_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 device_usage_description_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03, + 0x03, 0x03, 0x10, 0x01, 0x01, 0x00, 0x00 + }; + static const guint8 name_value_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x05, 0x40, 0x1f, 0x03 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &device_type_ul, 16) == 0) { + self->device_type = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" device type = %s", GST_STR_NULL (self->device_type)); + } else if (memcmp (tag_ul, &device_designation_ul, 16) == 0) { + if (tag_size > 32) + goto error; + + memcpy (self->device_designation, tag_data, tag_size); + GST_DEBUG (" device designation = %s", self->device_designation); + } else if (memcmp (tag_ul, &device_asset_number_ul, 16) == 0) { + if (tag_size > 32) + goto error; + + memcpy (self->device_asset_number, tag_data, tag_size); + GST_DEBUG (" device asset number = %s", self->device_asset_number); + } else if (memcmp (tag_ul, &ieee_device_identifier_ul, 16) == 0) { + if (tag_size != 6) + goto error; + + memcpy (self->ieee_device_identifier, tag_data, 6); + GST_DEBUG + (" IEEE device identifier = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", + self->ieee_device_identifier[0], self->ieee_device_identifier[1], + self->ieee_device_identifier[2], self->ieee_device_identifier[3], + self->ieee_device_identifier[4], self->ieee_device_identifier[5]); + } else if (memcmp (tag_ul, &manufacturer_ul, 16) == 0) { + self->manufacturer = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" manufacturer = %s", GST_STR_NULL (self->manufacturer)); + } else if (memcmp (tag_ul, &device_model_ul, 16) == 0) { + if (tag_size > 32) + goto error; + + memcpy (self->device_model, tag_data, tag_size); + GST_DEBUG (" device model = %s", self->device_model); + } else if (memcmp (tag_ul, &device_serial_number_ul, 16) == 0) { + if (tag_size > 32) + goto error; + + memcpy (self->device_serial_number, tag_data, tag_size); + GST_DEBUG (" device serial number = %s", self->device_serial_number); + } else if (memcmp (tag_ul, &device_usage_description_ul, 16) == 0) { + self->device_usage_description = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" device usage description = %s", + GST_STR_NULL (self->device_usage_description)); + } else if (memcmp (tag_ul, &name_value_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of name-value sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_name_value_sets = len; + self->name_value_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->name_value_sets_uids[i], tag_data, 16); + GST_DEBUG (" name-value sets %u = %s", i, + mxf_ul_to_string (&self->name_value_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else { + ret = + MXF_METADATA_BASE_CLASS + (mxf_dms1_device_parameters_parent_class)->handle_tag (metadata, primer, + tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 device parameters local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_dms1_device_parameters_init (MXFDMS1DeviceParameters * self) +{ +} + +static void +mxf_dms1_device_parameters_class_init (MXFDMS1DeviceParametersClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_device_parameters_finalize; + metadatabase_class->handle_tag = mxf_dms1_device_parameters_handle_tag; + metadatabase_class->resolve = mxf_dms1_device_parameters_resolve; +} + +G_DEFINE_TYPE (MXFDMS1NameValue, mxf_dms1_name_value, MXF_TYPE_DMS1); + +static void +mxf_dms1_name_value_finalize (GstMiniObject * object) +{ + MXFDMS1NameValue *self = MXF_DMS1_NAME_VALUE (object); + + g_free (self->item_name); + self->item_name = NULL; + + g_free (self->item_value); + self->item_value = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_name_value_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_name_value_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1NameValue *self = MXF_DMS1_NAME_VALUE (metadata); + gboolean ret = TRUE; +#ifndef GST_DISABLE_GST_DEBUG + gchar str[48]; +#endif + MXFUL *tag_ul = NULL; + static const guint8 item_name_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03, + 0x01, 0x02, 0x0a, 0x01, 0x01, 0x00, 0x00 + }; + static const guint8 item_value_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03, + 0x01, 0x02, 0x0a, 0x02, 0x01, 0x00, 0x00 + }; + static const guint8 smpte_universal_label_locator_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x01, + 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &item_name_ul, 16) == 0) { + self->item_name = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" item name = %s", GST_STR_NULL (self->item_name)); + } else if (memcmp (tag_ul, &item_value_ul, 16) == 0) { + self->item_value = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" item value = %s", GST_STR_NULL (self->item_value)); + } else if (memcmp (tag_ul, &smpte_universal_label_locator_ul, 16) == 0) { + if (tag_size != 16) + goto error; + + memcpy (&self->smpte_universal_label_locator, tag_data, 16); + GST_DEBUG (" SMPTE universal label locator = %s", + mxf_ul_to_string (&self->smpte_universal_label_locator, str)); + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_name_value_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 name-value local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_dms1_name_value_init (MXFDMS1NameValue * self) +{ +} + +static void +mxf_dms1_name_value_class_init (MXFDMS1NameValueClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_name_value_finalize; + metadatabase_class->handle_tag = mxf_dms1_name_value_handle_tag; +} + +G_DEFINE_TYPE (MXFDMS1Processing, mxf_dms1_processing, MXF_TYPE_DMS1); + +static void +mxf_dms1_processing_finalize (GstMiniObject * object) +{ + MXFDMS1Processing *self = MXF_DMS1_PROCESSING (object); + + g_free (self->descriptive_comment); + self->descriptive_comment = NULL; + + g_free (self->graphic_usage_type); + self->graphic_usage_type = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_processing_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_processing_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1Processing *self = MXF_DMS1_PROCESSING (metadata); + gboolean ret = TRUE; + MXFUL *tag_ul = NULL; + static const guint8 quality_flag_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x05, + 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 descriptive_comment_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x03, + 0x02, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00 + }; + static const guint8 logo_flag_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x05, + 0x01, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 graphic_usage_type_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x05, + 0x01, 0x01, 0x07, 0x01, 0x00, 0x00, 0x00 + }; + static const guint8 process_steps_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x05, + 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 generation_copy_number_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x05, + 0x01, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00 + }; + static const guint8 generation_clone_number_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x05, + 0x01, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &quality_flag_ul, 16) == 0) { + if (tag_size != 1) + goto error; + + self->quality_flag = GST_READ_UINT8 (tag_data); + GST_DEBUG (" quality flag = %u", self->quality_flag); + } else if (memcmp (tag_ul, &descriptive_comment_ul, 16) == 0) { + self->descriptive_comment = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" descriptive comment = %s", + GST_STR_NULL (self->descriptive_comment)); + } else if (memcmp (tag_ul, &logo_flag_ul, 16) == 0) { + if (tag_size != 1) + goto error; + + self->logo_flag = GST_READ_UINT8 (tag_data); + GST_DEBUG (" logo flag = %u", self->logo_flag); + } else if (memcmp (tag_ul, &graphic_usage_type_ul, 16) == 0) { + self->graphic_usage_type = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" graphic usage type = %s", + GST_STR_NULL (self->graphic_usage_type)); + } else if (memcmp (tag_ul, &process_steps_ul, 16) == 0) { + if (tag_size != 2) + goto error; + + self->process_steps = GST_READ_UINT16_BE (tag_data); + GST_DEBUG (" process steps = %u", self->process_steps); + } else if (memcmp (tag_ul, &generation_copy_number_ul, 16) == 0) { + if (tag_size != 2) + goto error; + + self->generation_copy_number = GST_READ_UINT16_BE (tag_data); + GST_DEBUG (" generation copy number = %u", self->generation_copy_number); + } else if (memcmp (tag_ul, &generation_clone_number_ul, 16) == 0) { + if (tag_size != 2) + goto error; + + self->generation_clone_number = GST_READ_UINT16_BE (tag_data); + GST_DEBUG (" generation clone number = %u", self->generation_clone_number); + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_processing_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 processing local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_dms1_processing_init (MXFDMS1Processing * self) +{ +} + +static void +mxf_dms1_processing_class_init (MXFDMS1ProcessingClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_processing_finalize; + metadatabase_class->handle_tag = mxf_dms1_processing_handle_tag; +} + +G_DEFINE_TYPE (MXFDMS1Project, mxf_dms1_project, MXF_TYPE_DMS1); + +static void +mxf_dms1_project_finalize (GstMiniObject * object) +{ + MXFDMS1Project *self = MXF_DMS1_PROJECT (object); + + g_free (self->project_name_or_title); + self->project_name_or_title = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_project_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_project_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer, + guint16 tag, const guint8 * tag_data, guint tag_size) +{ + MXFDMS1Project *self = MXF_DMS1_PROJECT (metadata); + gboolean ret = TRUE; + MXFUL *tag_ul = NULL; + static const guint8 project_number_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, 0x01, + 0x03, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00 + }; + static const guint8 project_name_or_title_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x01, + 0x03, 0x01, 0x08, 0x01, 0x00, 0x00, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &project_number_ul, 16) == 0) { + if (tag_size > 32) + goto error; + + memcpy (self->project_number, tag_data, tag_size); + + GST_DEBUG (" project number = %s", self->project_number); + } else if (memcmp (tag_ul, &project_name_or_title_ul, 16) == 0) { + self->project_name_or_title = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" project name or title = %s", + GST_STR_NULL (self->project_name_or_title)); + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_project_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 project local tag 0x%04x of size %u", tag, tag_size); + + return FALSE; +} + +static void +mxf_dms1_project_init (MXFDMS1Project * self) +{ +} + +static void +mxf_dms1_project_class_init (MXFDMS1ProjectClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_project_finalize; + metadatabase_class->handle_tag = mxf_dms1_project_handle_tag; +} + +G_DEFINE_TYPE (MXFDMS1ContactsList, mxf_dms1_contacts_list, MXF_TYPE_DMS1); + +static void +mxf_dms1_contacts_list_finalize (GstMiniObject * object) +{ + MXFDMS1ContactsList *self = MXF_DMS1_CONTACTS_LIST (object); + + g_free (self->person_sets_uids); + self->person_sets_uids = NULL; + + g_free (self->person_sets); + self->person_sets = NULL; + + g_free (self->organisation_sets_uids); + self->organisation_sets_uids = NULL; + + g_free (self->organisation_sets); + self->organisation_sets = NULL; + + g_free (self->location_sets_uids); + self->location_sets_uids = NULL; + + g_free (self->location_sets); + self->location_sets = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_contacts_list_parent_class)->finalize + (object); +} + +static gboolean +mxf_dms1_contacts_list_resolve (MXFMetadataBase * m, + MXFMetadataBase ** metadata) +{ + MXFDMS1ContactsList *self = MXF_DMS1_CONTACTS_LIST (m); + MXFMetadataBase **p = metadata, *current = NULL; + guint i; + + self->person_sets = g_new0 (MXFDMS1Person *, self->n_person_sets); + self->organisation_sets = + g_new0 (MXFDMS1Organisation *, self->n_organisation_sets); + self->location_sets = g_new0 (MXFDMS1Location *, self->n_location_sets); + + while (*p) { + current = *p; + + if (MXF_IS_DMS1_PERSON (current)) { + for (i = 0; i < self->n_person_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->person_sets_uids[i])) { + self->person_sets[i] = MXF_DMS1_PERSON (current); + break; + } + } + } + + if (MXF_IS_DMS1_ORGANISATION (current)) { + for (i = 0; i < self->n_organisation_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->organisation_sets_uids[i])) { + self->organisation_sets[i] = MXF_DMS1_ORGANISATION (current); + break; + } + } + } + + if (MXF_IS_DMS1_LOCATION (current)) { + for (i = 0; i < self->n_location_sets; i++) { + if (mxf_ul_is_equal (¤t->instance_uid, + &self->location_sets_uids[i])) { + self->location_sets[i] = MXF_DMS1_LOCATION (current); + break; + } + } + } + + p++; + } + + return + MXF_METADATA_BASE_CLASS (mxf_dms1_contacts_list_parent_class)->resolve (m, + metadata); +} + +static gboolean +mxf_dms1_contacts_list_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1ContactsList *self = MXF_DMS1_CONTACTS_LIST (metadata); + gboolean ret = TRUE; +#ifndef GST_DISABLE_GST_DEBUG + gchar str[48]; +#endif + MXFUL *tag_ul = NULL; + static const guint8 person_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x03, 0x40, 0x14, 0x00 + }; + static const guint8 organisation_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x03, 0x40, 0x15, 0x00 + }; + static const guint8 location_sets_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06, + 0x01, 0x01, 0x04, 0x03, 0x40, 0x16, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &person_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of person sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_person_sets = len; + self->person_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->person_sets_uids[i], tag_data, 16); + GST_DEBUG (" person sets %u = %s", i, + mxf_ul_to_string (&self->person_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &organisation_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of organisation sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_organisation_sets = len; + self->organisation_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->organisation_sets_uids[i], tag_data, 16); + GST_DEBUG (" organisation sets %u = %s", i, + mxf_ul_to_string (&self->organisation_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else if (memcmp (tag_ul, &location_sets_ul, 16) == 0) { + guint32 len, i; + + len = GST_READ_UINT32_BE (tag_data); + GST_DEBUG (" number of location sets = %u", len); + if (len == 0) + return ret; + + if (GST_READ_UINT32_BE (tag_data + 4) != 16) + goto error; + tag_data += 8; + tag_size -= 8; + + if (tag_size < 16 * len) + goto error; + + self->n_location_sets = len; + self->location_sets_uids = g_new0 (MXFUL, len); + + for (i = 0; i < len; i++) { + memcpy (&self->location_sets_uids[i], tag_data, 16); + GST_DEBUG (" location sets %u = %s", i, + mxf_ul_to_string (&self->location_sets_uids[i], str)); + tag_data += 16; + tag_size -= 16; + } + } else { + ret = + MXF_METADATA_BASE_CLASS + (mxf_dms1_contacts_list_parent_class)->handle_tag (metadata, primer, + tag, tag_data, tag_size); + } + + return ret; + +error: + + GST_ERROR ("Invalid DMS1 contacts list local tag 0x%04x of size %u", tag, + tag_size); + + return FALSE; +} + +static void +mxf_dms1_contacts_list_init (MXFDMS1ContactsList * self) +{ +} + +static void +mxf_dms1_contacts_list_class_init (MXFDMS1ContactsListClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_contacts_list_finalize; + metadatabase_class->handle_tag = mxf_dms1_contacts_list_handle_tag; + metadatabase_class->resolve = mxf_dms1_contacts_list_resolve; +} + +G_DEFINE_TYPE (MXFDMS1CueWords, mxf_dms1_cue_words, + MXF_TYPE_DMS1_TEXT_LANGUAGE); + +static void +mxf_dms1_cue_words_finalize (GstMiniObject * object) +{ + MXFDMS1CueWords *self = MXF_DMS1_CUE_WORDS (object); + + g_free (self->in_cue_words); + self->in_cue_words = NULL; + + g_free (self->out_cue_words); + self->out_cue_words = NULL; + + GST_MINI_OBJECT_CLASS (mxf_dms1_cue_words_parent_class)->finalize (object); +} + +static gboolean +mxf_dms1_cue_words_handle_tag (MXFMetadataBase * metadata, + MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, + guint tag_size) +{ + MXFDMS1CueWords *self = MXF_DMS1_CUE_WORDS (metadata); + gboolean ret = TRUE; + MXFUL *tag_ul = NULL; + static const guint8 in_cue_words_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x03, + 0x02, 0x01, 0x02, 0x0d, 0x01, 0x00, 0x00 + }; + static const guint8 out_cue_words_ul[] = { + 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x03, + 0x02, 0x01, 0x02, 0x0e, 0x01, 0x00, 0x00 + }; + + if (!(tag_ul = + (MXFUL *) g_hash_table_lookup (primer->mappings, + GUINT_TO_POINTER (((guint) tag))))) + return FALSE; + + if (memcmp (tag_ul, &in_cue_words_ul, 16) == 0) { + self->in_cue_words = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" in cue words = %s", GST_STR_NULL (self->in_cue_words)); + } else if (memcmp (tag_ul, &out_cue_words_ul, 16) == 0) { + self->out_cue_words = mxf_utf16_to_utf8 (tag_data, tag_size); + GST_DEBUG (" out cue words = %s", GST_STR_NULL (self->out_cue_words)); + } else { + ret = + MXF_METADATA_BASE_CLASS (mxf_dms1_cue_words_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); + } + + return ret; +} + +static void +mxf_dms1_cue_words_init (MXFDMS1CueWords * self) +{ +} + +static void +mxf_dms1_cue_words_class_init (MXFDMS1CueWordsClass * klass) +{ + GstMiniObjectClass *miniobject_class = (GstMiniObjectClass *) klass; + MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass; + + miniobject_class->finalize = mxf_dms1_cue_words_finalize; + metadatabase_class->handle_tag = mxf_dms1_cue_words_handle_tag; +} + +#define ADD_SET(ID, TYPE) \ + set = g_slice_new (MXFDescriptiveMetadataSet); \ + set->id = ID; \ + set->type = TYPE; \ + dms1_sets = g_slist_prepend (dms1_sets, set); + +void +mxf_dms1_initialize (void) +{ + GSList *dms1_sets = NULL; + MXFDescriptiveMetadataSet *set; + + ADD_SET (0x000000, MXF_TYPE_DMS1); + /* SMPTE S380M Table 3 */ + ADD_SET (0x010100, MXF_TYPE_DMS1_PRODUCTION_FRAMEWORK); + ADD_SET (0x010200, MXF_TYPE_DMS1_CLIP_FRAMEWORK); + ADD_SET (0x010300, MXF_TYPE_DMS1_SCENE_FRAMEWORK); + ADD_SET (0x100100, MXF_TYPE_DMS1_TITLES); + ADD_SET (0x110100, MXF_TYPE_DMS1_IDENTIFICATION); + ADD_SET (0x120100, MXF_TYPE_DMS1_GROUP_RELATIONSHIP); + ADD_SET (0x130100, MXF_TYPE_DMS1_BRANDING); + ADD_SET (0x140100, MXF_TYPE_DMS1_EVENT); + ADD_SET (0x140200, MXF_TYPE_DMS1_PUBLICATION); + ADD_SET (0x150100, MXF_TYPE_DMS1_AWARD); + ADD_SET (0x160100, MXF_TYPE_DMS1_CAPTIONS_DESCRIPTION); + ADD_SET (0x170100, MXF_TYPE_DMS1_ANNOTATION); + ADD_SET (0x170200, MXF_TYPE_DMS1_SETTING_PERIOD); + ADD_SET (0x170300, MXF_TYPE_DMS1_SCRIPTING); + ADD_SET (0x170400, MXF_TYPE_DMS1_CLASSIFICATION); + ADD_SET (0x170500, MXF_TYPE_DMS1_SHOT); + ADD_SET (0x170600, MXF_TYPE_DMS1_KEY_POINT); + ADD_SET (0x180100, MXF_TYPE_DMS1_PARTICIPANT); + ADD_SET (0x1a0200, MXF_TYPE_DMS1_PERSON); + ADD_SET (0x1a0300, MXF_TYPE_DMS1_ORGANISATION); + ADD_SET (0x1a0400, MXF_TYPE_DMS1_LOCATION); + ADD_SET (0x1b0100, MXF_TYPE_DMS1_ADDRESS); + ADD_SET (0x1b0200, MXF_TYPE_DMS1_COMMUNICATIONS); + ADD_SET (0x1c0100, MXF_TYPE_DMS1_CONTRACT); + ADD_SET (0x1c0200, MXF_TYPE_DMS1_RIGHTS); + ADD_SET (0x1d0100, MXF_TYPE_DMS1_PICTURE_FORMAT); + ADD_SET (0x1e0100, MXF_TYPE_DMS1_DEVICE_PARAMETERS); + ADD_SET (0x1f0100, MXF_TYPE_DMS1_NAME_VALUE); + ADD_SET (0x200100, MXF_TYPE_DMS1_PROCESSING); + ADD_SET (0x200200, MXF_TYPE_DMS1_PROJECT); + ADD_SET (0x190100, MXF_TYPE_DMS1_CONTACTS_LIST); + ADD_SET (0x170800, MXF_TYPE_DMS1_CUE_WORDS); + + mxf_descriptive_metadata_register (0x01, dms1_sets); +} + +#undef ADD_SET diff --git a/gst/mxf/mxfdms1.h b/gst/mxf/mxfdms1.h index d4f1fb0d..a3be035c 100644 --- a/gst/mxf/mxfdms1.h +++ b/gst/mxf/mxfdms1.h @@ -17,11 +17,917 @@ * Boston, MA 02111-1307, USA. */ -/* Implementation of SMPTE S380M - Descriptive Metadata Scheme-1 */ +/* Implementation of SMPTE S380M - Descriptive Scheme-1 */ -#ifndef __MXF_DMS1_H__ -#define __MXF_DMS1_H__ +#ifndef _MXF_DMS1_H_ +#define _MXF_DMS1_H_ +#include <gst/gst.h> +#include "mxfmetadata.h" +#define MXF_TYPE_DMS1 \ + (mxf_dms1_get_type()) +#define MXF_DMS1(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1, MXFDMS1)) +#define MXF_IS_DMS1(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1)) +typedef struct _MXFDMS1 MXFDMS1; +typedef MXFDescriptiveMetadataClass MXFDMS1Class; +GType mxf_dms1_get_type (void); -#endif /* __MXF_DMS1_H__ */ +#define MXF_TYPE_DMS1_TEXT_LANGUAGE \ + (mxf_dms1_text_language_get_type()) +#define MXF_DMS1_TEXT_LANGUAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_TEXT_LANGUAGE, MXFDMS1TextLanguage)) +#define MXF_IS_DMS1_TEXT_LANGUAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_TEXT_LANGUAGE)) +typedef struct _MXFDMS1TextLanguage MXFDMS1TextLanguage; +typedef MXFDescriptiveMetadataClass MXFDMS1TextLanguageClass; +GType mxf_dms1_text_language_get_type (void); + +#define MXF_TYPE_DMS1_THESAURUS \ + (mxf_dms1_thesaurus_get_type()) +#define MXF_DMS1_THESAURUS(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_THESAURUS, MXFDMS1Thesaurus)) +#define MXF_IS_DMS1_THESAURUS(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_THESAURUS)) +typedef struct _MXFDMS1Thesaurus MXFDMS1Thesaurus; +typedef MXFDescriptiveMetadataClass MXFDMS1ThesaurusClass; +GType mxf_dms1_thesaurus_get_type (void); + +#define MXF_TYPE_DMS1_FRAMEWORK \ + (mxf_dms1_framework_get_type()) +#define MXF_DMS1_FRAMEWORK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_FRAMEWORK, MXFDMS1Framework)) +#define MXF_IS_DMS1_FRAMEWORK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_FRAMEWORK)) +typedef struct _MXFDMS1Framework MXFDMS1Framework; +typedef MXFDescriptiveMetadataClass MXFDMS1FrameworkClass; +GType mxf_dms1_framework_get_type (void); + +#define MXF_TYPE_DMS1_PRODUCTION_CLIP_FRAMEWORK \ + (mxf_dms1_production_clip_framework_get_type()) +#define MXF_DMS1_PRODUCTION_CLIP_FRAMEWORK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_PRODUCTION_CLIP_FRAMEWORK, MXFDMS1ProductionClipFramework)) +#define MXF_IS_DMS1_PRODUCTION_CLIP_FRAMEWORK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_PRODUCTION_CLIP_FRAMEWORK)) +typedef struct _MXFDMS1ProductionClipFramework MXFDMS1ProductionClipFramework; +typedef MXFDescriptiveMetadataClass MXFDMS1ProductionClipFrameworkClass; +GType mxf_dms1_production_clip_framework_get_type (void); + +#define MXF_TYPE_DMS1_PRODUCTION_FRAMEWORK \ + (mxf_dms1_production_framework_get_type()) +#define MXF_DMS1_PRODUCTION_FRAMEWORK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_PRODUCTION_FRAMEWORK, MXFDMS1ProductionFramework)) +#define MXF_IS_DMS1_PRODUCTION_FRAMEWORK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_PRODUCTION_FRAMEWORK)) +typedef struct _MXFDMS1ProductionFramework MXFDMS1ProductionFramework; +typedef MXFDescriptiveMetadataClass MXFDMS1ProductionFrameworkClass; +GType mxf_dms1_production_framework_get_type (void); + +#define MXF_TYPE_DMS1_CLIP_FRAMEWORK \ + (mxf_dms1_clip_framework_get_type()) +#define MXF_DMS1_CLIP_FRAMEWORK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_CLIP_FRAMEWORK, MXFDMS1ClipFramework)) +#define MXF_IS_DMS1_CLIP_FRAMEWORK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_CLIP_FRAMEWORK)) +typedef struct _MXFDMS1ClipFramework MXFDMS1ClipFramework; +typedef MXFDescriptiveMetadataClass MXFDMS1ClipFrameworkClass; +GType mxf_dms1_clip_framework_get_type (void); + +#define MXF_TYPE_DMS1_SCENE_FRAMEWORK \ + (mxf_dms1_scene_framework_get_type()) +#define MXF_DMS1_SCENE_FRAMEWORK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_SCENE_FRAMEWORK, MXFDMS1SceneFramework)) +#define MXF_IS_DMS1_SCENE_FRAMEWORK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_SCENE_FRAMEWORK)) +typedef struct _MXFDMS1SceneFramework MXFDMS1SceneFramework; +typedef MXFDescriptiveMetadataClass MXFDMS1SceneFrameworkClass; +GType mxf_dms1_scene_framework_get_type (void); + +#define MXF_TYPE_DMS1_TITLES \ + (mxf_dms1_titles_get_type()) +#define MXF_DMS1_TITLES(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_TITLES, MXFDMS1Titles)) +#define MXF_IS_DMS1_TITLES(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_TITLES)) +typedef struct _MXFDMS1Titles MXFDMS1Titles; +typedef MXFDescriptiveMetadataClass MXFDMS1TitlesClass; +GType mxf_dms1_titles_get_type (void); + +#define MXF_TYPE_DMS1_IDENTIFICATION \ + (mxf_dms1_identification_get_type()) +#define MXF_DMS1_IDENTIFICATION(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_IDENTIFICATION, MXFDMS1Identification)) +#define MXF_IS_DMS1_IDENTIFICATION(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_IDENTIFICATION)) +typedef struct _MXFDMS1Identification MXFDMS1Identification; +typedef MXFDescriptiveMetadataClass MXFDMS1IdentificationClass; +GType mxf_dms1_identification_get_type (void); + +#define MXF_TYPE_DMS1_GROUP_RELATIONSHIP \ + (mxf_dms1_group_relationship_get_type()) +#define MXF_DMS1_GROUP_RELATIONSHIP(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_GROUP_RELATIONSHIP, MXFDMS1GroupRelationship)) +#define MXF_IS_DMS1_GROUP_RELATIONSHIP(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_GROUP_RELATIONSHIP)) +typedef struct _MXFDMS1GroupRelationship MXFDMS1GroupRelationship; +typedef MXFDescriptiveMetadataClass MXFDMS1GroupRelationshipClass; +GType mxf_dms1_group_relationship_get_type (void); + +#define MXF_TYPE_DMS1_BRANDING \ + (mxf_dms1_branding_get_type()) +#define MXF_DMS1_BRANDING(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_BRANDING, MXFDMS1Branding)) +#define MXF_IS_DMS1_BRANDING(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_BRANDING)) +typedef struct _MXFDMS1Branding MXFDMS1Branding; +typedef MXFDescriptiveMetadataClass MXFDMS1BrandingClass; +GType mxf_dms1_branding_get_type (void); + +#define MXF_TYPE_DMS1_EVENT \ + (mxf_dms1_event_get_type()) +#define MXF_DMS1_EVENT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_EVENT, MXFDMS1Event)) +#define MXF_IS_DMS1_EVENT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_EVENT)) +typedef struct _MXFDMS1Event MXFDMS1Event; +typedef MXFDescriptiveMetadataClass MXFDMS1EventClass; +GType mxf_dms1_event_get_type (void); + +#define MXF_TYPE_DMS1_PUBLICATION \ + (mxf_dms1_publication_get_type()) +#define MXF_DMS1_PUBLICATION(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_PUBLICATION, MXFDMS1Publication)) +#define MXF_IS_DMS1_PUBLICATION(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_PUBLICATION)) +typedef struct _MXFDMS1Publication MXFDMS1Publication; +typedef MXFDescriptiveMetadataClass MXFDMS1PublicationClass; +GType mxf_dms1_publication_get_type (void); + +#define MXF_TYPE_DMS1_AWARD \ + (mxf_dms1_award_get_type()) +#define MXF_DMS1_AWARD(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_AWARD, MXFDMS1Award)) +#define MXF_IS_DMS1_AWARD(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_AWARD)) +typedef struct _MXFDMS1Award MXFDMS1Award; +typedef MXFDescriptiveMetadataClass MXFDMS1AwardClass; +GType mxf_dms1_award_get_type (void); + +#define MXF_TYPE_DMS1_CAPTIONS_DESCRIPTION \ + (mxf_dms1_captions_description_get_type()) +#define MXF_DMS1_CAPTIONS_DESCRIPTION(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_CAPTIONS_DESCRIPTION, MXFDMS1CaptionsDescription)) +#define MXF_IS_DMS1_CAPTIONS_DESCRIPTION(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_CAPTIONS_DESCRIPTION)) +typedef struct _MXFDMS1CaptionsDescription MXFDMS1CaptionsDescription; +typedef MXFDescriptiveMetadataClass MXFDMS1CaptionsDescriptionClass; +GType mxf_dms1_captions_description_get_type (void); + +#define MXF_TYPE_DMS1_ANNOTATION \ + (mxf_dms1_annotation_get_type()) +#define MXF_DMS1_ANNOTATION(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_ANNOTATION, MXFDMS1Annotation)) +#define MXF_IS_DMS1_ANNOTATION(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_ANNOTATION)) +typedef struct _MXFDMS1Annotation MXFDMS1Annotation; +typedef MXFDescriptiveMetadataClass MXFDMS1AnnotationClass; +GType mxf_dms1_annotation_get_type (void); + +#define MXF_TYPE_DMS1_SETTING_PERIOD \ + (mxf_dms1_setting_period_get_type()) +#define MXF_DMS1_SETTING_PERIOD(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_SETTING_PERIOD, MXFDMS1SettingPeriod)) +#define MXF_IS_DMS1_SETTING_PERIOD(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_SETTING_PERIOD)) +typedef struct _MXFDMS1SettingPeriod MXFDMS1SettingPeriod; +typedef MXFDescriptiveMetadataClass MXFDMS1SettingPeriodClass; +GType mxf_dms1_setting_period_get_type (void); + +#define MXF_TYPE_DMS1_SCRIPTING \ + (mxf_dms1_scripting_get_type()) +#define MXF_DMS1_SCRIPTING(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_SCRIPTING, MXFDMS1Scripting)) +#define MXF_IS_DMS1_SCRIPTING(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_SCRIPTING)) +typedef struct _MXFDMS1Scripting MXFDMS1Scripting; +typedef MXFDescriptiveMetadataClass MXFDMS1ScriptingClass; +GType mxf_dms1_scripting_get_type (void); + +#define MXF_TYPE_DMS1_CLASSIFICATION \ + (mxf_dms1_classification_get_type()) +#define MXF_DMS1_CLASSIFICATION(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_CLASSIFICATION, MXFDMS1Classification)) +#define MXF_IS_DMS1_CLASSIFICATION(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_CLASSIFICATION)) +typedef struct _MXFDMS1Classification MXFDMS1Classification; +typedef MXFDescriptiveMetadataClass MXFDMS1ClassificationClass; +GType mxf_dms1_classification_get_type (void); + +#define MXF_TYPE_DMS1_SHOT \ + (mxf_dms1_shot_get_type()) +#define MXF_DMS1_SHOT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_SHOT, MXFDMS1Shot)) +#define MXF_IS_DMS1_SHOT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_SHOT)) +typedef struct _MXFDMS1Shot MXFDMS1Shot; +typedef MXFDescriptiveMetadataClass MXFDMS1ShotClass; +GType mxf_dms1_shot_get_type (void); + +#define MXF_TYPE_DMS1_KEY_POINT \ + (mxf_dms1_key_point_get_type()) +#define MXF_DMS1_KEY_POINT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_KEY_POINT, MXFDMS1KeyPoint)) +#define MXF_IS_DMS1_KEY_POINT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_KEY_POINT)) +typedef struct _MXFDMS1KeyPoint MXFDMS1KeyPoint; +typedef MXFDescriptiveMetadataClass MXFDMS1KeyPointClass; +GType mxf_dms1_key_point_get_type (void); + +#define MXF_TYPE_DMS1_PARTICIPANT \ + (mxf_dms1_participant_get_type()) +#define MXF_DMS1_PARTICIPANT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_PARTICIPANT, MXFDMS1Participant)) +#define MXF_IS_DMS1_PARTICIPANT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_PARTICIPANT)) +typedef struct _MXFDMS1Participant MXFDMS1Participant; +typedef MXFDescriptiveMetadataClass MXFDMS1ParticipantClass; +GType mxf_dms1_participant_get_type (void); + +#define MXF_TYPE_DMS1_CONTACT \ + (mxf_dms1_contact_get_type()) +#define MXF_DMS1_CONTACT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_CONTACT, MXFDMS1Contact)) +#define MXF_IS_DMS1_CONTACT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_CONTACT)) +typedef struct _MXFDMS1Contact MXFDMS1Contact; +typedef MXFDescriptiveMetadataClass MXFDMS1ContactClass; +GType mxf_dms1_contact_get_type (void); + +#define MXF_TYPE_DMS1_PERSON \ + (mxf_dms1_person_get_type()) +#define MXF_DMS1_PERSON(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_PERSON, MXFDMS1Person)) +#define MXF_IS_DMS1_PERSON(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_PERSON)) +typedef struct _MXFDMS1Person MXFDMS1Person; +typedef MXFDescriptiveMetadataClass MXFDMS1PersonClass; +GType mxf_dms1_person_get_type (void); + +#define MXF_TYPE_DMS1_ORGANISATION \ + (mxf_dms1_organisation_get_type()) +#define MXF_DMS1_ORGANISATION(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_ORGANISATION, MXFDMS1Organisation)) +#define MXF_IS_DMS1_ORGANISATION(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_ORGANISATION)) +typedef struct _MXFDMS1Organisation MXFDMS1Organisation; +typedef MXFDescriptiveMetadataClass MXFDMS1OrganisationClass; +GType mxf_dms1_organisation_get_type (void); + +#define MXF_TYPE_DMS1_LOCATION \ + (mxf_dms1_location_get_type()) +#define MXF_DMS1_LOCATION(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_LOCATION, MXFDMS1Location)) +#define MXF_IS_DMS1_LOCATION(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_LOCATION)) +typedef struct _MXFDMS1Location MXFDMS1Location; +typedef MXFDescriptiveMetadataClass MXFDMS1LocationClass; +GType mxf_dms1_location_get_type (void); + +#define MXF_TYPE_DMS1_ADDRESS \ + (mxf_dms1_address_get_type()) +#define MXF_DMS1_ADDRESS(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_ADDRESS, MXFDMS1Address)) +#define MXF_IS_DMS1_ADDRESS(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_ADDRESS)) +typedef struct _MXFDMS1Address MXFDMS1Address; +typedef MXFDescriptiveMetadataClass MXFDMS1AddressClass; +GType mxf_dms1_address_get_type (void); + +#define MXF_TYPE_DMS1_COMMUNICATIONS \ + (mxf_dms1_communications_get_type()) +#define MXF_DMS1_COMMUNICATIONS(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_COMMUNICATIONS, MXFDMS1Communications)) +#define MXF_IS_DMS1_COMMUNICATIONS(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_COMMUNICATIONS)) +typedef struct _MXFDMS1Communications MXFDMS1Communications; +typedef MXFDescriptiveMetadataClass MXFDMS1CommunicationsClass; +GType mxf_dms1_communications_get_type (void); + +#define MXF_TYPE_DMS1_CONTRACT \ + (mxf_dms1_contract_get_type()) +#define MXF_DMS1_CONTRACT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_CONTRACT, MXFDMS1Contract)) +#define MXF_IS_DMS1_CONTRACT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_CONTRACT)) +typedef struct _MXFDMS1Contract MXFDMS1Contract; +typedef MXFDescriptiveMetadataClass MXFDMS1ContractClass; +GType mxf_dms1_contract_get_type (void); + +#define MXF_TYPE_DMS1_RIGHTS \ + (mxf_dms1_rights_get_type()) +#define MXF_DMS1_RIGHTS(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_RIGHTS, MXFDMS1Rights)) +#define MXF_IS_DMS1_RIGHTS(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_RIGHTS)) +typedef struct _MXFDMS1Rights MXFDMS1Rights; +typedef MXFDescriptiveMetadataClass MXFDMS1RightsClass; +GType mxf_dms1_rights_get_type (void); + +#define MXF_TYPE_DMS1_PICTURE_FORMAT \ + (mxf_dms1_picture_format_get_type()) +#define MXF_DMS1_PICTURE_FORMAT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_PICTURE_FORMAT, MXFDMS1PictureFormat)) +#define MXF_IS_DMS1_PICTURE_FORMAT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_PICTURE_FORMAT)) +typedef struct _MXFDMS1PictureFormat MXFDMS1PictureFormat; +typedef MXFDescriptiveMetadataClass MXFDMS1PictureFormatClass; +GType mxf_dms1_picture_format_get_type (void); + +#define MXF_TYPE_DMS1_DEVICE_PARAMETERS \ + (mxf_dms1_device_parameters_get_type()) +#define MXF_DMS1_DEVICE_PARAMETERS(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_DEVICE_PARAMETERS, MXFDMS1DeviceParameters)) +#define MXF_IS_DMS1_DEVICE_PARAMETERS(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_DEVICE_PARAMETERS)) +typedef struct _MXFDMS1DeviceParameters MXFDMS1DeviceParameters; +typedef MXFDescriptiveMetadataClass MXFDMS1DeviceParametersClass; +GType mxf_dms1_device_parameters_get_type (void); + +#define MXF_TYPE_DMS1_NAME_VALUE \ + (mxf_dms1_name_value_get_type()) +#define MXF_DMS1_NAME_VALUE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_NAME_VALUE, MXFDMS1NameValue)) +#define MXF_IS_DMS1_NAME_VALUE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_NAME_VALUE)) +typedef struct _MXFDMS1NameValue MXFDMS1NameValue; +typedef MXFDescriptiveMetadataClass MXFDMS1NameValueClass; +GType mxf_dms1_name_value_get_type (void); + +#define MXF_TYPE_DMS1_PROCESSING \ + (mxf_dms1_processing_get_type()) +#define MXF_DMS1_PROCESSING(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_PROCESSING, MXFDMS1Processing)) +#define MXF_IS_DMS1_PROCESSING(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_PROCESSING)) +typedef struct _MXFDMS1Processing MXFDMS1Processing; +typedef MXFDescriptiveMetadataClass MXFDMS1ProcessingClass; +GType mxf_dms1_processing_get_type (void); + +#define MXF_TYPE_DMS1_PROJECT \ + (mxf_dms1_project_get_type()) +#define MXF_DMS1_PROJECT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_PROJECT, MXFDMS1Project)) +#define MXF_IS_DMS1_PROJECT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_PROJECT)) +typedef struct _MXFDMS1Project MXFDMS1Project; +typedef MXFDescriptiveMetadataClass MXFDMS1ProjectClass; +GType mxf_dms1_project_get_type (void); + +#define MXF_TYPE_DMS1_CONTACTS_LIST \ + (mxf_dms1_contacts_list_get_type()) +#define MXF_DMS1_CONTACTS_LIST(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_CONTACTS_LIST, MXFDMS1ContactsList)) +#define MXF_IS_DMS1_CONTACTS_LIST(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_CONTACTS_LIST)) +typedef struct _MXFDMS1ContactsList MXFDMS1ContactsList; +typedef MXFDescriptiveMetadataClass MXFDMS1ContactsListClass; +GType mxf_dms1_contacts_list_get_type (void); + +#define MXF_TYPE_DMS1_CUE_WORDS \ + (mxf_dms1_cue_words_get_type()) +#define MXF_DMS1_CUE_WORDS(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DMS1_CUE_WORDS, MXFDMS1CueWords)) +#define MXF_IS_DMS1_CUE_WORDS(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DMS1_CUE_WORDS)) +typedef struct _MXFDMS1CueWords MXFDMS1CueWords; +typedef MXFDescriptiveMetadataClass MXFDMS1CueWordsClass; +GType mxf_dms1_cue_words_get_type (void); + +struct _MXFDMS1 { + MXFDescriptiveMetadata parent; +}; + +struct _MXFDMS1TextLanguage { + MXFDMS1 parent; + + gchar extended_text_language_code[13]; +}; + +struct _MXFDMS1Thesaurus { + MXFDMS1TextLanguage parent; + + gchar *thesaurus_name; +}; + +struct _MXFDMS1Framework { + MXFDMS1 parent; + + gchar framework_extended_text_language_code[13]; + gchar *framework_thesaurus_name; + gchar *framework_title; + gchar primary_extended_spoken_language_code[13]; + gchar secondary_extended_spoken_language_code[13]; + gchar original_extended_spoken_language_code[13]; + + guint32 n_metadata_server_locators; + MXFUL *metadata_server_locators_uids; + /* TODO */ + + guint32 n_titles_sets; + MXFUL *titles_sets_uids; + MXFDMS1Titles **titles_sets; + + guint32 n_annotations_sets; + MXFUL *annotations_sets_uids; + MXFDMS1Annotation **annotations_sets; + + guint32 n_participant_sets; + MXFUL *participant_sets_uids; + MXFDMS1Participant **participant_sets; + + MXFUL contacts_list_set_uid; + MXFDMS1ContactsList *contacts_list_set; + + guint32 n_location_sets; + MXFUL *location_sets_uids; + MXFDMS1Location **location_sets; +}; + +struct _MXFDMS1ProductionClipFramework { + MXFDMS1Framework parent; + + MXFUL picture_format_set_uid; + MXFDMS1PictureFormat *picture_format; + + guint32 n_captions_description_sets; + MXFUL *captions_description_sets_uids; + MXFDMS1CaptionsDescription **captions_description_sets; + + guint32 n_contract_sets; + MXFUL *contract_sets_uids; + MXFDMS1Contract **contract_sets; + + MXFUL project_set_uid; + MXFDMS1Project *project_set; +}; + +struct _MXFDMS1ProductionFramework { + MXFDMS1ProductionClipFramework parent; + + gchar *integration_indication; + + guint32 n_identification_sets; + MXFUL *identification_sets_uids; + MXFDMS1Identification **identification_sets; + + guint32 n_group_relationship_sets; + MXFUL *group_relationship_sets_uids; + MXFDMS1GroupRelationship **group_relationship_sets; + + guint32 n_branding_sets; + MXFUL *branding_sets_uids; + MXFDMS1Branding **branding_sets; + + guint32 n_event_sets; + MXFUL *event_sets_uids; + MXFDMS1Event **event_sets; + + guint32 n_award_sets; + MXFUL *award_sets_uids; + MXFDMS1Award **award_sets; + + guint32 n_setting_period_sets; + MXFUL *setting_period_sets_uids; + MXFDMS1SettingPeriod **setting_period_sets; +}; + +struct _MXFDMS1ClipFramework { + MXFDMS1ProductionClipFramework parent; + + gchar *clip_kind; + gchar clip_number[33]; + + guint8 extended_clip_id[64]; + gboolean extended_clip_id_full; + + MXFTimestamp clip_creation_date_and_time; + + guint16 take_number; + + gchar *slate_information; + + guint32 n_scripting_sets; + MXFUL *scripting_sets_uids; + MXFDMS1Scripting **scripting_sets; + + guint32 n_shot_sets; + MXFUL *shot_sets_uids; + MXFDMS1Shot **shot_sets; + + guint32 n_device_parameters_sets; + MXFUL *device_parameters_sets_uids; + MXFDMS1DeviceParameters **device_parameters_sets; + + MXFUL processing_set_uid; + MXFDMS1Processing *processing_set; +}; + +struct _MXFDMS1SceneFramework { + MXFDMS1Framework parent; + + gchar scene_number[33]; + + guint32 n_setting_period_sets; + MXFUL *setting_period_sets_uids; + MXFDMS1SettingPeriod **setting_period_sets; + + guint32 n_shot_scene_sets; + MXFUL *shot_scene_sets_uids; + MXFDMS1Shot **shot_scene_sets; +}; + +struct _MXFDMS1Titles { + MXFDMS1TextLanguage parent; + + gchar *main_title; + gchar *secondary_title; + gchar *working_title; + gchar *original_title; + gchar *version_title; +}; + +struct _MXFDMS1Identification { + MXFDMS1Thesaurus parent; + + gchar identifier_kind[33]; + guint8 *identifier_value; + guint16 identifier_value_length; + MXFUL identification_locator; + gchar *identification_issuing_authority; +}; + +struct _MXFDMS1GroupRelationship { + MXFDMS1Thesaurus parent; + + gchar *programming_group_kind; + gchar* programming_group_title; + gchar *group_synopsis; + guint32 numerical_position_in_sequence; + guint32 total_number_in_the_sequence; + guint16 episodic_start_number; + guint16 episodic_end_number; +}; + +struct _MXFDMS1Branding { + MXFDMS1TextLanguage parent; + + gchar *brand_main_title; + gchar *brand_original_title; +}; + +struct _MXFDMS1Event { + MXFDMS1Thesaurus parent; + + gchar *event_indication; + gchar event_start_date_and_time[33]; + gchar event_end_date_and_time[33]; + + guint32 n_publication_sets; + MXFUL *publication_sets_uids; + MXFDMS1Publication **publication_sets; + + guint32 n_annotation_sets; + MXFUL *annotation_sets_uids; + MXFDMS1Annotation **annotation_sets; +}; + +struct _MXFDMS1Publication { + MXFDMS1 parent; + + gchar *publication_organisation_name; + gchar *publication_service_name; + gchar *publication_medium; + gchar *publication_region; +}; + +struct _MXFDMS1Award { + MXFDMS1Thesaurus parent; + + gchar *festival; + gchar festival_date_and_time[33]; + gchar *award_name; + gchar *award_classification; + gchar *nomination_category; + + guint32 n_participant_sets; + MXFUL *participant_sets_uids; + MXFDMS1Participant **participant_sets; +}; + +struct _MXFDMS1CaptionsDescription { + MXFDMS1Thesaurus parent; + + gchar extended_captions_language_code[13]; + gchar *caption_kind; +}; + +struct _MXFDMS1Annotation { + MXFDMS1Thesaurus parent; + + gchar *annotation_kind; + gchar *annotation_synopsis; + gchar *annotation_description; + gchar *related_material_description; + + guint32 n_classification_sets; + MXFUL *classification_sets_uids; + MXFDMS1Classification **classification_sets; + + MXFUL cue_words_set_uid; + MXFDMS1CueWords *cue_words_set; + + guint32 n_related_material_locators; + MXFUL *related_material_locators; + /* TODO */ + + guint32 n_participant_sets; + MXFUL *participant_sets_uids; + MXFDMS1Participant **participant_sets; +}; + +struct _MXFDMS1SettingPeriod { + MXFDMS1Thesaurus parent; + + MXFTimestamp setting_date_and_time; + gchar *time_period_keyword; + gchar *setting_period_description; +}; + +struct _MXFDMS1Scripting { + MXFDMS1Thesaurus parent; + + gchar *scripting_kind; + gchar *scripting_text; + + guint32 n_scripting_locators; + MXFUL *scripting_locators; + /* TODO */ +}; + +struct _MXFDMS1Classification { + MXFDMS1Thesaurus parent; + + gchar content_classification[128]; + + guint32 n_name_value_sets; + MXFUL *name_value_sets_uids; + MXFDMS1NameValue **name_value_sets; +}; + +struct _MXFDMS1Shot { + MXFDMS1TextLanguage parent; + + gint64 shot_start_position; + gint64 shot_duration; + + guint32 n_shot_track_ids; + guint32 *shot_track_ids; + + gchar *shot_description; + gchar *shot_comment_kind; + gchar *shot_comment; + + MXFUL cue_words_set_uid; + MXFDMS1CueWords *cue_words_set; + + guint32 n_key_point_sets; + MXFUL *key_point_sets_uids; + MXFDMS1KeyPoint **key_point_sets; +}; + +struct _MXFDMS1KeyPoint { + MXFDMS1Thesaurus parent; + + gchar *keypoint_kind; + gchar *keypoint_value; + gint64 keypoint_position; +}; + +struct _MXFDMS1Participant { + MXFDMS1Thesaurus parent; + + MXFUL participant_uid; + + gchar *contribution_status; + gchar *job_function; + gchar job_function_code[33]; + gchar *role_or_identity_name; + + guint32 n_person_sets; + MXFUL *person_sets_uids; + MXFDMS1Person **person_sets; + + guint32 n_organisation_sets; + MXFUL *organisation_sets_uids; + MXFDMS1Organisation **organisation_sets; +}; + +struct _MXFDMS1Contact { + MXFDMS1Thesaurus parent; + + MXFUL contact_uid; + + guint32 n_name_value_sets; + MXFUL *name_value_sets_uids; + MXFDMS1NameValue **name_value_sets; + + guint32 n_address_sets; + MXFUL *address_sets_uids; + MXFDMS1Address **address_sets; +}; + +struct _MXFDMS1Person { + MXFDMS1Contact parent; + + gchar *family_name; + gchar *first_given_name; + gchar *other_given_names; + gchar *linking_name; + gchar *salutation; + gchar *name_suffix; + gchar *honours_qualifications; + gchar *former_family_name; + gchar *person_description; + gchar *alternate_name; + gchar *nationality; + gchar *citizenship; + + guint32 n_organisation_sets; + MXFUL *organisation_sets_uids; + MXFDMS1Organisation **organisation_sets; +}; + +struct _MXFDMS1Organisation { + MXFDMS1Contact parent; + + gchar *nature_of_organisation; + gchar *organisation_main_name; + gchar *organisation_code; + gchar *contact_department; +}; + +struct _MXFDMS1Location { + MXFDMS1Contact parent; + + gchar *location_kind; + gchar *location_description; +}; + +struct _MXFDMS1Address { + MXFDMS1 parent; + + gchar *room_or_suite_number; + gchar *room_or_suite_name; + gchar *building_name; + gchar *place_name; + gchar *street_number; + gchar *street_name; + gchar *postal_town; + gchar *city; + gchar *state_or_province_or_country; + gchar *postal_code; + gchar *country; + guint8 geographical_coordinate[12]; + gchar *astronomical_body_name; + + guint32 n_communications_sets; + MXFUL *communications_sets_uids; + MXFDMS1Communications **communications_sets; + + guint32 n_name_value_sets; + MXFUL *name_value_sets_uids; + MXFDMS1NameValue **name_value_sets; +}; + +struct _MXFDMS1Communications { + MXFDMS1 parent; + + gchar central_telephone_number[33]; + gchar telephone_number[33]; + gchar mobile_telephone_number[33]; + gchar fax_number[33]; + gchar *email_address; + gchar *web_page; +}; + +struct _MXFDMS1Contract { + MXFDMS1Thesaurus parent; + + gchar supply_contract_number[33]; + + guint32 n_rights_sets; + MXFUL *rights_sets_uids; + MXFDMS1Rights **rights_sets; + + guint32 n_participant_sets; + MXFUL *participant_sets_uids; + MXFDMS1Participant **participant_sets; +}; + +struct _MXFDMS1Rights { + MXFDMS1Thesaurus parent; + + gchar *copyright_owner; + gchar *rights_holder; + gchar *rights_managment_authority; + gchar *region_or_area_of_ip_license; + gchar *intellectual_property_type; + gchar *right_condition; + gchar *right_remarks; + gchar *intellectual_property_right; + MXFTimestamp rights_start_date_and_time; + MXFTimestamp rights_stop_date_and_time; + guint16 maximum_number_of_usages; +}; + +struct _MXFDMS1PictureFormat { + MXFDMS1 parent; + + MXFFraction viewport_aspect_ratio; + gchar perceived_display_format[33]; + gchar *colour_descriptor; +}; + +struct _MXFDMS1DeviceParameters { + MXFDMS1Thesaurus parent; + + gchar *device_type; + gchar device_designation[33]; + gchar device_asset_number[33]; + guint8 ieee_device_identifier[6]; + gchar *manufacturer; + gchar *device_model; + gchar *device_serial_number; + gchar *device_usage_description; + + guint32 n_name_value_sets; + MXFUL *name_value_sets_uids; + MXFDMS1NameValue **name_value_sets; +}; + +struct _MXFDMS1NameValue { + MXFDMS1 parent; + + gchar *item_name; + gchar *item_value; + + MXFUL smpte_universal_label_locator; +}; + +struct _MXFDMS1Processing { + MXFDMS1 parent; + + gboolean quality_flag; + gchar *descriptive_comment; + gboolean logo_flag; + gchar *graphic_usage_type; + guint16 process_steps; + guint16 generation_copy_number; + guint16 generation_clone_number; +}; + +struct _MXFDMS1Project { + MXFDMS1 parent; + + gchar project_number[33]; + gchar *project_name_or_title; +}; + +struct _MXFDMS1ContactsList { + MXFDMS1 parent; + + guint32 n_person_sets; + MXFUL *person_sets_uids; + MXFDMS1Person **person_sets; + + guint32 n_organisation_sets; + MXFUL *organisation_sets_uids; + MXFDMS1Organisation **organisation_sets; + + guint32 n_location_sets; + MXFUL *location_sets_uids; + MXFDMS1Location **location_sets; +}; + +struct _MXFDMS1CueWords { + MXFDMS1TextLanguage parent; + + gchar *in_cue_words; + gchar *out_cue_words; +}; + +void mxf_dms1_initialize (void); + +#endif /* _MXF_DMS1_H_ */ diff --git a/gst/mxf/mxfjpeg2000.c b/gst/mxf/mxfjpeg2000.c index a08c426f..657777f0 100644 --- a/gst/mxf/mxfjpeg2000.c +++ b/gst/mxf/mxfjpeg2000.c @@ -106,10 +106,10 @@ mxf_jpeg2000_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, if (!track->parent.descriptor[i]) continue; - if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track->parent. - descriptor[i])) { - p = (MXFMetadataGenericPictureEssenceDescriptor *) track-> - parent.descriptor[i]; + if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track-> + parent.descriptor[i])) { + p = (MXFMetadataGenericPictureEssenceDescriptor *) track->parent. + descriptor[i]; f = track->parent.descriptor[i]; break; } else if (MXF_IS_METADATA_FILE_DESCRIPTOR (track->parent.descriptor[i]) && diff --git a/gst/mxf/mxfmetadata.c b/gst/mxf/mxfmetadata.c index 02f301a6..e0d6b5b1 100644 --- a/gst/mxf/mxfmetadata.c +++ b/gst/mxf/mxfmetadata.c @@ -114,10 +114,10 @@ mxf_metadata_base_resolve (MXFMetadataBase * self, MXFMetadataBase ** metadata) if (self->resolved == MXF_METADATA_BASE_RESOLVE_STATE_SUCCESS) return TRUE; - else if (self->resolved == MXF_METADATA_BASE_RESOLVE_STATE_FAILURE) + else if (self->resolved != MXF_METADATA_BASE_RESOLVE_STATE_NONE) return FALSE; - self->resolved = TRUE; + self->resolved = MXF_METADATA_BASE_RESOLVE_STATE_RUNNING;; klass = MXF_METADATA_BASE_GET_CLASS (self); @@ -151,6 +151,13 @@ mxf_metadata_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer, GST_DEBUG (" instance uid = %s", mxf_ul_to_string (&self->parent.instance_uid, str)); break; + case 0x0102: + 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 @@ -327,13 +334,6 @@ mxf_metadata_preface_handle_tag (MXFMetadataBase * metadata, gboolean ret = TRUE; switch (tag) { - case 0x0102: - if (tag_size != 16) - goto error; - memcpy (&self->generation_uid, tag_data, 16); - GST_DEBUG (" generation uid = %s", - mxf_ul_to_string (&self->generation_uid, str)); - break; case 0x3b02: if (!mxf_timestamp_parse (&self->last_modified_date, tag_data, tag_size)) goto error; @@ -701,13 +701,6 @@ mxf_metadata_content_storage_handle_tag (MXFMetadataBase * metadata, #endif switch (tag) { - case 0x0102: - if (tag_size != 16) - goto error; - memcpy (&self->generation_uid, tag_data, 16); - GST_DEBUG (" generation uid = %s", - mxf_ul_to_string (&self->generation_uid, str)); - break; case 0x1901:{ guint32 len; guint i; @@ -867,13 +860,6 @@ mxf_metadata_essence_container_data_handle_tag (MXFMetadataBase * metadata, #endif switch (tag) { - case 0x0102: - if (tag_size != 16) - goto error; - memcpy (&self->generation_uid, tag_data, 16); - GST_DEBUG (" generation uid = %s", - mxf_ul_to_string (&self->generation_uid, str)); - break; case 0x2701: if (tag_size != 32) goto error; @@ -996,13 +982,6 @@ mxf_metadata_generic_package_handle_tag (MXFMetadataBase * metadata, #endif switch (tag) { - case 0x0102: - if (tag_size != 16) - goto error; - memcpy (&self->generation_uid, tag_data, 16); - GST_DEBUG (" generation uid = %s", - mxf_ul_to_string (&self->generation_uid, str)); - break; case 0x4401: if (tag_size != 32) goto error; @@ -1401,13 +1380,6 @@ mxf_metadata_track_handle_tag (MXFMetadataBase * metadata, #endif switch (tag) { - case 0x0102: - if (tag_size != 16) - goto error; - memcpy (&self->generation_uid, tag_data, 16); - GST_DEBUG (" generation uid = %s", - mxf_ul_to_string (&self->generation_uid, str)); - break; case 0x4801: if (tag_size != 4) goto error; @@ -1702,13 +1674,6 @@ mxf_metadata_sequence_handle_tag (MXFMetadataBase * metadata, #endif switch (tag) { - case 0x0102: - if (tag_size != 16) - goto error; - memcpy (&self->generation_uid, tag_data, 16); - GST_DEBUG (" generation uid = %s", - mxf_ul_to_string (&self->generation_uid, str)); - break; case 0x0201: if (tag_size != 16) goto error; @@ -1837,13 +1802,6 @@ mxf_metadata_structural_component_handle_tag (MXFMetadataBase * metadata, #endif switch (tag) { - case 0x0102: - if (tag_size != 16) - goto error; - memcpy (&self->generation_uid, tag_data, 16); - GST_DEBUG (" generation uid = %s", - mxf_ul_to_string (&self->generation_uid, str)); - break; case 0x0201: if (tag_size != 16) goto error; @@ -2249,10 +2207,10 @@ mxf_metadata_dm_segment_resolve (MXFMetadataBase * m, 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_IS_DESCRIPTIVE_METADATA_FRAMEWORK (current) + && mxf_ul_is_equal (¤t->instance_uid, &self->dm_framework_uid)) { if (mxf_metadata_base_resolve (current, metadata)) { - self->dm_framework = current; + self->dm_framework = MXF_DESCRIPTIVE_METADATA_FRAMEWORK (current); } break; } @@ -2318,13 +2276,6 @@ mxf_metadata_generic_descriptor_handle_tag (MXFMetadataBase * metadata, #endif switch (tag) { - case 0x0102: - if (tag_size != 16) - goto error; - memcpy (&self->generation_uid, tag_data, 16); - GST_DEBUG (" generation uid = %s", - mxf_ul_to_string (&self->generation_uid, str)); - break; case 0x2f01:{ guint32 len; guint i; @@ -2681,8 +2632,8 @@ mxf_metadata_generic_picture_essence_descriptor_handle_tag (MXFMetadataBase * default: ret = MXF_METADATA_BASE_CLASS - (mxf_metadata_generic_picture_essence_descriptor_parent_class)-> - handle_tag (metadata, primer, tag, tag_data, tag_size); + (mxf_metadata_generic_picture_essence_descriptor_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); break; } @@ -2835,8 +2786,8 @@ mxf_metadata_generic_sound_essence_descriptor_handle_tag (MXFMetadataBase * default: ret = MXF_METADATA_BASE_CLASS - (mxf_metadata_generic_sound_essence_descriptor_parent_class)-> - handle_tag (metadata, primer, tag, tag_data, tag_size); + (mxf_metadata_generic_sound_essence_descriptor_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); break; } @@ -2970,8 +2921,8 @@ mxf_metadata_cdci_picture_essence_descriptor_handle_tag (MXFMetadataBase * default: ret = MXF_METADATA_BASE_CLASS - (mxf_metadata_cdci_picture_essence_descriptor_parent_class)-> - handle_tag (metadata, primer, tag, tag_data, tag_size); + (mxf_metadata_cdci_picture_essence_descriptor_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); break; } @@ -3096,8 +3047,8 @@ mxf_metadata_rgba_picture_essence_descriptor_handle_tag (MXFMetadataBase * default: ret = MXF_METADATA_BASE_CLASS - (mxf_metadata_rgba_picture_essence_descriptor_parent_class)-> - handle_tag (metadata, primer, tag, tag_data, tag_size); + (mxf_metadata_rgba_picture_essence_descriptor_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); break; } @@ -3160,8 +3111,8 @@ mxf_metadata_generic_data_essence_descriptor_handle_tag (MXFMetadataBase * default: ret = MXF_METADATA_BASE_CLASS - (mxf_metadata_generic_data_essence_descriptor_parent_class)-> - handle_tag (metadata, primer, tag, tag_data, tag_size); + (mxf_metadata_generic_data_essence_descriptor_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); break; } @@ -3331,41 +3282,6 @@ mxf_metadata_multiple_descriptor_class_init (MXFMetadataMultipleDescriptorClass G_DEFINE_ABSTRACT_TYPE (MXFMetadataLocator, mxf_metadata_locator, MXF_TYPE_METADATA); -static gboolean -mxf_metadata_locator_handle_tag (MXFMetadataBase * metadata, - MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data, - guint tag_size) -{ - MXFMetadataLocator *self = MXF_METADATA_LOCATOR (metadata); - gboolean ret = TRUE; -#ifndef GST_DISABLE_GST_DEBUG - gchar str[48]; -#endif - - switch (tag) { - case 0x0102: - if (tag_size != 16) - goto error; - memcpy (&self->generation_uid, tag_data, 16); - GST_DEBUG (" generation uid = %s", - mxf_ul_to_string (&self->generation_uid, str)); - break; - default: - ret = - MXF_METADATA_BASE_CLASS - (mxf_metadata_locator_parent_class)->handle_tag (metadata, - primer, tag, tag_data, tag_size); - break; - } - - return ret; - -error: - GST_ERROR ("Invalid locator local tag 0x%04x of size %u", tag, tag_size); - - return FALSE; -} - static void mxf_metadata_locator_init (MXFMetadataLocator * self) { @@ -3374,9 +3290,6 @@ mxf_metadata_locator_init (MXFMetadataLocator * self) static void mxf_metadata_locator_class_init (MXFMetadataLocatorClass * klass) { - MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass; - - metadata_base_class->handle_tag = mxf_metadata_locator_handle_tag; } G_DEFINE_TYPE (MXFMetadataTextLocator, mxf_metadata_text_locator, @@ -3487,3 +3400,125 @@ mxf_metadata_network_locator_class_init (MXFMetadataNetworkLocatorClass * klass) miniobject_class->finalize = mxf_metadata_network_locator_finalize; metadata_base_class->handle_tag = mxf_metadata_network_locator_handle_tag; } + +G_DEFINE_ABSTRACT_TYPE (MXFDescriptiveMetadata, mxf_descriptive_metadata, + MXF_TYPE_METADATA_BASE); + +static void +mxf_descriptive_metadata_init (MXFDescriptiveMetadata * self) +{ +} + +static void +mxf_descriptive_metadata_class_init (MXFDescriptiveMetadataClass * klass) +{ +} + +typedef struct +{ + guint8 scheme; + GSList *sets; +} _MXFDescriptiveMetadataScheme; + +static GSList *_dm_schemes = NULL; + +void +mxf_descriptive_metadata_register (guint8 scheme, GSList * sets) +{ + _MXFDescriptiveMetadataScheme *s = + g_slice_new (_MXFDescriptiveMetadataScheme); + + s->scheme = scheme; + s->sets = sets; + _dm_schemes = g_slist_prepend (_dm_schemes, s); +} + +MXFDescriptiveMetadata * +mxf_descriptive_metadata_new (guint8 scheme, guint32 type, + MXFPrimerPack * primer, const guint8 * data, guint size) +{ + GSList *l; + GType t = G_TYPE_INVALID; + _MXFDescriptiveMetadataScheme *s = NULL; + MXFDescriptiveMetadata *ret = NULL; + + g_return_val_if_fail (type != 0, NULL); + g_return_val_if_fail (primer != NULL, NULL); + + for (l = _dm_schemes; l; l = l->next) { + _MXFDescriptiveMetadataScheme *data = l->data; + + if (data->scheme == scheme) { + s = data; + break; + } + } + + if (s == NULL) { + GST_WARNING ("Descriptive metadata scheme 0x%02x not supported", scheme); + return NULL; + } + + for (l = s->sets; l; l = l->next) { + MXFDescriptiveMetadataSet *set = l->data; + + if (set->id == type) { + t = set->type; + break; + } else if (set->id == 0x000000) { + t = set->type; + } + } + + if (t == G_TYPE_INVALID) { + GST_WARNING + ("No handler for type 0x%06x of descriptive metadata scheme 0x%02x found", + type, scheme); + return NULL; + } + + ret = (MXFDescriptiveMetadata *) g_type_create_instance (t); + if (!mxf_metadata_base_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; +} + +/* TODO: Remove this once we depend on GLib 2.14 */ +#if GLIB_CHECK_VERSION (2, 14, 0) +#define __gst_once_init_enter(val) (g_once_init_enter (val)) +#define __gst_once_init_leave(val,newval) (g_once_init_leave (val, newval)) +#endif + +GType +mxf_descriptive_metadata_framework_get_type (void) +{ + static volatile gsize type = 0; + if (__gst_once_init_enter (&type)) { + GType _type = 0; + static const GTypeInfo info = { + sizeof (MXFDescriptiveMetadataFrameworkInterface), + NULL, /* base_init */ + NULL, /* base_finalize */ + NULL, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, /* instance_size */ + 0, /* n_preallocs */ + NULL /* instance_init */ + }; + _type = g_type_register_static (G_TYPE_INTERFACE, + "MXFDescriptiveMetadataFrameworkInterface", &info, 0); + + g_type_interface_add_prerequisite (_type, MXF_TYPE_DESCRIPTIVE_METADATA); + + __gst_once_init_leave (&type, (gsize) _type); + } + + return (GType) type; +} diff --git a/gst/mxf/mxfmetadata.h b/gst/mxf/mxfmetadata.h index e5c455e8..5b6f12eb 100644 --- a/gst/mxf/mxfmetadata.h +++ b/gst/mxf/mxfmetadata.h @@ -333,16 +333,45 @@ typedef struct _MXFMetadataTextLocator MXFMetadataTextLocator; typedef MXFMetadataBaseClass MXFMetadataTextLocatorClass; GType mxf_metadata_text_locator_get_type (void); +#define MXF_TYPE_DESCRIPTIVE_METADATA \ + (mxf_descriptive_metadata_get_type()) +#define MXF_DESCRIPTIVE_METADATA(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_DESCRIPTIVE_METADATA,MXFDescriptiveMetadata)) +#define MXF_IS_DESCRIPTIVE_METADATA(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_DESCRIPTIVE_METADATA)) +#define MXF_DESCRIPTIVE_METADATA_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), MXF_TYPE_DESCRIPTIVE_METADATA, MXFDescriptiveMetadataClass)) +#define MXF_DESCRIPTIVE_METADATA_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),MXF_TYPE_DESCRIPTIVE_METADATA,MXFDescriptiveMetadataClass)) +typedef struct _MXFDescriptiveMetadata MXFDescriptiveMetadata; +typedef struct _MXFDescriptiveMetadataClass MXFDescriptiveMetadataClass; +GType mxf_descriptive_metadata_get_type (void); + +#define MXF_TYPE_DESCRIPTIVE_METADATA_FRAMEWORK \ + (mxf_descriptive_metadata_framework_get_type ()) +#define MXF_DESCRIPTIVE_METADATA_FRAMEWORK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), MXF_TYPE_DESCRIPTIVE_METADATA_FRAMEWORK, MXFDescriptiveMetadataFramework)) +#define MXF_IS_DESCRIPTIVE_METADATA_FRAMEWORK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MXF_TYPE_DESCRIPTIVE_METADATA_FRAMEWORK)) +#define MXF_DESCRIPTIVE_METADATA_FRAMEWORK_GET_INTERFACE(inst) \ + (G_TYPE_INSTANCE_GET_INTERFACE ((inst), MXF_TYPE_DESCRIPTIVE_METADATA_FRAMEWORK, MXFDescriptiveMetadataFrameworkInterface)) + +typedef struct _MXFDescriptiveMetadataFramework MXFDescriptiveMetadataFramework; /* dummy object */ +typedef struct _MXFDescriptiveMetadataFrameworkInterface MXFDescriptiveMetadataFrameworkInterface; +GType mxf_descriptive_metadata_framework_get_type (void); + typedef enum { MXF_METADATA_BASE_RESOLVE_STATE_NONE = 0, MXF_METADATA_BASE_RESOLVE_STATE_SUCCESS, - MXF_METADATA_BASE_RESOLVE_STATE_FAILURE + MXF_METADATA_BASE_RESOLVE_STATE_FAILURE, + MXF_METADATA_BASE_RESOLVE_STATE_RUNNING } MXFMetadataBaseResolveState; struct _MXFMetadataBase { GstMiniObject parent; MXFUL instance_uid; + MXFUL generation_uid; MXFMetadataBaseResolveState resolved; @@ -365,8 +394,6 @@ struct _MXFMetadata { struct _MXFMetadataPreface { MXFMetadata parent; - MXFUL generation_uid; - MXFTimestamp last_modified_date; guint16 version; @@ -415,8 +442,6 @@ struct _MXFMetadataIdentification { struct _MXFMetadataContentStorage { MXFMetadata parent; - MXFUL generation_uid; - guint32 n_packages; MXFUL *packages_uids; MXFMetadataGenericPackage **packages; @@ -429,8 +454,6 @@ struct _MXFMetadataContentStorage { struct _MXFMetadataEssenceContainerData { MXFMetadata parent; - MXFUL generation_uid; - MXFUMID linked_package_uid; MXFMetadataSourcePackage *linked_package; @@ -441,8 +464,6 @@ struct _MXFMetadataEssenceContainerData { struct _MXFMetadataGenericPackage { MXFMetadata parent; - MXFUL generation_uid; - MXFUMID package_uid; gchar *name; @@ -486,8 +507,6 @@ typedef enum { struct _MXFMetadataTrack { MXFMetadata parent; - MXFUL generation_uid; - guint32 track_id; guint32 track_number; @@ -519,8 +538,6 @@ struct _MXFMetadataEventTrack { struct _MXFMetadataSequence { MXFMetadata parent; - MXFUL generation_uid; - MXFUL data_definition; gint64 duration; @@ -533,8 +550,6 @@ struct _MXFMetadataSequence { struct _MXFMetadataStructuralComponent { MXFMetadata parent; - MXFUL generation_uid; - MXFUL data_definition; gint64 duration; }; @@ -574,14 +589,12 @@ struct _MXFMetadataDMSegment { guint32 *track_ids; MXFUL dm_framework_uid; - MXFMetadataBase *dm_framework; + MXFDescriptiveMetadataFramework *dm_framework; }; struct _MXFMetadataGenericDescriptor { MXFMetadata parent; - MXFUL generation_uid; - guint32 n_locators; MXFUL *locators_uids; MXFMetadataLocator **locators; @@ -698,8 +711,6 @@ struct _MXFMetadataMultipleDescriptor { struct _MXFMetadataLocator { MXFMetadata parent; - - MXFUL generation_uid; }; struct _MXFMetadataNetworkLocator { @@ -714,6 +725,25 @@ struct _MXFMetadataTextLocator { gchar *locator_name; }; +typedef struct { + guint32 id; + GType type; +} MXFDescriptiveMetadataSet; + +struct _MXFDescriptiveMetadata { + MXFMetadataBase parent; + + guint32 type; +}; + +struct _MXFDescriptiveMetadataClass { + MXFMetadataBase parent; +}; + +struct _MXFDescriptiveMetadataFrameworkInterface { + GTypeInterface parent; +}; + gboolean mxf_metadata_base_parse (MXFMetadataBase *self, MXFPrimerPack *primer, const guint8 *data, guint size); gboolean mxf_metadata_base_resolve (MXFMetadataBase *self, MXFMetadataBase **metadata); @@ -726,4 +756,7 @@ MXFMetadataTrackType mxf_metadata_track_identifier_parse (const MXFUL * track_id void mxf_metadata_generic_picture_essence_descriptor_set_caps (MXFMetadataGenericPictureEssenceDescriptor * self, GstCaps * caps); void mxf_metadata_generic_sound_essence_descriptor_set_caps (MXFMetadataGenericSoundEssenceDescriptor * self, GstCaps * caps); +void mxf_descriptive_metadata_register (guint8 scheme, GSList *sets); +MXFDescriptiveMetadata * mxf_descriptive_metadata_new (guint8 scheme, guint32 type, MXFPrimerPack * primer, const guint8 * data, guint size); + #endif /* __MXF_METADATA_H__ */ diff --git a/gst/mxf/mxfmpeg.c b/gst/mxf/mxfmpeg.c index 574cc5a8..e95719d2 100644 --- a/gst/mxf/mxfmpeg.c +++ b/gst/mxf/mxfmpeg.c @@ -478,17 +478,17 @@ mxf_mpeg_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, if (!track->parent.descriptor[i]) continue; - if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track->parent. - descriptor[i])) { + if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track-> + parent.descriptor[i])) { f = track->parent.descriptor[i]; - p = (MXFMetadataGenericPictureEssenceDescriptor *) track-> - parent.descriptor[i]; + p = (MXFMetadataGenericPictureEssenceDescriptor *) track->parent. + descriptor[i]; break; - } else if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->parent. - descriptor[i])) { + } else if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track-> + parent.descriptor[i])) { f = track->parent.descriptor[i]; - s = (MXFMetadataGenericSoundEssenceDescriptor *) track-> - parent.descriptor[i]; + s = (MXFMetadataGenericSoundEssenceDescriptor *) track->parent. + descriptor[i]; break; } } diff --git a/gst/mxf/mxfup.c b/gst/mxf/mxfup.c index afd8e2a1..8155d8d2 100644 --- a/gst/mxf/mxfup.c +++ b/gst/mxf/mxfup.c @@ -222,19 +222,19 @@ mxf_up_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, if (!track->parent.descriptor[i]) continue; - if (MXF_IS_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (track-> - parent.descriptor[i])) { - p = (MXFMetadataGenericPictureEssenceDescriptor *) track-> - parent.descriptor[i]; - r = (MXFMetadataRGBAPictureEssenceDescriptor *) track-> - parent.descriptor[i]; - break; - } else if (MXF_IS_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (track->parent. + if (MXF_IS_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (track->parent. descriptor[i])) { - p = (MXFMetadataGenericPictureEssenceDescriptor *) track-> - parent.descriptor[i]; - c = (MXFMetadataCDCIPictureEssenceDescriptor *) track-> - parent.descriptor[i]; + p = (MXFMetadataGenericPictureEssenceDescriptor *) track->parent. + descriptor[i]; + r = (MXFMetadataRGBAPictureEssenceDescriptor *) track->parent. + descriptor[i]; + break; + } else if (MXF_IS_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (track-> + parent.descriptor[i])) { + p = (MXFMetadataGenericPictureEssenceDescriptor *) track->parent. + descriptor[i]; + c = (MXFMetadataCDCIPictureEssenceDescriptor *) track->parent. + descriptor[i]; } } diff --git a/gst/mxf/mxfvc3.c b/gst/mxf/mxfvc3.c index 1fcb2d7e..398bcc58 100644 --- a/gst/mxf/mxfvc3.c +++ b/gst/mxf/mxfvc3.c @@ -100,10 +100,10 @@ mxf_vc3_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, if (!track->parent.descriptor[i]) continue; - if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track-> - parent.descriptor[i])) { - p = (MXFMetadataGenericPictureEssenceDescriptor *) track->parent. - descriptor[i]; + if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track->parent. + descriptor[i])) { + p = (MXFMetadataGenericPictureEssenceDescriptor *) track-> + parent.descriptor[i]; f = track->parent.descriptor[i]; break; } else if (MXF_IS_METADATA_FILE_DESCRIPTOR (track->parent.descriptor[i]) && |