d735e4d609b9b36bd23e596882ced257d4195d57
[platform/upstream/gstreamer.git] / gst / mxf / mxfdms1.c
1 /* GStreamer
2  * Copyright (C) 2008-2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 /* Implementation of SMPTE S380M - Descriptive Metadata Scheme-1 */
21
22 /* TODO:
23  *   - What are the "locators"?
24  *   - Create sensible tags from this
25  */
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include <gst/gst.h>
32 #include <string.h>
33
34 #include "mxfdms1.h"
35 #include "mxftypes.h"
36
37 GST_DEBUG_CATEGORY_EXTERN (mxf_debug);
38 #define GST_CAT_DEFAULT mxf_debug
39
40 G_DEFINE_ABSTRACT_TYPE (MXFDMS1, mxf_dms1, MXF_TYPE_DESCRIPTIVE_METADATA);
41
42 static gboolean
43 mxf_dms1_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer,
44     guint16 tag, const guint8 * tag_data, guint tag_size)
45 {
46   MXFDMS1 *self = MXF_DMS1 (metadata);
47   gboolean ret = TRUE;
48 #ifndef GST_DISABLE_GST_DEBUG
49   gchar str[48];
50 #endif
51   MXFUL *tag_ul = NULL;
52   static const guint8 instance_uid_ul[] = {
53     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x01,
54     0x01, 0x15, 0x02, 0x00, 0x00, 0x00, 0x00
55   };
56   static const guint8 generation_uid_ul[] = {
57     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, 0x05,
58     0x20, 0x07, 0x01, 0x08, 0x00, 0x00, 0x00
59   };
60
61   if (!(tag_ul =
62           (MXFUL *) g_hash_table_lookup (primer->mappings,
63               GUINT_TO_POINTER (((guint) tag)))))
64     return FALSE;
65
66   if (memcmp (tag_ul, &instance_uid_ul, 16) == 0) {
67     if (tag_size != 16)
68       goto error;
69     memcpy (&MXF_METADATA_BASE (self)->instance_uid, tag_data, 16);
70     GST_DEBUG ("  instance uid = %s",
71         mxf_uuid_to_string (&MXF_METADATA_BASE (self)->instance_uid, str));
72   } else if (memcmp (tag_ul, &generation_uid_ul, 16) == 0) {
73     if (tag_size != 16)
74       goto error;
75     memcpy (&MXF_METADATA_BASE (self)->generation_uid, tag_data, 16);
76     GST_DEBUG ("  generation uid = %s",
77         mxf_uuid_to_string (&MXF_METADATA_BASE (self)->generation_uid, str));
78   } else {
79     ret =
80         MXF_METADATA_BASE_CLASS (mxf_dms1_parent_class)->handle_tag
81         (metadata, primer, tag, tag_data, tag_size);
82   }
83
84   return ret;
85
86 error:
87
88   GST_ERROR ("Invalid DMS1 local tag 0x%04x of size %u", tag, tag_size);
89
90   return FALSE;
91 }
92
93 static void
94 mxf_dms1_init (MXFDMS1 * self)
95 {
96 }
97
98 static void
99 mxf_dms1_class_init (MXFDMS1Class * klass)
100 {
101   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
102   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
103
104   metadatabase_class->handle_tag = mxf_dms1_handle_tag;
105   dm_class->scheme = 0x01;
106 }
107
108 G_DEFINE_ABSTRACT_TYPE (MXFDMS1TextLanguage, mxf_dms1_text_language,
109     MXF_TYPE_DMS1);
110
111 static gboolean
112 mxf_dms1_text_language_handle_tag (MXFMetadataBase * metadata,
113     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
114     guint tag_size)
115 {
116   MXFDMS1TextLanguage *self = MXF_DMS1_TEXT_LANGUAGE (metadata);
117   gboolean ret = TRUE;
118   MXFUL *tag_ul = NULL;
119   static const guint8 extended_text_language_code_ul[] = {
120     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x03,
121     0x01, 0x01, 0x02, 0x02, 0x11, 0x00, 0x00
122   };
123
124   if (!(tag_ul =
125           (MXFUL *) g_hash_table_lookup (primer->mappings,
126               GUINT_TO_POINTER (((guint) tag)))))
127     return FALSE;
128
129   if (memcmp (tag_ul, &extended_text_language_code_ul, 16) == 0) {
130     if (tag_size > 12)
131       goto error;
132
133     memcpy (self->extended_text_language_code, tag_data, tag_size);
134     GST_DEBUG ("  extended text language code = %s",
135         self->extended_text_language_code);
136   } else {
137     ret =
138         MXF_METADATA_BASE_CLASS
139         (mxf_dms1_text_language_parent_class)->handle_tag (metadata, primer,
140         tag, tag_data, tag_size);
141   }
142
143   return ret;
144
145 error:
146
147   GST_ERROR ("Invalid DMS1 text language local tag 0x%04x of size %u", tag,
148       tag_size);
149
150   return FALSE;
151 }
152
153 static void
154 mxf_dms1_text_language_init (MXFDMS1TextLanguage * self)
155 {
156 }
157
158 static void
159 mxf_dms1_text_language_class_init (MXFDMS1TextLanguageClass * klass)
160 {
161   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
162
163   metadatabase_class->handle_tag = mxf_dms1_text_language_handle_tag;
164 }
165
166 G_DEFINE_ABSTRACT_TYPE (MXFDMS1Thesaurus, mxf_dms1_thesaurus,
167     MXF_TYPE_DMS1_TEXT_LANGUAGE);
168
169 static void
170 mxf_dms1_thesaurus_finalize (GObject * object)
171 {
172   MXFDMS1Thesaurus *self = MXF_DMS1_THESAURUS (object);
173
174   g_free (self->thesaurus_name);
175   self->thesaurus_name = NULL;
176
177   G_OBJECT_CLASS (mxf_dms1_thesaurus_parent_class)->finalize (object);
178 }
179
180 static gboolean
181 mxf_dms1_thesaurus_handle_tag (MXFMetadataBase * metadata,
182     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
183     guint tag_size)
184 {
185   MXFDMS1Thesaurus *self = MXF_DMS1_THESAURUS (metadata);
186   gboolean ret = TRUE;
187   MXFUL *tag_ul = NULL;
188   static const guint8 thesaurus_name_ul[] = {
189     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x03,
190     0x02, 0x01, 0x02, 0x02, 0x01, 0x00, 0x00
191   };
192
193   if (!(tag_ul =
194           (MXFUL *) g_hash_table_lookup (primer->mappings,
195               GUINT_TO_POINTER (((guint) tag)))))
196     return FALSE;
197
198   if (memcmp (tag_ul, &thesaurus_name_ul, 16) == 0) {
199     self->thesaurus_name = mxf_utf16_to_utf8 (tag_data, tag_size);
200     GST_DEBUG ("  thesaurus name  = %s", GST_STR_NULL (self->thesaurus_name));
201   } else {
202     ret =
203         MXF_METADATA_BASE_CLASS (mxf_dms1_thesaurus_parent_class)->handle_tag
204         (metadata, primer, tag, tag_data, tag_size);
205   }
206
207   return ret;
208 }
209
210 static void
211 mxf_dms1_thesaurus_init (MXFDMS1Thesaurus * self)
212 {
213 }
214
215 static void
216 mxf_dms1_thesaurus_class_init (MXFDMS1ThesaurusClass * klass)
217 {
218   GObjectClass *object_class = (GObjectClass *) klass;
219   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
220
221   object_class->finalize = mxf_dms1_thesaurus_finalize;
222   metadatabase_class->handle_tag = mxf_dms1_thesaurus_handle_tag;
223 }
224
225 static void
226 mxf_dms1_framework_interface_init (gpointer g_iface, gpointer iface_data)
227 {
228 }
229
230 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MXFDMS1Framework, mxf_dms1_framework,
231     MXF_TYPE_DMS1,
232     G_IMPLEMENT_INTERFACE (MXF_TYPE_DESCRIPTIVE_METADATA_FRAMEWORK,
233         mxf_dms1_framework_interface_init));
234
235 static void
236 mxf_dms1_framework_finalize (GObject * object)
237 {
238   MXFDMS1Framework *self = MXF_DMS1_FRAMEWORK (object);
239
240   g_free (self->framework_thesaurus_name);
241   self->framework_thesaurus_name = NULL;
242
243   g_free (self->framework_title);
244   self->framework_title = NULL;
245
246   g_free (self->metadata_server_locators_uids);
247   self->metadata_server_locators_uids = NULL;
248
249   g_free (self->titles_sets_uids);
250   self->titles_sets_uids = NULL;
251
252   g_free (self->titles_sets);
253   self->titles_sets = NULL;
254
255   g_free (self->annotation_sets_uids);
256   self->annotation_sets_uids = NULL;
257
258   g_free (self->annotation_sets);
259   self->annotation_sets = NULL;
260
261   g_free (self->participant_sets_uids);
262   self->participant_sets_uids = NULL;
263
264   g_free (self->participant_sets);
265   self->participant_sets = NULL;
266
267   g_free (self->location_sets_uids);
268   self->location_sets_uids = NULL;
269
270   g_free (self->location_sets);
271   self->location_sets = NULL;
272
273   G_OBJECT_CLASS (mxf_dms1_framework_parent_class)->finalize (object);
274 }
275
276 static gboolean
277 mxf_dms1_framework_resolve (MXFMetadataBase * m, GHashTable * metadata)
278 {
279   MXFDMS1Framework *self = MXF_DMS1_FRAMEWORK (m);
280   MXFMetadataBase *current = NULL;
281   guint i;
282
283   if (self->titles_sets)
284     memset (self->titles_sets, 0, sizeof (gpointer) * self->n_titles_sets);
285   else
286     self->titles_sets = g_new0 (MXFDMS1Titles *, self->n_titles_sets);
287
288   if (self->annotation_sets)
289     memset (self->annotation_sets, 0,
290         sizeof (gpointer) * self->n_annotation_sets);
291   else
292     self->annotation_sets =
293         g_new0 (MXFDMS1Annotation *, self->n_annotation_sets);
294
295   if (self->participant_sets)
296     memset (self->participant_sets, 0,
297         sizeof (gpointer) * self->n_participant_sets);
298   else
299     self->participant_sets =
300         g_new0 (MXFDMS1Participant *, self->n_participant_sets);
301
302   if (self->location_sets)
303     memset (self->location_sets, 0, sizeof (gpointer) * self->n_location_sets);
304   else
305     self->location_sets = g_new0 (MXFDMS1Location *, self->n_location_sets);
306
307   for (i = 0; i < self->n_titles_sets; i++) {
308     current = g_hash_table_lookup (metadata, &self->titles_sets_uids[i]);
309
310     if (current && MXF_IS_DMS1_TITLES (current)) {
311       self->titles_sets[i] = MXF_DMS1_TITLES (current);
312     }
313   }
314
315   for (i = 0; i < self->n_annotation_sets; i++) {
316     current = g_hash_table_lookup (metadata, &self->annotation_sets_uids[i]);
317     if (current && MXF_IS_DMS1_ANNOTATION (current)) {
318       self->annotation_sets[i] = MXF_DMS1_ANNOTATION (current);
319     }
320   }
321
322   for (i = 0; i < self->n_participant_sets; i++) {
323     current = g_hash_table_lookup (metadata, &self->participant_sets_uids[i]);
324     if (current && MXF_IS_DMS1_PARTICIPANT (current)) {
325       self->participant_sets[i] = MXF_DMS1_PARTICIPANT (current);
326     }
327   }
328
329   current = g_hash_table_lookup (metadata, &self->contacts_list_set_uid);
330   if (current && MXF_IS_DMS1_CONTACTS_LIST (current)) {
331     self->contacts_list_set = MXF_DMS1_CONTACTS_LIST (current);
332   }
333
334   for (i = 0; i < self->n_location_sets; i++) {
335     current = g_hash_table_lookup (metadata, &self->location_sets_uids[i]);
336     if (current && MXF_IS_DMS1_LOCATION (current)) {
337       self->location_sets[i] = MXF_DMS1_LOCATION (current);
338     }
339   }
340
341   return MXF_METADATA_BASE_CLASS (mxf_dms1_framework_parent_class)->resolve (m,
342       metadata);
343 }
344
345 static gboolean
346 mxf_dms1_framework_handle_tag (MXFMetadataBase * metadata,
347     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
348     guint tag_size)
349 {
350   MXFDMS1Framework *self = MXF_DMS1_FRAMEWORK (metadata);
351   gboolean ret = TRUE;
352 #ifndef GST_DISABLE_GST_DEBUG
353   gchar str[48];
354 #endif
355   MXFUL *tag_ul = NULL;
356   static const guint8 framework_extended_text_language_code_ul[] = {
357     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x03,
358     0x01, 0x01, 0x02, 0x02, 0x13, 0x00, 0x00
359   };
360   static const guint8 framework_thesaurus_name_ul[] = {
361     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03,
362     0x02, 0x01, 0x02, 0x15, 0x01, 0x00, 0x00
363   };
364   static const guint8 framework_title_ul[] = {
365     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x01,
366     0x05, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00
367   };
368   static const guint8 primary_extended_spoken_language_code_ul[] = {
369     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x03,
370     0x01, 0x01, 0x02, 0x03, 0x11, 0x00, 0x00
371   };
372   static const guint8 secondary_extended_spoken_language_code_ul[] = {
373     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x03,
374     0x01, 0x01, 0x02, 0x03, 0x12, 0x00, 0x00
375   };
376   static const guint8 original_extended_spoken_language_code_ul[] = {
377     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x03,
378     0x01, 0x01, 0x02, 0x03, 0x13, 0x00, 0x00
379   };
380   static const guint8 metadata_server_locators_ul[] = {
381     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
382     0x01, 0x01, 0x04, 0x06, 0x0C, 0x00, 0x00
383   };
384   static const guint8 titles_sets_ul[] = {
385     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
386     0x01, 0x01, 0x04, 0x05, 0x40, 0x04, 0x00
387   };
388   static const guint8 annotation_sets_ul[] = {
389     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
390     0x01, 0x01, 0x04, 0x05, 0x40, 0x0d, 0x00
391   };
392   static const guint8 participant_sets_ul[] = {
393     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
394     0x01, 0x01, 0x04, 0x05, 0x40, 0x13, 0x00
395   };
396   static const guint8 contacts_list_set_ul[] = {
397     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
398     0x01, 0x01, 0x04, 0x02, 0x40, 0x22, 0x00
399   };
400   static const guint8 location_sets_ul[] = {
401     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
402     0x01, 0x01, 0x04, 0x03, 0x40, 0x16, 0x00
403   };
404
405   if (!(tag_ul =
406           (MXFUL *) g_hash_table_lookup (primer->mappings,
407               GUINT_TO_POINTER (((guint) tag)))))
408     return FALSE;
409
410   if (memcmp (tag_ul, &framework_extended_text_language_code_ul, 16) == 0) {
411     if (tag_size > 12)
412       goto error;
413     memcpy (&self->framework_extended_text_language_code, tag_data, tag_size);
414     GST_DEBUG ("  framework extended text language code = %s",
415         self->framework_extended_text_language_code);
416   } else if (memcmp (tag_ul, &framework_thesaurus_name_ul, 16) == 0) {
417     self->framework_thesaurus_name = mxf_utf16_to_utf8 (tag_data, tag_size);
418     GST_DEBUG ("  framework thesaurus name = %s",
419         GST_STR_NULL (self->framework_thesaurus_name));
420   } else if (memcmp (tag_ul, &framework_title_ul, 16) == 0) {
421     self->framework_title = mxf_utf16_to_utf8 (tag_data, tag_size);
422     GST_DEBUG ("  framework title = %s", GST_STR_NULL (self->framework_title));
423   } else if (memcmp (tag_ul, &primary_extended_spoken_language_code_ul,
424           16) == 0) {
425     if (tag_size > 12)
426       goto error;
427     memcpy (&self->primary_extended_spoken_language_code, tag_data, tag_size);
428     GST_DEBUG ("  primary extended spoken language code = %s",
429         self->primary_extended_spoken_language_code);
430   } else if (memcmp (tag_ul, &secondary_extended_spoken_language_code_ul,
431           16) == 0) {
432     if (tag_size > 12)
433       goto error;
434     memcpy (&self->secondary_extended_spoken_language_code, tag_data, tag_size);
435     GST_DEBUG ("  secondary extended spoken language code = %s",
436         self->secondary_extended_spoken_language_code);
437   } else if (memcmp (tag_ul, &original_extended_spoken_language_code_ul,
438           16) == 0) {
439     if (tag_size > 12)
440       goto error;
441     memcpy (&self->original_extended_spoken_language_code, tag_data, tag_size);
442     GST_DEBUG ("  original extended spoken language code = %s",
443         self->original_extended_spoken_language_code);
444   } else if (memcmp (tag_ul, &metadata_server_locators_ul, 16) == 0) {
445     if (!mxf_uuid_array_parse (&self->metadata_server_locators_uids,
446             &self->n_metadata_server_locators, tag_data, tag_size))
447       goto error;
448
449     GST_DEBUG ("  number of metadata server locators = %u",
450         self->n_metadata_server_locators);
451 #ifndef GST_DISABLE_GST_DEBUG
452     {
453       guint i;
454       for (i = 0; i < self->n_metadata_server_locators; i++) {
455         GST_DEBUG ("    metadata server locator %u = %s", i,
456             mxf_uuid_to_string (&self->metadata_server_locators_uids[i], str));
457       }
458     }
459 #endif
460   } else if (memcmp (tag_ul, &titles_sets_ul, 16) == 0) {
461     if (!mxf_uuid_array_parse (&self->titles_sets_uids, &self->n_titles_sets,
462             tag_data, tag_size))
463       goto error;
464
465     GST_DEBUG ("  number of titles sets = %u", self->n_titles_sets);
466 #ifndef GST_DISABLE_GST_DEBUG
467     {
468       guint i;
469       for (i = 0; i < self->n_titles_sets; i++) {
470         GST_DEBUG ("    titles sets %u = %s", i,
471             mxf_uuid_to_string (&self->titles_sets_uids[i], str));
472       }
473     }
474 #endif
475   } else if (memcmp (tag_ul, &annotation_sets_ul, 16) == 0) {
476     if (!mxf_uuid_array_parse (&self->annotation_sets_uids,
477             &self->n_annotation_sets, tag_data, tag_size))
478       goto error;
479     GST_DEBUG ("  number of annotation sets = %u", self->n_annotation_sets);
480 #ifndef GST_DISABLE_GST_DEBUG
481     {
482       guint i;
483       for (i = 0; i < self->n_annotation_sets; i++) {
484         GST_DEBUG ("    annotation sets %u = %s", i,
485             mxf_uuid_to_string (&self->annotation_sets_uids[i], str));
486       }
487     }
488 #endif
489   } else if (memcmp (tag_ul, &participant_sets_ul, 16) == 0) {
490     if (!mxf_uuid_array_parse (&self->participant_sets_uids,
491             &self->n_participant_sets, tag_data, tag_size))
492       goto error;
493     GST_DEBUG ("  number of participant sets = %u", self->n_participant_sets);
494 #ifndef GST_DISABLE_GST_DEBUG
495     {
496       guint i;
497       for (i = 0; i < self->n_participant_sets; i++) {
498         GST_DEBUG ("    participant sets %u = %s", i,
499             mxf_uuid_to_string (&self->participant_sets_uids[i], str));
500       }
501     }
502 #endif
503   } else if (memcmp (tag_ul, &contacts_list_set_ul, 16) == 0) {
504     if (tag_size != 16)
505       goto error;
506
507     memcpy (&self->contacts_list_set_uid, tag_data, 16);
508     GST_DEBUG ("  contacts list = %s",
509         mxf_uuid_to_string (&self->contacts_list_set_uid, str));
510   } else if (memcmp (tag_ul, &location_sets_ul, 16) == 0) {
511     if (!mxf_uuid_array_parse (&self->location_sets_uids,
512             &self->n_location_sets, tag_data, tag_size))
513       goto error;
514     GST_DEBUG ("  number of location sets = %u", self->n_location_sets);
515 #ifndef GST_DISABLE_GST_DEBUG
516     {
517       guint i;
518       for (i = 0; i < self->n_location_sets; i++) {
519         GST_DEBUG ("    location sets %u = %s", i,
520             mxf_uuid_to_string (&self->location_sets_uids[i], str));
521       }
522     }
523 #endif
524   } else {
525     ret =
526         MXF_METADATA_BASE_CLASS (mxf_dms1_framework_parent_class)->handle_tag
527         (metadata, primer, tag, tag_data, tag_size);
528   }
529
530   return ret;
531
532 error:
533
534   GST_ERROR ("Invalid DMS1 framework local tag 0x%04x of size %u", tag,
535       tag_size);
536
537   return FALSE;
538 }
539
540 static void
541 mxf_dms1_framework_init (MXFDMS1Framework * self)
542 {
543 }
544
545 static void
546 mxf_dms1_framework_class_init (MXFDMS1FrameworkClass * klass)
547 {
548   GObjectClass *object_class = (GObjectClass *) klass;
549   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
550
551   object_class->finalize = mxf_dms1_framework_finalize;
552   metadatabase_class->handle_tag = mxf_dms1_framework_handle_tag;
553   metadatabase_class->resolve = mxf_dms1_framework_resolve;
554 }
555
556 G_DEFINE_ABSTRACT_TYPE (MXFDMS1ProductionClipFramework,
557     mxf_dms1_production_clip_framework, MXF_TYPE_DMS1_FRAMEWORK);
558
559 static void
560 mxf_dms1_production_clip_framework_finalize (GObject * object)
561 {
562   MXFDMS1ProductionClipFramework *self =
563       MXF_DMS1_PRODUCTION_CLIP_FRAMEWORK (object);
564
565   g_free (self->captions_description_sets_uids);
566   self->captions_description_sets_uids = NULL;
567
568   g_free (self->captions_description_sets);
569   self->captions_description_sets = NULL;
570
571   g_free (self->contract_sets_uids);
572   self->contract_sets_uids = NULL;
573
574   g_free (self->contract_sets);
575   self->contract_sets = NULL;
576
577   G_OBJECT_CLASS
578       (mxf_dms1_production_clip_framework_parent_class)->finalize (object);
579 }
580
581 static gboolean
582 mxf_dms1_production_clip_framework_resolve (MXFMetadataBase * m,
583     GHashTable * metadata)
584 {
585   MXFDMS1ProductionClipFramework *self = MXF_DMS1_PRODUCTION_CLIP_FRAMEWORK (m);
586   MXFMetadataBase *current = NULL;
587   guint i;
588
589   if (self->captions_description_sets)
590     memset (self->captions_description_sets, 0,
591         sizeof (gpointer) * self->n_captions_description_sets);
592   else
593     self->captions_description_sets =
594         g_new0 (MXFDMS1CaptionsDescription *,
595         self->n_captions_description_sets);
596
597   if (self->contract_sets)
598     memset (self->contract_sets, 0,
599         sizeof (gpointer) * self->n_captions_description_sets);
600   else
601     self->contract_sets = g_new0 (MXFDMS1Contract *, self->n_contract_sets);
602
603   current = g_hash_table_lookup (metadata, &self->picture_format_set_uid);
604   if (current && MXF_IS_DMS1_PICTURE_FORMAT (current)) {
605     self->picture_format = MXF_DMS1_PICTURE_FORMAT (current);
606   }
607
608   for (i = 0; i < self->n_captions_description_sets; i++) {
609     current =
610         g_hash_table_lookup (metadata,
611         &self->captions_description_sets_uids[i]);
612     if (current && MXF_IS_DMS1_CAPTIONS_DESCRIPTION (current)) {
613       self->captions_description_sets[i] =
614           MXF_DMS1_CAPTIONS_DESCRIPTION (current);
615     }
616   }
617
618   for (i = 0; i < self->n_contract_sets; i++) {
619     current = g_hash_table_lookup (metadata, &self->contract_sets_uids[i]);
620     if (current && MXF_IS_DMS1_CONTRACT (current)) {
621       self->contract_sets[i] = MXF_DMS1_CONTRACT (current);
622     }
623   }
624
625   current = g_hash_table_lookup (metadata, &self->project_set_uid);
626   if (current && MXF_IS_DMS1_PROJECT (current)) {
627     self->project_set = MXF_DMS1_PROJECT (current);
628   }
629
630   return
631       MXF_METADATA_BASE_CLASS
632       (mxf_dms1_production_clip_framework_parent_class)->resolve (m, metadata);
633 }
634
635 static gboolean
636 mxf_dms1_production_clip_framework_handle_tag (MXFMetadataBase * metadata,
637     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
638     guint tag_size)
639 {
640   MXFDMS1ProductionClipFramework *self =
641       MXF_DMS1_PRODUCTION_CLIP_FRAMEWORK (metadata);
642   gboolean ret = TRUE;
643 #ifndef GST_DISABLE_GST_DEBUG
644   gchar str[48];
645 #endif
646   MXFUL *tag_ul = NULL;
647   static const guint8 picture_format_ul[] = {
648     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
649     0x01, 0x01, 0x04, 0x02, 0x40, 0x1d, 0x00
650   };
651   static const guint8 captions_description_ul[] = {
652     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
653     0x01, 0x01, 0x04, 0x05, 0x40, 0x0c, 0x00
654   };
655   static const guint8 contract_ul[] = {
656     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
657     0x01, 0x01, 0x04, 0x05, 0x40, 0x19, 0x00
658   };
659   static const guint8 project_ul[] = {
660     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
661     0x01, 0x01, 0x04, 0x02, 0x40, 0x21, 0x00
662   };
663
664   if (!(tag_ul =
665           (MXFUL *) g_hash_table_lookup (primer->mappings,
666               GUINT_TO_POINTER (((guint) tag)))))
667     return FALSE;
668
669   if (memcmp (tag_ul, &picture_format_ul, 16) == 0) {
670     if (tag_size != 16)
671       goto error;
672
673     memcpy (&self->picture_format_set_uid, tag_data, 16);
674     GST_DEBUG ("  picture format set = %s",
675         mxf_uuid_to_string (&self->picture_format_set_uid, str));
676   } else if (memcmp (tag_ul, &captions_description_ul, 16) == 0) {
677     if (!mxf_uuid_array_parse (&self->captions_description_sets_uids,
678             &self->n_captions_description_sets, tag_data, tag_size))
679       goto error;
680     GST_DEBUG ("  number of captions description sets = %u",
681         self->n_captions_description_sets);
682 #ifndef GST_DISABLE_GST_DEBUG
683     {
684       guint i;
685       for (i = 0; i < self->n_captions_description_sets; i++) {
686         GST_DEBUG ("    captions description sets %u = %s", i,
687             mxf_uuid_to_string (&self->captions_description_sets_uids[i], str));
688       }
689     }
690 #endif
691   } else if (memcmp (tag_ul, &contract_ul, 16) == 0) {
692     if (!mxf_uuid_array_parse (&self->contract_sets_uids,
693             &self->n_contract_sets, tag_data, tag_size))
694       goto error;
695
696     GST_DEBUG ("  number of contract sets = %u", self->n_contract_sets);
697 #ifndef GST_DISABLE_GST_DEBUG
698     {
699       guint i;
700       for (i = 0; i < self->n_contract_sets; i++) {
701         GST_DEBUG ("    contract sets %u = %s", i,
702             mxf_uuid_to_string (&self->contract_sets_uids[i], str));
703       }
704     }
705 #endif
706   } else if (memcmp (tag_ul, &project_ul, 16) == 0) {
707     if (tag_size != 16)
708       goto error;
709
710     memcpy (&self->project_set_uid, tag_data, 16);
711     GST_DEBUG ("  project set = %s", mxf_uuid_to_string (&self->project_set_uid,
712             str));
713   } else {
714     ret =
715         MXF_METADATA_BASE_CLASS
716         (mxf_dms1_production_clip_framework_parent_class)->handle_tag (metadata,
717         primer, tag, tag_data, tag_size);
718   }
719
720   return ret;
721
722 error:
723
724   GST_ERROR
725       ("Invalid DMS1 production-clip framework local tag 0x%04x of size %u",
726       tag, tag_size);
727
728   return FALSE;
729 }
730
731 static void
732 mxf_dms1_production_clip_framework_init (MXFDMS1ProductionClipFramework * self)
733 {
734 }
735
736 static void
737     mxf_dms1_production_clip_framework_class_init
738     (MXFDMS1ProductionClipFrameworkClass * klass)
739 {
740   GObjectClass *object_class = (GObjectClass *) klass;
741   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
742
743   object_class->finalize = mxf_dms1_production_clip_framework_finalize;
744   metadatabase_class->handle_tag =
745       mxf_dms1_production_clip_framework_handle_tag;
746   metadatabase_class->resolve = mxf_dms1_production_clip_framework_resolve;
747 }
748
749 G_DEFINE_TYPE (MXFDMS1ProductionFramework, mxf_dms1_production_framework,
750     MXF_TYPE_DMS1_PRODUCTION_CLIP_FRAMEWORK);
751
752 static void
753 mxf_dms1_production_framework_finalize (GObject * object)
754 {
755   MXFDMS1ProductionFramework *self = MXF_DMS1_PRODUCTION_FRAMEWORK (object);
756
757   g_free (self->integration_indication);
758   self->integration_indication = NULL;
759
760   g_free (self->identification_sets_uids);
761   self->identification_sets_uids = NULL;
762
763   g_free (self->identification_sets);
764   self->identification_sets = NULL;
765
766   g_free (self->group_relationship_sets_uids);
767   self->group_relationship_sets_uids = NULL;
768
769   g_free (self->group_relationship_sets);
770   self->group_relationship_sets = NULL;
771
772   g_free (self->branding_sets_uids);
773   self->branding_sets_uids = NULL;
774
775   g_free (self->branding_sets);
776   self->branding_sets = NULL;
777
778   g_free (self->event_sets_uids);
779   self->event_sets_uids = NULL;
780
781   g_free (self->event_sets);
782   self->event_sets = NULL;
783
784   g_free (self->award_sets_uids);
785   self->award_sets_uids = NULL;
786
787   g_free (self->award_sets);
788   self->award_sets = NULL;
789
790   g_free (self->setting_period_sets_uids);
791   self->setting_period_sets_uids = NULL;
792
793   g_free (self->setting_period_sets);
794   self->setting_period_sets = NULL;
795
796   G_OBJECT_CLASS (mxf_dms1_production_framework_parent_class)->finalize
797       (object);
798 }
799
800 static gboolean
801 mxf_dms1_production_framework_resolve (MXFMetadataBase * m,
802     GHashTable * metadata)
803 {
804   MXFDMS1ProductionFramework *self = MXF_DMS1_PRODUCTION_FRAMEWORK (m);
805   MXFMetadataBase *current = NULL;
806   guint i;
807
808   if (self->identification_sets)
809     memset (self->identification_sets, 0,
810         sizeof (gpointer) * self->n_identification_sets);
811   else
812     self->identification_sets =
813         g_new0 (MXFDMS1Identification *, self->n_identification_sets);
814
815   if (self->group_relationship_sets)
816     memset (self->group_relationship_sets, 0,
817         sizeof (gpointer) * self->n_group_relationship_sets);
818   else
819     self->group_relationship_sets =
820         g_new0 (MXFDMS1GroupRelationship *, self->n_group_relationship_sets);
821
822   if (self->branding_sets)
823     memset (self->branding_sets, 0, sizeof (gpointer) * self->n_branding_sets);
824   else
825     self->branding_sets = g_new0 (MXFDMS1Branding *, self->n_branding_sets);
826
827   if (self->event_sets)
828     memset (self->event_sets, 0, sizeof (gpointer) * self->n_event_sets);
829   else
830     self->event_sets = g_new0 (MXFDMS1Event *, self->n_event_sets);
831
832   if (self->award_sets)
833     memset (self->award_sets, 0, sizeof (gpointer) * self->n_award_sets);
834   else
835     self->award_sets = g_new0 (MXFDMS1Award *, self->n_award_sets);
836
837   if (self->setting_period_sets)
838     memset (self->setting_period_sets, 0,
839         sizeof (gpointer) * self->n_setting_period_sets);
840   else
841     self->setting_period_sets =
842         g_new0 (MXFDMS1SettingPeriod *, self->n_setting_period_sets);
843
844   for (i = 0; i < self->n_identification_sets; i++) {
845     current =
846         g_hash_table_lookup (metadata, &self->identification_sets_uids[i]);
847     if (current && MXF_IS_DMS1_IDENTIFICATION (current)) {
848       self->identification_sets[i] = MXF_DMS1_IDENTIFICATION (current);
849     }
850   }
851
852   for (i = 0; i < self->n_group_relationship_sets; i++) {
853     current =
854         g_hash_table_lookup (metadata, &self->group_relationship_sets_uids[i]);
855     if (current && MXF_IS_DMS1_GROUP_RELATIONSHIP (current)) {
856       self->group_relationship_sets[i] = MXF_DMS1_GROUP_RELATIONSHIP (current);
857     }
858   }
859
860   for (i = 0; i < self->n_branding_sets; i++) {
861     current = g_hash_table_lookup (metadata, &self->branding_sets_uids[i]);
862     if (current && MXF_IS_DMS1_BRANDING (current)) {
863       self->branding_sets[i] = MXF_DMS1_BRANDING (current);
864     }
865   }
866
867   for (i = 0; i < self->n_event_sets; i++) {
868     current = g_hash_table_lookup (metadata, &self->event_sets_uids[i]);
869     if (current && MXF_IS_DMS1_EVENT (current)) {
870       self->event_sets[i] = MXF_DMS1_EVENT (current);
871     }
872   }
873
874   for (i = 0; i < self->n_award_sets; i++) {
875     current = g_hash_table_lookup (metadata, &self->award_sets_uids[i]);
876     if (current && MXF_IS_DMS1_AWARD (current)) {
877       self->award_sets[i] = MXF_DMS1_AWARD (current);
878     }
879   }
880
881   for (i = 0; i < self->n_setting_period_sets; i++) {
882     current =
883         g_hash_table_lookup (metadata, &self->setting_period_sets_uids[i]);
884     if (current && MXF_IS_DMS1_SETTING_PERIOD (current)) {
885       self->setting_period_sets[i] = MXF_DMS1_SETTING_PERIOD (current);
886     }
887   }
888
889   return
890       MXF_METADATA_BASE_CLASS
891       (mxf_dms1_production_framework_parent_class)->resolve (m, metadata);
892 }
893
894 static gboolean
895 mxf_dms1_production_framework_handle_tag (MXFMetadataBase * metadata,
896     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
897     guint tag_size)
898 {
899   MXFDMS1ProductionFramework *self = MXF_DMS1_PRODUCTION_FRAMEWORK (metadata);
900   gboolean ret = TRUE;
901 #ifndef GST_DISABLE_GST_DEBUG
902   gchar str[48];
903 #endif
904   MXFUL *tag_ul = NULL;
905   static const guint8 integration_indication_ul[] = {
906     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x05,
907     0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00
908   };
909   static const guint8 identification_sets_ul[] = {
910     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
911     0x01, 0x01, 0x04, 0x05, 0x40, 0x06, 0x00
912   };
913   static const guint8 group_relationship_sets_ul[] = {
914     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
915     0x01, 0x01, 0x04, 0x05, 0x40, 0x05, 0x00
916   };
917   static const guint8 branding_sets_ul[] = {
918     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
919     0x01, 0x01, 0x04, 0x05, 0x40, 0x08, 0x00
920   };
921   static const guint8 event_sets_ul[] = {
922     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
923     0x01, 0x01, 0x04, 0x05, 0x40, 0x09, 0x00
924   };
925   static const guint8 award_sets_ul[] = {
926     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
927     0x01, 0x01, 0x04, 0x05, 0x40, 0x0b, 0x00
928   };
929   static const guint8 setting_period_sets_ul[] = {
930     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
931     0x01, 0x01, 0x04, 0x05, 0x40, 0x0e, 0x01
932   };
933
934   if (!(tag_ul =
935           (MXFUL *) g_hash_table_lookup (primer->mappings,
936               GUINT_TO_POINTER (((guint) tag)))))
937     return FALSE;
938
939   if (memcmp (tag_ul, &integration_indication_ul, 16) == 0) {
940     self->integration_indication = mxf_utf16_to_utf8 (tag_data, tag_size);
941     GST_DEBUG ("  integration indication = %s",
942         GST_STR_NULL (self->integration_indication));
943   } else if (memcmp (tag_ul, &identification_sets_ul, 16) == 0) {
944     if (!mxf_uuid_array_parse (&self->identification_sets_uids,
945             &self->n_identification_sets, tag_data, tag_size))
946       goto error;
947
948     GST_DEBUG ("  number of identification sets = %u",
949         self->n_identification_sets);
950 #ifndef GST_DISABLE_GST_DEBUG
951     {
952       guint i;
953       for (i = 0; i < self->n_identification_sets; i++) {
954         GST_DEBUG ("    identification sets %u = %s", i,
955             mxf_uuid_to_string (&self->identification_sets_uids[i], str));
956       }
957     }
958 #endif
959   } else if (memcmp (tag_ul, &group_relationship_sets_ul, 16) == 0) {
960     if (!mxf_uuid_array_parse (&self->group_relationship_sets_uids,
961             &self->n_group_relationship_sets, tag_data, tag_size))
962       goto error;
963     GST_DEBUG ("  number of group relationship sets = %u",
964         self->n_group_relationship_sets);
965 #ifndef GST_DISABLE_GST_DEBUG
966     {
967       guint i;
968       for (i = 0; i < self->n_group_relationship_sets; i++) {
969         GST_DEBUG ("    group relationship sets %u = %s", i,
970             mxf_uuid_to_string (&self->group_relationship_sets_uids[i], str));
971       }
972     }
973 #endif
974   } else if (memcmp (tag_ul, &branding_sets_ul, 16) == 0) {
975     if (!mxf_uuid_array_parse (&self->branding_sets_uids,
976             &self->n_branding_sets, tag_data, tag_size))
977       goto error;
978
979     GST_DEBUG ("  number of branding sets = %u", self->n_branding_sets);
980 #ifndef GST_DISABLE_GST_DEBUG
981     {
982       guint i;
983       for (i = 0; i < self->n_branding_sets; i++) {
984         GST_DEBUG ("    branding sets %u = %s", i,
985             mxf_uuid_to_string (&self->branding_sets_uids[i], str));
986       }
987     }
988 #endif
989   } else if (memcmp (tag_ul, &event_sets_ul, 16) == 0) {
990     if (!mxf_uuid_array_parse (&self->event_sets_uids, &self->n_event_sets,
991             tag_data, tag_size))
992       goto error;
993     GST_DEBUG ("  number of event sets = %u", self->n_event_sets);
994 #ifndef GST_DISABLE_GST_DEBUG
995     {
996       guint i;
997       for (i = 0; i < self->n_event_sets; i++) {
998         GST_DEBUG ("    event sets %u = %s", i,
999             mxf_uuid_to_string (&self->event_sets_uids[i], str));
1000       }
1001     }
1002 #endif
1003   } else if (memcmp (tag_ul, &award_sets_ul, 16) == 0) {
1004     if (!mxf_uuid_array_parse (&self->award_sets_uids, &self->n_award_sets,
1005             tag_data, tag_size))
1006       goto error;
1007     GST_DEBUG ("  number of award sets = %u", self->n_award_sets);
1008 #ifndef GST_DISABLE_GST_DEBUG
1009     {
1010       guint i;
1011       for (i = 0; i < self->n_award_sets; i++) {
1012         GST_DEBUG ("    award sets %u = %s", i,
1013             mxf_uuid_to_string (&self->award_sets_uids[i], str));
1014       }
1015     }
1016 #endif
1017   } else if (memcmp (tag_ul, &setting_period_sets_ul, 16) == 0) {
1018     if (!mxf_uuid_array_parse (&self->setting_period_sets_uids,
1019             &self->n_setting_period_sets, tag_data, tag_size))
1020       goto error;
1021     GST_DEBUG ("  number of setting period sets = %u",
1022         self->n_setting_period_sets);
1023 #ifndef GST_DISABLE_GST_DEBUG
1024     {
1025       guint i;
1026       for (i = 0; i < self->n_setting_period_sets; i++) {
1027         GST_DEBUG ("    setting period sets %u = %s", i,
1028             mxf_uuid_to_string (&self->setting_period_sets_uids[i], str));
1029       }
1030     }
1031 #endif
1032   } else {
1033     ret =
1034         MXF_METADATA_BASE_CLASS
1035         (mxf_dms1_production_framework_parent_class)->handle_tag (metadata,
1036         primer, tag, tag_data, tag_size);
1037   }
1038
1039   return ret;
1040
1041 error:
1042
1043   GST_ERROR ("Invalid DMS1 production framework local tag 0x%04x of size %u",
1044       tag, tag_size);
1045
1046   return FALSE;
1047 }
1048
1049 static void
1050 mxf_dms1_production_framework_init (MXFDMS1ProductionFramework * self)
1051 {
1052 }
1053
1054 static void
1055 mxf_dms1_production_framework_class_init (MXFDMS1ProductionFrameworkClass *
1056     klass)
1057 {
1058   GObjectClass *object_class = (GObjectClass *) klass;
1059   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
1060   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
1061
1062   object_class->finalize = mxf_dms1_production_framework_finalize;
1063   metadatabase_class->handle_tag = mxf_dms1_production_framework_handle_tag;
1064   metadatabase_class->resolve = mxf_dms1_production_framework_resolve;
1065
1066   dm_class->type = 0x010100;
1067 }
1068
1069 G_DEFINE_TYPE (MXFDMS1ClipFramework, mxf_dms1_clip_framework,
1070     MXF_TYPE_DMS1_PRODUCTION_CLIP_FRAMEWORK);
1071
1072 static void
1073 mxf_dms1_clip_framework_finalize (GObject * object)
1074 {
1075   MXFDMS1ClipFramework *self = MXF_DMS1_CLIP_FRAMEWORK (object);
1076
1077   g_free (self->clip_kind);
1078   self->clip_kind = NULL;
1079
1080   g_free (self->slate_information);
1081   self->slate_information = NULL;
1082
1083   g_free (self->scripting_sets_uids);
1084   self->scripting_sets_uids = NULL;
1085
1086   g_free (self->scripting_sets);
1087   self->scripting_sets = NULL;
1088
1089   g_free (self->shot_sets_uids);
1090   self->shot_sets_uids = NULL;
1091
1092   g_free (self->shot_sets);
1093   self->shot_sets = NULL;
1094
1095   g_free (self->device_parameters_sets_uids);
1096   self->device_parameters_sets_uids = NULL;
1097
1098   g_free (self->device_parameters_sets);
1099   self->device_parameters_sets = NULL;
1100
1101   G_OBJECT_CLASS (mxf_dms1_clip_framework_parent_class)->finalize (object);
1102 }
1103
1104 static gboolean
1105 mxf_dms1_clip_framework_resolve (MXFMetadataBase * m, GHashTable * metadata)
1106 {
1107   MXFDMS1ClipFramework *self = MXF_DMS1_CLIP_FRAMEWORK (m);
1108   MXFMetadataBase *current = NULL;
1109   guint i;
1110
1111   if (self->scripting_sets)
1112     memset (self->scripting_sets, 0,
1113         sizeof (gpointer) * self->n_scripting_sets);
1114   else
1115     self->scripting_sets = g_new0 (MXFDMS1Scripting *, self->n_scripting_sets);
1116
1117   if (self->shot_sets)
1118     memset (self->shot_sets, 0, sizeof (gpointer) * self->n_shot_sets);
1119   else
1120     self->shot_sets = g_new0 (MXFDMS1Shot *, self->n_shot_sets);
1121
1122   if (self->device_parameters_sets)
1123     memset (self->device_parameters_sets, 0,
1124         sizeof (gpointer) * self->n_device_parameters_sets);
1125   else
1126     self->device_parameters_sets =
1127         g_new0 (MXFDMS1DeviceParameters *, self->n_device_parameters_sets);
1128
1129   for (i = 0; i < self->n_scripting_sets; i++) {
1130     current = g_hash_table_lookup (metadata, &self->scripting_sets_uids[i]);
1131
1132     if (current && MXF_IS_DMS1_SCRIPTING (current)) {
1133       self->scripting_sets[i] = MXF_DMS1_SCRIPTING (current);
1134     }
1135   }
1136
1137   for (i = 0; i < self->n_shot_sets; i++) {
1138     current = g_hash_table_lookup (metadata, &self->shot_sets_uids[i]);
1139     if (current && MXF_IS_DMS1_SHOT (current)) {
1140       self->shot_sets[i] = MXF_DMS1_SHOT (current);
1141     }
1142   }
1143
1144   for (i = 0; i < self->n_device_parameters_sets; i++) {
1145     current =
1146         g_hash_table_lookup (metadata, &self->device_parameters_sets_uids[i]);
1147     if (current && MXF_IS_DMS1_DEVICE_PARAMETERS (current)) {
1148       self->device_parameters_sets[i] = MXF_DMS1_DEVICE_PARAMETERS (current);
1149     }
1150   }
1151
1152   current = g_hash_table_lookup (metadata, &self->processing_set_uid);
1153   if (current && MXF_IS_DMS1_PROCESSING (current)) {
1154     self->processing_set = MXF_DMS1_PROCESSING (current);
1155   }
1156
1157   return
1158       MXF_METADATA_BASE_CLASS (mxf_dms1_clip_framework_parent_class)->resolve
1159       (m, metadata);
1160 }
1161
1162 static gboolean
1163 mxf_dms1_clip_framework_handle_tag (MXFMetadataBase * metadata,
1164     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
1165     guint tag_size)
1166 {
1167   MXFDMS1ClipFramework *self = MXF_DMS1_CLIP_FRAMEWORK (metadata);
1168   gboolean ret = TRUE;
1169 #ifndef GST_DISABLE_GST_DEBUG
1170   gchar str[96];
1171 #endif
1172   MXFUL *tag_ul = NULL;
1173   static const guint8 clip_kind_ul[] = {
1174     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03,
1175     0x02, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00
1176   };
1177   static const guint8 clip_number_ul[] = {
1178     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x01,
1179     0x05, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00
1180   };
1181   static const guint8 extended_clip_id_ul[] = {
1182     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x01,
1183     0x01, 0x15, 0x09, 0x00, 0x00, 0x00, 0x00
1184   };
1185   static const guint8 clip_creation_date_and_time_ul[] = {
1186     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x07,
1187     0x02, 0x01, 0x10, 0x01, 0x04, 0x00, 0x00
1188   };
1189   static const guint8 take_number_ul[] = {
1190     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x01,
1191     0x05, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00
1192   };
1193   static const guint8 slate_information_ul[] = {
1194     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x03,
1195     0x02, 0x05, 0x03, 0x00, 0x00, 0x00, 0x00
1196   };
1197   static const guint8 scripting_sets_ul[] = {
1198     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
1199     0x01, 0x01, 0x04, 0x05, 0x40, 0x0f, 0x00
1200   };
1201   static const guint8 shot_sets_ul[] = {
1202     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
1203     0x01, 0x01, 0x04, 0x05, 0x40, 0x11, 0x02
1204   };
1205   static const guint8 device_parameters_sets_ul[] = {
1206     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
1207     0x01, 0x01, 0x04, 0x05, 0x40, 0x1e, 0x00
1208   };
1209   static const guint8 processing_set_ul[] = {
1210     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
1211     0x01, 0x01, 0x04, 0x02, 0x40, 0x20, 0x00
1212   };
1213
1214   if (!(tag_ul =
1215           (MXFUL *) g_hash_table_lookup (primer->mappings,
1216               GUINT_TO_POINTER (((guint) tag)))))
1217     return FALSE;
1218
1219   if (memcmp (tag_ul, &clip_kind_ul, 16) == 0) {
1220     self->clip_kind = mxf_utf16_to_utf8 (tag_data, tag_size);
1221     GST_DEBUG ("  clip kind = %s", GST_STR_NULL (self->clip_kind));
1222   } else if (memcmp (tag_ul, &clip_number_ul, 16) == 0) {
1223     if (tag_size > 32)
1224       goto error;
1225
1226     memcpy (self->clip_number, tag_data, tag_size);
1227     GST_DEBUG ("  clip number = %s", self->clip_number);
1228   } else if (memcmp (tag_ul, &extended_clip_id_ul, 16) == 0) {
1229     if (tag_size != 32 && tag_size != 64)
1230       goto error;
1231
1232     memcpy (self->extended_clip_id, tag_data, tag_size);
1233     self->extended_clip_id_full = (tag_size == 64);
1234
1235     GST_DEBUG ("  extended clip id (1) = %s",
1236         mxf_umid_to_string ((MXFUMID *) & self->extended_clip_id, str));
1237     if (tag_size == 64)
1238       GST_DEBUG ("  extended clip id (2) = %s",
1239           mxf_umid_to_string ((MXFUMID *) & self->extended_clip_id[32], str));
1240   } else if (memcmp (tag_ul, &clip_creation_date_and_time_ul, 16) == 0) {
1241     if (!mxf_timestamp_parse (&self->clip_creation_date_and_time, tag_data,
1242             tag_size))
1243       goto error;
1244     GST_DEBUG ("  clip creation date and time = %s",
1245         mxf_timestamp_to_string (&self->clip_creation_date_and_time, str));
1246   } else if (memcmp (tag_ul, &take_number_ul, 16) == 0) {
1247     if (tag_size != 2)
1248       goto error;
1249
1250     self->take_number = GST_READ_UINT16_BE (tag_data);
1251     GST_DEBUG ("  take number = %u", self->take_number);
1252   } else if (memcmp (tag_ul, &slate_information_ul, 16) == 0) {
1253     self->slate_information = mxf_utf16_to_utf8 (tag_data, tag_size);
1254     GST_DEBUG ("  slate information = %s",
1255         GST_STR_NULL (self->slate_information));
1256   } else if (memcmp (tag_ul, &scripting_sets_ul, 16) == 0) {
1257     if (!mxf_uuid_array_parse (&self->scripting_sets_uids,
1258             &self->n_scripting_sets, tag_data, tag_size))
1259       goto error;
1260     GST_DEBUG ("  number of scripting sets = %u", self->n_scripting_sets);
1261 #ifndef GST_DISABLE_GST_DEBUG
1262     {
1263       guint i;
1264       for (i = 0; i < self->n_scripting_sets; i++) {
1265         GST_DEBUG ("    scripting sets %u = %s", i,
1266             mxf_uuid_to_string (&self->scripting_sets_uids[i], str));
1267       }
1268     }
1269 #endif
1270   } else if (memcmp (tag_ul, &shot_sets_ul, 16) == 0) {
1271     if (!mxf_uuid_array_parse (&self->shot_sets_uids, &self->n_shot_sets,
1272             tag_data, tag_size))
1273       goto error;
1274     GST_DEBUG ("  number of shot sets = %u", self->n_shot_sets);
1275 #ifndef GST_DISABLE_GST_DEBUG
1276     {
1277       guint i;
1278       for (i = 0; i < self->n_shot_sets; i++) {
1279         GST_DEBUG ("    shot sets %u = %s", i,
1280             mxf_uuid_to_string (&self->shot_sets_uids[i], str));
1281       }
1282     }
1283 #endif
1284   } else if (memcmp (tag_ul, &device_parameters_sets_ul, 16) == 0) {
1285     if (!mxf_uuid_array_parse (&self->device_parameters_sets_uids,
1286             &self->n_device_parameters_sets, tag_data, tag_size))
1287       goto error;
1288     GST_DEBUG ("  number of device parameters sets = %u",
1289         self->n_device_parameters_sets);
1290 #ifndef GST_DISABLE_GST_DEBUG
1291     {
1292       guint i;
1293       for (i = 0; i < self->n_device_parameters_sets; i++) {
1294         GST_DEBUG ("    device parameters sets %u = %s", i,
1295             mxf_uuid_to_string (&self->device_parameters_sets_uids[i], str));
1296       }
1297     }
1298 #endif
1299   } else if (memcmp (tag_ul, &processing_set_ul, 16) == 0) {
1300     if (tag_size != 16)
1301       goto error;
1302
1303     memcpy (&self->processing_set_uid, tag_data, 16);
1304     GST_DEBUG ("  processing set = %s",
1305         mxf_uuid_to_string (&self->processing_set_uid, str));
1306   } else {
1307     ret =
1308         MXF_METADATA_BASE_CLASS
1309         (mxf_dms1_clip_framework_parent_class)->handle_tag (metadata, primer,
1310         tag, tag_data, tag_size);
1311   }
1312
1313   return ret;
1314
1315 error:
1316
1317   GST_ERROR ("Invalid DMS1 clip framework local tag 0x%04x of size %u", tag,
1318       tag_size);
1319
1320   return FALSE;
1321 }
1322
1323 static void
1324 mxf_dms1_clip_framework_init (MXFDMS1ClipFramework * self)
1325 {
1326 }
1327
1328 static void
1329 mxf_dms1_clip_framework_class_init (MXFDMS1ClipFrameworkClass * klass)
1330 {
1331   GObjectClass *object_class = (GObjectClass *) klass;
1332   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
1333   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
1334
1335   object_class->finalize = mxf_dms1_clip_framework_finalize;
1336   metadatabase_class->handle_tag = mxf_dms1_clip_framework_handle_tag;
1337   metadatabase_class->resolve = mxf_dms1_clip_framework_resolve;
1338   dm_class->type = 0x010200;
1339 }
1340
1341 G_DEFINE_TYPE (MXFDMS1SceneFramework, mxf_dms1_scene_framework,
1342     MXF_TYPE_DMS1_FRAMEWORK);
1343
1344 static void
1345 mxf_dms1_scene_framework_finalize (GObject * object)
1346 {
1347   MXFDMS1SceneFramework *self = MXF_DMS1_SCENE_FRAMEWORK (object);
1348
1349   g_free (self->setting_period_sets_uids);
1350   self->setting_period_sets_uids = NULL;
1351
1352   g_free (self->setting_period_sets);
1353   self->setting_period_sets = NULL;
1354
1355   g_free (self->shot_scene_sets_uids);
1356   self->shot_scene_sets_uids = NULL;
1357
1358   g_free (self->shot_scene_sets);
1359   self->shot_scene_sets = NULL;
1360
1361   G_OBJECT_CLASS (mxf_dms1_scene_framework_parent_class)->finalize (object);
1362 }
1363
1364 static gboolean
1365 mxf_dms1_scene_framework_resolve (MXFMetadataBase * m, GHashTable * metadata)
1366 {
1367   MXFDMS1SceneFramework *self = MXF_DMS1_SCENE_FRAMEWORK (m);
1368   MXFMetadataBase *current = NULL;
1369   guint i;
1370
1371   if (self->setting_period_sets)
1372     memset (self->setting_period_sets, 0,
1373         sizeof (gpointer) * self->n_setting_period_sets);
1374   else
1375     self->setting_period_sets =
1376         g_new0 (MXFDMS1SettingPeriod *, self->n_setting_period_sets);
1377
1378   if (self->shot_scene_sets)
1379     memset (self->shot_scene_sets, 0,
1380         sizeof (gpointer) * self->n_shot_scene_sets);
1381   else
1382     self->shot_scene_sets = g_new0 (MXFDMS1Shot *, self->n_shot_scene_sets);
1383
1384   for (i = 0; i < self->n_setting_period_sets; i++) {
1385     current =
1386         g_hash_table_lookup (metadata, &self->setting_period_sets_uids[i]);
1387     if (current && MXF_IS_DMS1_SETTING_PERIOD (current)) {
1388       self->setting_period_sets[i] = MXF_DMS1_SETTING_PERIOD (current);
1389     }
1390   }
1391
1392   for (i = 0; i < self->n_shot_scene_sets; i++) {
1393     current = g_hash_table_lookup (metadata, &self->shot_scene_sets_uids[i]);
1394     if (current && MXF_IS_DMS1_SHOT (current)) {
1395       self->shot_scene_sets[i] = MXF_DMS1_SHOT (current);
1396     }
1397   }
1398
1399   return
1400       MXF_METADATA_BASE_CLASS (mxf_dms1_scene_framework_parent_class)->resolve
1401       (m, metadata);
1402 }
1403
1404 static gboolean
1405 mxf_dms1_scene_framework_handle_tag (MXFMetadataBase * metadata,
1406     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
1407     guint tag_size)
1408 {
1409   MXFDMS1SceneFramework *self = MXF_DMS1_SCENE_FRAMEWORK (metadata);
1410   gboolean ret = TRUE;
1411 #ifndef GST_DISABLE_GST_DEBUG
1412   gchar str[48];
1413 #endif
1414   MXFUL *tag_ul = NULL;
1415   static const guint8 scene_number_ul[] = {
1416     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x01,
1417     0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00
1418   };
1419   static const guint8 setting_period_sets_ul[] = {
1420     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
1421     0x01, 0x01, 0x04, 0x05, 0x40, 0x0e, 0x02
1422   };
1423   static const guint8 shot_scene_sets_ul[] = {
1424     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
1425     0x01, 0x01, 0x04, 0x05, 0x40, 0x11, 0x01
1426   };
1427
1428   if (!(tag_ul =
1429           (MXFUL *) g_hash_table_lookup (primer->mappings,
1430               GUINT_TO_POINTER (((guint) tag)))))
1431     return FALSE;
1432
1433   if (memcmp (tag_ul, &scene_number_ul, 16) == 0) {
1434     if (tag_size > 32)
1435       goto error;
1436
1437     memcpy (self->scene_number, tag_data, tag_size);
1438     GST_DEBUG ("  scene number = %s", self->scene_number);
1439   } else if (memcmp (tag_ul, &setting_period_sets_ul, 16) == 0) {
1440     if (!mxf_uuid_array_parse (&self->setting_period_sets_uids,
1441             &self->n_setting_period_sets, tag_data, tag_size))
1442       goto error;
1443     GST_DEBUG ("  number of setting period sets = %u",
1444         self->n_setting_period_sets);
1445 #ifndef GST_DISABLE_GST_DEBUG
1446     {
1447       guint i;
1448       for (i = 0; i < self->n_setting_period_sets; i++) {
1449         GST_DEBUG ("    setting period sets %u = %s", i,
1450             mxf_uuid_to_string (&self->setting_period_sets_uids[i], str));
1451       }
1452     }
1453 #endif
1454   } else if (memcmp (tag_ul, &shot_scene_sets_ul, 16) == 0) {
1455     if (!mxf_uuid_array_parse (&self->shot_scene_sets_uids,
1456             &self->n_shot_scene_sets, tag_data, tag_size))
1457       goto error;
1458     GST_DEBUG ("  number of shot sets = %u", self->n_shot_scene_sets);
1459 #ifndef GST_DISABLE_GST_DEBUG
1460     {
1461       guint i;
1462       for (i = 0; i < self->n_shot_scene_sets; i++) {
1463         GST_DEBUG ("    shot sets %u = %s", i,
1464             mxf_uuid_to_string (&self->shot_scene_sets_uids[i], str));
1465       }
1466     }
1467 #endif
1468   } else {
1469     ret =
1470         MXF_METADATA_BASE_CLASS
1471         (mxf_dms1_scene_framework_parent_class)->handle_tag (metadata, primer,
1472         tag, tag_data, tag_size);
1473   }
1474
1475   return ret;
1476
1477 error:
1478
1479   GST_ERROR ("Invalid DMS1 scene framework local tag 0x%04x of size %u", tag,
1480       tag_size);
1481
1482   return FALSE;
1483 }
1484
1485 static void
1486 mxf_dms1_scene_framework_init (MXFDMS1SceneFramework * self)
1487 {
1488 }
1489
1490 static void
1491 mxf_dms1_scene_framework_class_init (MXFDMS1SceneFrameworkClass * klass)
1492 {
1493   GObjectClass *object_class = (GObjectClass *) klass;
1494   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
1495   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
1496
1497   object_class->finalize = mxf_dms1_scene_framework_finalize;
1498   metadatabase_class->handle_tag = mxf_dms1_scene_framework_handle_tag;
1499   metadatabase_class->resolve = mxf_dms1_scene_framework_resolve;
1500   dm_class->type = 0x010300;
1501 }
1502
1503 G_DEFINE_TYPE (MXFDMS1Titles, mxf_dms1_titles, MXF_TYPE_DMS1_TEXT_LANGUAGE);
1504
1505 static void
1506 mxf_dms1_titles_finalize (GObject * object)
1507 {
1508   MXFDMS1Titles *self = MXF_DMS1_TITLES (object);
1509
1510   g_free (self->main_title);
1511   self->main_title = NULL;
1512
1513   g_free (self->secondary_title);
1514   self->secondary_title = NULL;
1515
1516   g_free (self->working_title);
1517   self->working_title = NULL;
1518
1519   g_free (self->original_title);
1520   self->original_title = NULL;
1521
1522   g_free (self->version_title);
1523   self->version_title = NULL;
1524
1525   G_OBJECT_CLASS (mxf_dms1_titles_parent_class)->finalize (object);
1526 }
1527
1528 static gboolean
1529 mxf_dms1_titles_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer,
1530     guint16 tag, const guint8 * tag_data, guint tag_size)
1531 {
1532   MXFDMS1Titles *self = MXF_DMS1_TITLES (metadata);
1533   gboolean ret = TRUE;
1534   MXFUL *tag_ul = NULL;
1535   static const guint8 main_title_ul[] = {
1536     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x01,
1537     0x05, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00
1538   };
1539   static const guint8 secondary_title_ul[] = {
1540     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x01,
1541     0x05, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00
1542   };
1543   static const guint8 working_title_ul[] = {
1544     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x01,
1545     0x05, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00
1546   };
1547   static const guint8 original_title_ul[] = {
1548     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x01,
1549     0x05, 0x0b, 0x01, 0x00, 0x00, 0x00, 0x00
1550   };
1551   static const guint8 version_title_ul[] = {
1552     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x01,
1553     0x05, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00
1554   };
1555
1556   if (!(tag_ul =
1557           (MXFUL *) g_hash_table_lookup (primer->mappings,
1558               GUINT_TO_POINTER (((guint) tag)))))
1559     return FALSE;
1560
1561   if (memcmp (tag_ul, &main_title_ul, 16) == 0) {
1562     self->main_title = mxf_utf16_to_utf8 (tag_data, tag_size);
1563     GST_DEBUG ("  main title = %s", GST_STR_NULL (self->main_title));
1564   } else if (memcmp (tag_ul, &secondary_title_ul, 16) == 0) {
1565     self->secondary_title = mxf_utf16_to_utf8 (tag_data, tag_size);
1566     GST_DEBUG ("  secondary title = %s", GST_STR_NULL (self->secondary_title));
1567   } else if (memcmp (tag_ul, &working_title_ul, 16) == 0) {
1568     self->working_title = mxf_utf16_to_utf8 (tag_data, tag_size);
1569     GST_DEBUG ("  working title = %s", GST_STR_NULL (self->working_title));
1570   } else if (memcmp (tag_ul, &original_title_ul, 16) == 0) {
1571     self->original_title = mxf_utf16_to_utf8 (tag_data, tag_size);
1572     GST_DEBUG ("  original title = %s", GST_STR_NULL (self->original_title));
1573   } else if (memcmp (tag_ul, &version_title_ul, 16) == 0) {
1574     self->version_title = mxf_utf16_to_utf8 (tag_data, tag_size);
1575     GST_DEBUG ("  version title = %s", GST_STR_NULL (self->version_title));
1576   } else {
1577     ret =
1578         MXF_METADATA_BASE_CLASS (mxf_dms1_titles_parent_class)->handle_tag
1579         (metadata, primer, tag, tag_data, tag_size);
1580   }
1581
1582   return ret;
1583 }
1584
1585 static void
1586 mxf_dms1_titles_init (MXFDMS1Titles * self)
1587 {
1588 }
1589
1590 static void
1591 mxf_dms1_titles_class_init (MXFDMS1TitlesClass * klass)
1592 {
1593   GObjectClass *object_class = (GObjectClass *) klass;
1594   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
1595   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
1596
1597   object_class->finalize = mxf_dms1_titles_finalize;
1598   metadatabase_class->handle_tag = mxf_dms1_titles_handle_tag;
1599   dm_class->type = 0x100100;
1600 }
1601
1602 G_DEFINE_TYPE (MXFDMS1Identification, mxf_dms1_identification,
1603     MXF_TYPE_DMS1_THESAURUS);
1604
1605 static void
1606 mxf_dms1_identification_finalize (GObject * object)
1607 {
1608   MXFDMS1Identification *self = MXF_DMS1_IDENTIFICATION (object);
1609
1610   g_free (self->identifier_value);
1611   self->identifier_value = NULL;
1612
1613   g_free (self->identification_issuing_authority);
1614   self->identification_issuing_authority = NULL;
1615
1616   G_OBJECT_CLASS (mxf_dms1_identification_parent_class)->finalize (object);
1617 }
1618
1619 static gboolean
1620 mxf_dms1_identification_handle_tag (MXFMetadataBase * metadata,
1621     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
1622     guint tag_size)
1623 {
1624   MXFDMS1Identification *self = MXF_DMS1_IDENTIFICATION (metadata);
1625 #ifndef GST_DISABLE_GST_DEBUG
1626   gchar str[48];
1627 #endif
1628   gboolean ret = TRUE;
1629   MXFUL *tag_ul = NULL;
1630   static const guint8 identifier_kind_ul[] = {
1631     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x01,
1632     0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
1633   };
1634   static const guint8 identifier_value_ul[] = {
1635     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x01,
1636     0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00
1637   };
1638   static const guint8 identification_locator_ul[] = {
1639     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x01,
1640     0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00
1641   };
1642   static const guint8 identification_issuing_authority_ul[] = {
1643     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x02,
1644     0x0a, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00
1645   };
1646
1647   if (!(tag_ul =
1648           (MXFUL *) g_hash_table_lookup (primer->mappings,
1649               GUINT_TO_POINTER (((guint) tag)))))
1650     return FALSE;
1651
1652   if (memcmp (tag_ul, &identifier_kind_ul, 16) == 0) {
1653     if (tag_size > 32)
1654       goto error;
1655
1656     memcpy (self->identifier_kind, tag_data, tag_size);
1657     GST_DEBUG ("  identifier kind = %s", self->identifier_kind);
1658   } else if (memcmp (tag_ul, &identifier_value_ul, 16) == 0) {
1659     self->identifier_value = g_memdup (tag_data, tag_size);
1660     self->identifier_value_length = tag_size;
1661     GST_DEBUG ("  identifier value length = %u", tag_size);
1662   } else if (memcmp (tag_ul, &identification_locator_ul, 16) == 0) {
1663     if (tag_size != 16)
1664       goto error;
1665
1666     memcpy (&self->identification_locator, tag_data, 16);
1667
1668     GST_DEBUG ("  identification locator = %s",
1669         mxf_uuid_to_string (&self->identification_locator, str));
1670   } else if (memcmp (tag_ul, &identification_issuing_authority_ul, 16) == 0) {
1671     self->identification_issuing_authority =
1672         mxf_utf16_to_utf8 (tag_data, tag_size);
1673     GST_DEBUG ("  identification issuing authority = %s",
1674         GST_STR_NULL (self->identification_issuing_authority));
1675   } else {
1676     ret =
1677         MXF_METADATA_BASE_CLASS
1678         (mxf_dms1_identification_parent_class)->handle_tag (metadata, primer,
1679         tag, tag_data, tag_size);
1680   }
1681
1682   return ret;
1683
1684 error:
1685
1686   GST_ERROR ("Invalid DMS1 identification local tag 0x%04x of size %u", tag,
1687       tag_size);
1688
1689   return FALSE;
1690 }
1691
1692 static void
1693 mxf_dms1_identification_init (MXFDMS1Identification * self)
1694 {
1695 }
1696
1697 static void
1698 mxf_dms1_identification_class_init (MXFDMS1IdentificationClass * klass)
1699 {
1700   GObjectClass *object_class = (GObjectClass *) klass;
1701   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
1702   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
1703
1704   object_class->finalize = mxf_dms1_identification_finalize;
1705   metadatabase_class->handle_tag = mxf_dms1_identification_handle_tag;
1706   dm_class->type = 0x110100;
1707 }
1708
1709 G_DEFINE_TYPE (MXFDMS1GroupRelationship, mxf_dms1_group_relationship,
1710     MXF_TYPE_DMS1_THESAURUS);
1711
1712 static void
1713 mxf_dms1_group_relationship_finalize (GObject * object)
1714 {
1715   MXFDMS1GroupRelationship *self = MXF_DMS1_GROUP_RELATIONSHIP (object);
1716
1717   g_free (self->programming_group_kind);
1718   self->programming_group_kind = NULL;
1719
1720   g_free (self->programming_group_title);
1721   self->programming_group_title = NULL;
1722
1723   g_free (self->group_synopsis);
1724   self->group_synopsis = NULL;
1725
1726   G_OBJECT_CLASS (mxf_dms1_group_relationship_parent_class)->finalize (object);
1727 }
1728
1729 static gboolean
1730 mxf_dms1_group_relationship_handle_tag (MXFMetadataBase * metadata,
1731     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
1732     guint tag_size)
1733 {
1734   MXFDMS1GroupRelationship *self = MXF_DMS1_GROUP_RELATIONSHIP (metadata);
1735   gboolean ret = TRUE;
1736   MXFUL *tag_ul = NULL;
1737   static const guint8 programming_group_kind_ul[] = {
1738     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x02,
1739     0x02, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00
1740   };
1741   static const guint8 programming_group_title_ul[] = {
1742     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x02,
1743     0x02, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00
1744   };
1745   static const guint8 group_synopsis_ul[] = {
1746     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03,
1747     0x02, 0x01, 0x06, 0x08, 0x01, 0x00, 0x00
1748   };
1749   static const guint8 numerical_position_in_sequence_ul[] = {
1750     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x06,
1751     0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
1752   };
1753   static const guint8 total_number_in_the_sequence_ul[] = {
1754     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
1755     0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00
1756   };
1757   static const guint8 episodic_start_number_ul[] = {
1758     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x02,
1759     0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00
1760   };
1761   static const guint8 episodic_end_number_ul[] = {
1762     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x02,
1763     0x02, 0x05, 0x02, 0x03, 0x01, 0x00, 0x00
1764   };
1765
1766   if (!(tag_ul =
1767           (MXFUL *) g_hash_table_lookup (primer->mappings,
1768               GUINT_TO_POINTER (((guint) tag)))))
1769     return FALSE;
1770
1771   if (memcmp (tag_ul, &programming_group_kind_ul, 16) == 0) {
1772     self->programming_group_kind = mxf_utf16_to_utf8 (tag_data, tag_size);
1773     GST_DEBUG ("  programming group kind = %s",
1774         GST_STR_NULL (self->programming_group_kind));
1775   } else if (memcmp (tag_ul, &programming_group_title_ul, 16) == 0) {
1776     self->programming_group_title = mxf_utf16_to_utf8 (tag_data, tag_size);
1777     GST_DEBUG ("  programming group title = %s",
1778         GST_STR_NULL (self->programming_group_title));
1779   } else if (memcmp (tag_ul, &group_synopsis_ul, 16) == 0) {
1780     self->group_synopsis = mxf_utf16_to_utf8 (tag_data, tag_size);
1781     GST_DEBUG ("  group synopsis = %s", GST_STR_NULL (self->group_synopsis));
1782   } else if (memcmp (tag_ul, &numerical_position_in_sequence_ul, 16) == 0) {
1783     if (tag_size != 4)
1784       goto error;
1785
1786     self->numerical_position_in_sequence = GST_READ_UINT32_BE (tag_data);
1787     GST_DEBUG ("  numerical position in sequence = %u",
1788         self->numerical_position_in_sequence);
1789   } else if (memcmp (tag_ul, &total_number_in_the_sequence_ul, 16) == 0) {
1790     if (tag_size != 4)
1791       goto error;
1792
1793     self->total_number_in_the_sequence = GST_READ_UINT32_BE (tag_data);
1794     GST_DEBUG ("  total number in the sequence = %u",
1795         self->total_number_in_the_sequence);
1796   } else if (memcmp (tag_ul, &episodic_start_number_ul, 16) == 0) {
1797     if (tag_size != 2)
1798       goto error;
1799
1800     self->episodic_start_number = GST_READ_UINT16_BE (tag_data);
1801     GST_DEBUG ("  episodic start number = %u", self->episodic_start_number);
1802   } else if (memcmp (tag_ul, &episodic_end_number_ul, 16) == 0) {
1803     if (tag_size != 2)
1804       goto error;
1805
1806     self->episodic_end_number = GST_READ_UINT16_BE (tag_data);
1807     GST_DEBUG ("  episodic end number = %u", self->episodic_end_number);
1808   } else {
1809     ret =
1810         MXF_METADATA_BASE_CLASS
1811         (mxf_dms1_group_relationship_parent_class)->handle_tag (metadata,
1812         primer, tag, tag_data, tag_size);
1813   }
1814
1815   return ret;
1816
1817 error:
1818
1819   GST_ERROR ("Invalid DMS1 group relationship local tag 0x%04x of size %u", tag,
1820       tag_size);
1821
1822   return FALSE;
1823 }
1824
1825 static void
1826 mxf_dms1_group_relationship_init (MXFDMS1GroupRelationship * self)
1827 {
1828 }
1829
1830 static void
1831 mxf_dms1_group_relationship_class_init (MXFDMS1GroupRelationshipClass * klass)
1832 {
1833   GObjectClass *object_class = (GObjectClass *) klass;
1834   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
1835   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
1836
1837   object_class->finalize = mxf_dms1_group_relationship_finalize;
1838   metadatabase_class->handle_tag = mxf_dms1_group_relationship_handle_tag;
1839   dm_class->type = 0x120100;
1840 }
1841
1842 G_DEFINE_TYPE (MXFDMS1Branding, mxf_dms1_branding, MXF_TYPE_DMS1_TEXT_LANGUAGE);
1843
1844 static void
1845 mxf_dms1_branding_finalize (GObject * object)
1846 {
1847   MXFDMS1Branding *self = MXF_DMS1_BRANDING (object);
1848
1849   g_free (self->brand_main_title);
1850   self->brand_main_title = NULL;
1851
1852   g_free (self->brand_original_title);
1853   self->brand_original_title = NULL;
1854
1855   G_OBJECT_CLASS (mxf_dms1_branding_parent_class)->finalize (object);
1856 }
1857
1858 static gboolean
1859 mxf_dms1_branding_handle_tag (MXFMetadataBase * metadata,
1860     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
1861     guint tag_size)
1862 {
1863   MXFDMS1Branding *self = MXF_DMS1_BRANDING (metadata);
1864   gboolean ret = TRUE;
1865   MXFUL *tag_ul = NULL;
1866   static const guint8 brand_main_title_ul[] = {
1867     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x01,
1868     0x05, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00
1869   };
1870   static const guint8 brand_original_title_ul[] = {
1871     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x01,
1872     0x05, 0x0E, 0x01, 0x00, 0x00, 0x00, 0x00
1873   };
1874
1875   if (!(tag_ul =
1876           (MXFUL *) g_hash_table_lookup (primer->mappings,
1877               GUINT_TO_POINTER (((guint) tag)))))
1878     return FALSE;
1879
1880   if (memcmp (tag_ul, &brand_main_title_ul, 16) == 0) {
1881     self->brand_main_title = mxf_utf16_to_utf8 (tag_data, tag_size);
1882     GST_DEBUG ("  brand main title = %s",
1883         GST_STR_NULL (self->brand_main_title));
1884   } else if (memcmp (tag_ul, &brand_original_title_ul, 16) == 0) {
1885     self->brand_original_title = mxf_utf16_to_utf8 (tag_data, tag_size);
1886     GST_DEBUG ("  brand original title = %s",
1887         GST_STR_NULL (self->brand_original_title));
1888   } else {
1889     ret =
1890         MXF_METADATA_BASE_CLASS (mxf_dms1_branding_parent_class)->handle_tag
1891         (metadata, primer, tag, tag_data, tag_size);
1892   }
1893
1894   return ret;
1895 }
1896
1897 static void
1898 mxf_dms1_branding_init (MXFDMS1Branding * self)
1899 {
1900 }
1901
1902 static void
1903 mxf_dms1_branding_class_init (MXFDMS1BrandingClass * klass)
1904 {
1905   GObjectClass *object_class = (GObjectClass *) klass;
1906   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
1907   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
1908
1909   object_class->finalize = mxf_dms1_branding_finalize;
1910   metadatabase_class->handle_tag = mxf_dms1_branding_handle_tag;
1911   dm_class->type = 0x130100;
1912 }
1913
1914 G_DEFINE_TYPE (MXFDMS1Event, mxf_dms1_event, MXF_TYPE_DMS1_THESAURUS);
1915
1916 static void
1917 mxf_dms1_event_finalize (GObject * object)
1918 {
1919   MXFDMS1Event *self = MXF_DMS1_EVENT (object);
1920
1921   g_free (self->event_indication);
1922   self->event_indication = NULL;
1923
1924   g_free (self->publication_sets_uids);
1925   self->publication_sets_uids = NULL;
1926
1927   g_free (self->publication_sets);
1928   self->publication_sets = NULL;
1929
1930   g_free (self->annotation_sets_uids);
1931   self->annotation_sets_uids = NULL;
1932
1933   g_free (self->annotation_sets);
1934   self->annotation_sets = NULL;
1935
1936   G_OBJECT_CLASS (mxf_dms1_event_parent_class)->finalize (object);
1937 }
1938
1939 static gboolean
1940 mxf_dms1_event_resolve (MXFMetadataBase * m, GHashTable * metadata)
1941 {
1942   MXFDMS1Event *self = MXF_DMS1_EVENT (m);
1943   MXFMetadataBase *current = NULL;
1944   guint i;
1945
1946   if (self->publication_sets)
1947     memset (self->publication_sets, 0,
1948         sizeof (gpointer) * self->n_publication_sets);
1949   else
1950     self->publication_sets =
1951         g_new0 (MXFDMS1Publication *, self->n_publication_sets);
1952
1953   if (self->annotation_sets)
1954     memset (self->annotation_sets, 0,
1955         sizeof (gpointer) * self->n_annotation_sets);
1956   else
1957     self->annotation_sets =
1958         g_new0 (MXFDMS1Annotation *, self->n_annotation_sets);
1959
1960   for (i = 0; i < self->n_publication_sets; i++) {
1961     current = g_hash_table_lookup (metadata, &self->publication_sets_uids[i]);
1962     if (current && MXF_IS_DMS1_PUBLICATION (current)) {
1963       self->publication_sets[i] = MXF_DMS1_PUBLICATION (current);
1964     }
1965   }
1966
1967   for (i = 0; i < self->n_annotation_sets; i++) {
1968     current = g_hash_table_lookup (metadata, &self->annotation_sets_uids[i]);
1969     if (current && MXF_IS_DMS1_ANNOTATION (current)) {
1970       self->annotation_sets[i] = MXF_DMS1_ANNOTATION (current);
1971     }
1972   }
1973
1974   return MXF_METADATA_BASE_CLASS (mxf_dms1_event_parent_class)->resolve (m,
1975       metadata);
1976 }
1977
1978 static gboolean
1979 mxf_dms1_event_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer,
1980     guint16 tag, const guint8 * tag_data, guint tag_size)
1981 {
1982   MXFDMS1Event *self = MXF_DMS1_EVENT (metadata);
1983   gboolean ret = TRUE;
1984 #ifndef GST_DISABLE_GST_DEBUG
1985   gchar str[48];
1986 #endif
1987   MXFUL *tag_ul = NULL;
1988   static const guint8 event_indication_ul[] = {
1989     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x05,
1990     0x01, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00
1991   };
1992   static const guint8 event_start_date_and_time_ul[] = {
1993     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x07,
1994     0x02, 0x01, 0x02, 0x07, 0x02, 0x00, 0x00
1995   };
1996   static const guint8 event_end_date_and_time_ul[] = {
1997     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x07,
1998     0x02, 0x01, 0x02, 0x09, 0x02, 0x00, 0x00
1999   };
2000   static const guint8 publication_sets_ul[] = {
2001     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
2002     0x01, 0x01, 0x04, 0x05, 0x40, 0x0a, 0x00
2003   };
2004   static const guint8 annotation_sets_ul[] = {
2005     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08, 0x06,
2006     0x01, 0x01, 0x04, 0x05, 0x40, 0x0d, 0x01
2007   };
2008
2009   if (!(tag_ul =
2010           (MXFUL *) g_hash_table_lookup (primer->mappings,
2011               GUINT_TO_POINTER (((guint) tag)))))
2012     return FALSE;
2013
2014   if (memcmp (tag_ul, &event_indication_ul, 16) == 0) {
2015     self->event_indication = mxf_utf16_to_utf8 (tag_data, tag_size);
2016     GST_DEBUG ("  event indication = %s",
2017         GST_STR_NULL (self->event_indication));
2018   } else if (memcmp (tag_ul, &event_start_date_and_time_ul, 16) == 0) {
2019     if (tag_size > 32)
2020       goto error;
2021
2022     memcpy (self->event_start_date_and_time, tag_data, tag_size);
2023     GST_DEBUG ("  event start date and time = %s",
2024         self->event_start_date_and_time);
2025   } else if (memcmp (tag_ul, &event_end_date_and_time_ul, 16) == 0) {
2026     if (tag_size > 32)
2027       goto error;
2028
2029     memcpy (self->event_end_date_and_time, tag_data, tag_size);
2030     GST_DEBUG ("  event end date and time = %s", self->event_end_date_and_time);
2031   } else if (memcmp (tag_ul, &publication_sets_ul, 16) == 0) {
2032     if (!mxf_uuid_array_parse (&self->publication_sets_uids,
2033             &self->n_publication_sets, tag_data, tag_size))
2034       goto error;
2035     GST_DEBUG ("  number of publication sets = %u", self->n_publication_sets);
2036 #ifndef GST_DISABLE_GST_DEBUG
2037     {
2038       guint i;
2039       for (i = 0; i < self->n_publication_sets; i++) {
2040         GST_DEBUG ("    publication sets %u = %s", i,
2041             mxf_uuid_to_string (&self->publication_sets_uids[i], str));
2042       }
2043     }
2044 #endif
2045   } else if (memcmp (tag_ul, &annotation_sets_ul, 16) == 0) {
2046     if (!mxf_uuid_array_parse (&self->annotation_sets_uids,
2047             &self->n_annotation_sets, tag_data, tag_size))
2048       goto error;
2049     GST_DEBUG ("  number of annotation sets = %u", self->n_annotation_sets);
2050 #ifndef GST_DISABLE_GST_DEBUG
2051     {
2052       guint i;
2053       for (i = 0; i < self->n_annotation_sets; i++) {
2054         GST_DEBUG ("    annotation sets %u = %s", i,
2055             mxf_uuid_to_string (&self->annotation_sets_uids[i], str));
2056       }
2057     }
2058 #endif
2059   } else {
2060     ret =
2061         MXF_METADATA_BASE_CLASS (mxf_dms1_event_parent_class)->handle_tag
2062         (metadata, primer, tag, tag_data, tag_size);
2063   }
2064
2065   return ret;
2066
2067 error:
2068
2069   GST_ERROR ("Invalid DMS1 event local tag 0x%04x of size %u", tag, tag_size);
2070
2071   return FALSE;
2072 }
2073
2074 static void
2075 mxf_dms1_event_init (MXFDMS1Event * self)
2076 {
2077 }
2078
2079 static void
2080 mxf_dms1_event_class_init (MXFDMS1EventClass * klass)
2081 {
2082   GObjectClass *object_class = (GObjectClass *) klass;
2083   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
2084   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
2085
2086   object_class->finalize = mxf_dms1_event_finalize;
2087   metadatabase_class->handle_tag = mxf_dms1_event_handle_tag;
2088   metadatabase_class->resolve = mxf_dms1_event_resolve;
2089   dm_class->type = 0x140100;
2090 }
2091
2092 G_DEFINE_TYPE (MXFDMS1Publication, mxf_dms1_publication, MXF_TYPE_DMS1);
2093
2094 static void
2095 mxf_dms1_publication_finalize (GObject * object)
2096 {
2097   MXFDMS1Publication *self = MXF_DMS1_PUBLICATION (object);
2098
2099   g_free (self->publication_organisation_name);
2100   self->publication_organisation_name = NULL;
2101
2102   g_free (self->publication_service_name);
2103   self->publication_service_name = NULL;
2104
2105   g_free (self->publication_medium);
2106   self->publication_medium = NULL;
2107
2108   g_free (self->publication_region);
2109   self->publication_region = NULL;
2110
2111   G_OBJECT_CLASS (mxf_dms1_publication_parent_class)->finalize (object);
2112 }
2113
2114 static gboolean
2115 mxf_dms1_publication_handle_tag (MXFMetadataBase * metadata,
2116     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
2117     guint tag_size)
2118 {
2119   MXFDMS1Publication *self = MXF_DMS1_PUBLICATION (metadata);
2120   gboolean ret = TRUE;
2121   MXFUL *tag_ul = NULL;
2122   static const guint8 publication_organisation_name_ul[] = {
2123     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x02,
2124     0x10, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00
2125   };
2126   static const guint8 publication_service_name_ul[] = {
2127     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x02,
2128     0x10, 0x02, 0x01, 0x02, 0x01, 0x00, 0x00
2129   };
2130   static const guint8 publication_medium_ul[] = {
2131     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x02,
2132     0x10, 0x02, 0x01, 0x03, 0x01, 0x00, 0x00
2133   };
2134   static const guint8 publication_region_ul[] = {
2135     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x02,
2136     0x10, 0x02, 0x01, 0x04, 0x01, 0x00, 0x00
2137   };
2138
2139   if (!(tag_ul =
2140           (MXFUL *) g_hash_table_lookup (primer->mappings,
2141               GUINT_TO_POINTER (((guint) tag)))))
2142     return FALSE;
2143
2144   if (memcmp (tag_ul, &publication_organisation_name_ul, 16) == 0) {
2145     self->publication_organisation_name =
2146         mxf_utf16_to_utf8 (tag_data, tag_size);
2147     GST_DEBUG ("  publication organisation name = %s",
2148         GST_STR_NULL (self->publication_organisation_name));
2149   } else if (memcmp (tag_ul, &publication_service_name_ul, 16) == 0) {
2150     self->publication_service_name = mxf_utf16_to_utf8 (tag_data, tag_size);
2151     GST_DEBUG (" publication service name = %s",
2152         GST_STR_NULL (self->publication_service_name));
2153   } else if (memcmp (tag_ul, &publication_medium_ul, 16) == 0) {
2154     self->publication_medium = mxf_utf16_to_utf8 (tag_data, tag_size);
2155     GST_DEBUG (" publication medium = %s",
2156         GST_STR_NULL (self->publication_medium));
2157   } else if (memcmp (tag_ul, &publication_region_ul, 16) == 0) {
2158     self->publication_region = mxf_utf16_to_utf8 (tag_data, tag_size);
2159     GST_DEBUG (" publication region = %s",
2160         GST_STR_NULL (self->publication_region));
2161   } else {
2162     ret =
2163         MXF_METADATA_BASE_CLASS (mxf_dms1_publication_parent_class)->handle_tag
2164         (metadata, primer, tag, tag_data, tag_size);
2165   }
2166
2167   return ret;
2168 }
2169
2170 static void
2171 mxf_dms1_publication_init (MXFDMS1Publication * self)
2172 {
2173 }
2174
2175 static void
2176 mxf_dms1_publication_class_init (MXFDMS1PublicationClass * klass)
2177 {
2178   GObjectClass *object_class = (GObjectClass *) klass;
2179   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
2180   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
2181
2182   object_class->finalize = mxf_dms1_publication_finalize;
2183   metadatabase_class->handle_tag = mxf_dms1_publication_handle_tag;
2184   dm_class->type = 0x140200;
2185 }
2186
2187 G_DEFINE_TYPE (MXFDMS1Award, mxf_dms1_award, MXF_TYPE_DMS1_THESAURUS);
2188
2189 static void
2190 mxf_dms1_award_finalize (GObject * object)
2191 {
2192   MXFDMS1Award *self = MXF_DMS1_AWARD (object);
2193
2194   g_free (self->festival);
2195   self->festival = NULL;
2196
2197   g_free (self->award_name);
2198   self->award_name = NULL;
2199
2200   g_free (self->award_classification);
2201   self->award_classification = NULL;
2202
2203   g_free (self->nomination_category);
2204   self->nomination_category = NULL;
2205
2206   g_free (self->participant_sets_uids);
2207   self->participant_sets_uids = NULL;
2208
2209   g_free (self->participant_sets);
2210   self->participant_sets = NULL;
2211
2212   G_OBJECT_CLASS (mxf_dms1_award_parent_class)->finalize (object);
2213 }
2214
2215 static gboolean
2216 mxf_dms1_award_resolve (MXFMetadataBase * m, GHashTable * metadata)
2217 {
2218   MXFDMS1Award *self = MXF_DMS1_AWARD (m);
2219   MXFMetadataBase *current = NULL;
2220   guint i;
2221
2222   if (self->participant_sets)
2223     memset (self->participant_sets, 0,
2224         sizeof (gpointer) * self->n_participant_sets);
2225   else
2226     self->participant_sets =
2227         g_new0 (MXFDMS1Participant *, self->n_participant_sets);
2228
2229   for (i = 0; i < self->n_participant_sets; i++) {
2230     current = g_hash_table_lookup (metadata, &self->participant_sets_uids[i]);
2231     if (current && MXF_IS_DMS1_PARTICIPANT (current)) {
2232       self->participant_sets[i] = MXF_DMS1_PARTICIPANT (current);
2233     }
2234   }
2235
2236   return MXF_METADATA_BASE_CLASS (mxf_dms1_award_parent_class)->resolve (m,
2237       metadata);
2238 }
2239
2240 static gboolean
2241 mxf_dms1_award_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer,
2242     guint16 tag, const guint8 * tag_data, guint tag_size)
2243 {
2244   MXFDMS1Award *self = MXF_DMS1_AWARD (metadata);
2245   gboolean ret = TRUE;
2246 #ifndef GST_DISABLE_GST_DEBUG
2247   gchar str[48];
2248 #endif
2249   MXFUL *tag_ul = NULL;
2250   static const guint8 festival_ul[] = {
2251     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x03,
2252     0x02, 0x02, 0x01, 0x03, 0x01, 0x00, 0x00
2253   };
2254   static const guint8 festival_date_and_time_ul[] = {
2255     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x07,
2256     0x02, 0x01, 0x02, 0x07, 0x10, 0x01, 0x00
2257   };
2258   static const guint8 award_name_ul[] = {
2259     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x03,
2260     0x02, 0x02, 0x01, 0x04, 0x01, 0x00, 0x00
2261   };
2262   static const guint8 award_classification_ul[] = {
2263     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x03,
2264     0x02, 0x02, 0x01, 0x05, 0x01, 0x00, 0x00
2265   };
2266   static const guint8 nomination_category_ul[] = {
2267     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x03,
2268     0x02, 0x02, 0x01, 0x06, 0x01, 0x00, 0x00
2269   };
2270   static const guint8 participant_sets_ul[] = {
2271     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
2272     0x01, 0x01, 0x04, 0x03, 0x40, 0x13, 0x01
2273   };
2274
2275   if (!(tag_ul =
2276           (MXFUL *) g_hash_table_lookup (primer->mappings,
2277               GUINT_TO_POINTER (((guint) tag)))))
2278     return FALSE;
2279
2280   if (memcmp (tag_ul, &festival_ul, 16) == 0) {
2281     self->festival = mxf_utf16_to_utf8 (tag_data, tag_size);
2282     GST_DEBUG ("  festival = %s", GST_STR_NULL (self->festival));
2283   } else if (memcmp (tag_ul, &festival_date_and_time_ul, 16) == 0) {
2284     if (tag_size > 32)
2285       goto error;
2286
2287     memcpy (self->festival_date_and_time, tag_data, tag_size);
2288     GST_DEBUG ("  festival date and time = %s",
2289         GST_STR_NULL (self->festival_date_and_time));
2290   } else if (memcmp (tag_ul, &award_name_ul, 16) == 0) {
2291     self->award_name = mxf_utf16_to_utf8 (tag_data, tag_size);
2292     GST_DEBUG ("  award name = %s", GST_STR_NULL (self->award_name));
2293   } else if (memcmp (tag_ul, &award_classification_ul, 16) == 0) {
2294     self->award_classification = mxf_utf16_to_utf8 (tag_data, tag_size);
2295     GST_DEBUG ("  award classification = %s",
2296         GST_STR_NULL (self->award_classification));
2297   } else if (memcmp (tag_ul, &nomination_category_ul, 16) == 0) {
2298     self->nomination_category = mxf_utf16_to_utf8 (tag_data, tag_size);
2299     GST_DEBUG ("  nomination category = %s",
2300         GST_STR_NULL (self->nomination_category));
2301   } else if (memcmp (tag_ul, &participant_sets_ul, 16) == 0) {
2302     if (!mxf_uuid_array_parse (&self->participant_sets_uids,
2303             &self->n_participant_sets, tag_data, tag_size))
2304       goto error;
2305     GST_DEBUG ("  number of participant sets = %u", self->n_participant_sets);
2306 #ifndef GST_DISABLE_GST_DEBUG
2307     {
2308       guint i;
2309       for (i = 0; i < self->n_participant_sets; i++) {
2310         GST_DEBUG ("    participant sets %u = %s", i,
2311             mxf_uuid_to_string (&self->participant_sets_uids[i], str));
2312       }
2313     }
2314 #endif
2315   } else {
2316     ret =
2317         MXF_METADATA_BASE_CLASS (mxf_dms1_award_parent_class)->handle_tag
2318         (metadata, primer, tag, tag_data, tag_size);
2319   }
2320
2321   return ret;
2322
2323 error:
2324
2325   GST_ERROR ("Invalid DMS1 award local tag 0x%04x of size %u", tag, tag_size);
2326
2327   return FALSE;
2328 }
2329
2330 static void
2331 mxf_dms1_award_init (MXFDMS1Award * self)
2332 {
2333 }
2334
2335 static void
2336 mxf_dms1_award_class_init (MXFDMS1AwardClass * klass)
2337 {
2338   GObjectClass *object_class = (GObjectClass *) klass;
2339   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
2340   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
2341
2342   object_class->finalize = mxf_dms1_award_finalize;
2343   metadatabase_class->handle_tag = mxf_dms1_award_handle_tag;
2344   metadatabase_class->resolve = mxf_dms1_award_resolve;
2345   dm_class->type = 0x150100;
2346 }
2347
2348 G_DEFINE_TYPE (MXFDMS1CaptionsDescription, mxf_dms1_captions_description,
2349     MXF_TYPE_DMS1_THESAURUS);
2350
2351 static void
2352 mxf_dms1_captions_description_finalize (GObject * object)
2353 {
2354   MXFDMS1CaptionsDescription *self = MXF_DMS1_CAPTIONS_DESCRIPTION (object);
2355
2356   g_free (self->caption_kind);
2357   self->caption_kind = NULL;
2358
2359   G_OBJECT_CLASS (mxf_dms1_captions_description_parent_class)->finalize
2360       (object);
2361 }
2362
2363 static gboolean
2364 mxf_dms1_captions_description_handle_tag (MXFMetadataBase * metadata,
2365     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
2366     guint tag_size)
2367 {
2368   MXFDMS1CaptionsDescription *self = MXF_DMS1_CAPTIONS_DESCRIPTION (metadata);
2369   gboolean ret = TRUE;
2370   MXFUL *tag_ul = NULL;
2371   static const guint8 extended_captions_language_code_ul[] = {
2372     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x03,
2373     0x01, 0x01, 0x02, 0x02, 0x12, 0x00, 0x00
2374   };
2375   static const guint8 caption_kind_ul[] = {
2376     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x04,
2377     0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00
2378   };
2379
2380   if (!(tag_ul =
2381           (MXFUL *) g_hash_table_lookup (primer->mappings,
2382               GUINT_TO_POINTER (((guint) tag)))))
2383     return FALSE;
2384
2385   if (memcmp (tag_ul, &extended_captions_language_code_ul, 16) == 0) {
2386     if (tag_size > 12)
2387       goto error;
2388
2389     memcpy (self->extended_captions_language_code, tag_data, tag_size);
2390     GST_DEBUG ("  extended captions language code = %s",
2391         self->extended_captions_language_code);
2392   } else if (memcmp (tag_ul, &caption_kind_ul, 16) == 0) {
2393     self->caption_kind = mxf_utf16_to_utf8 (tag_data, tag_size);
2394     GST_DEBUG ("  caption kind = %s", GST_STR_NULL (self->caption_kind));
2395   } else {
2396     ret =
2397         MXF_METADATA_BASE_CLASS
2398         (mxf_dms1_captions_description_parent_class)->handle_tag (metadata,
2399         primer, tag, tag_data, tag_size);
2400   }
2401
2402   return ret;
2403
2404 error:
2405
2406   GST_ERROR ("Invalid DMS1 captions description local tag 0x%04x of size %u",
2407       tag, tag_size);
2408
2409   return FALSE;
2410 }
2411
2412 static void
2413 mxf_dms1_captions_description_init (MXFDMS1CaptionsDescription * self)
2414 {
2415 }
2416
2417 static void
2418 mxf_dms1_captions_description_class_init (MXFDMS1CaptionsDescriptionClass *
2419     klass)
2420 {
2421   GObjectClass *object_class = (GObjectClass *) klass;
2422   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
2423   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
2424
2425   object_class->finalize = mxf_dms1_captions_description_finalize;
2426   metadatabase_class->handle_tag = mxf_dms1_captions_description_handle_tag;
2427   dm_class->type = 0x160100;
2428 }
2429
2430 G_DEFINE_TYPE (MXFDMS1Annotation, mxf_dms1_annotation, MXF_TYPE_DMS1_THESAURUS);
2431
2432 static void
2433 mxf_dms1_annotation_finalize (GObject * object)
2434 {
2435   MXFDMS1Annotation *self = MXF_DMS1_ANNOTATION (object);
2436
2437   g_free (self->annotation_kind);
2438   self->annotation_kind = NULL;
2439
2440   g_free (self->annotation_synopsis);
2441   self->annotation_synopsis = NULL;
2442
2443   g_free (self->annotation_description);
2444   self->annotation_description = NULL;
2445
2446   g_free (self->related_material_description);
2447   self->related_material_description = NULL;
2448
2449   g_free (self->classification_sets_uids);
2450   self->classification_sets_uids = NULL;
2451
2452   g_free (self->classification_sets);
2453   self->classification_sets = NULL;
2454
2455   g_free (self->related_material_locators);
2456   self->related_material_locators = NULL;
2457
2458   g_free (self->participant_sets_uids);
2459   self->participant_sets_uids = NULL;
2460
2461   g_free (self->participant_sets);
2462   self->participant_sets = NULL;
2463
2464   G_OBJECT_CLASS (mxf_dms1_annotation_parent_class)->finalize (object);
2465 }
2466
2467 static gboolean
2468 mxf_dms1_annotation_resolve (MXFMetadataBase * m, GHashTable * metadata)
2469 {
2470   MXFDMS1Annotation *self = MXF_DMS1_ANNOTATION (m);
2471   MXFMetadataBase *current = NULL;
2472   guint i;
2473
2474   if (self->classification_sets)
2475     memset (self->classification_sets, 0,
2476         sizeof (gpointer) * self->n_classification_sets);
2477   else
2478     self->classification_sets =
2479         g_new0 (MXFDMS1Classification *, self->n_classification_sets);
2480
2481   if (self->participant_sets)
2482     memset (self->participant_sets, 0,
2483         sizeof (gpointer) * self->n_participant_sets);
2484   else
2485     self->participant_sets =
2486         g_new0 (MXFDMS1Participant *, self->n_participant_sets);
2487
2488   for (i = 0; i < self->n_classification_sets; i++) {
2489     current =
2490         g_hash_table_lookup (metadata, &self->classification_sets_uids[i]);
2491     if (current && MXF_IS_DMS1_CLASSIFICATION (current)) {
2492       self->classification_sets[i] = MXF_DMS1_CLASSIFICATION (current);
2493     }
2494   }
2495
2496   current = g_hash_table_lookup (metadata, &self->cue_words_set_uid);
2497   if (current && MXF_IS_DMS1_CUE_WORDS (current)) {
2498     self->cue_words_set = MXF_DMS1_CUE_WORDS (current);
2499   }
2500
2501   for (i = 0; i < self->n_participant_sets; i++) {
2502     current = g_hash_table_lookup (metadata, &self->participant_sets_uids[i]);
2503     if (current && MXF_IS_DMS1_PARTICIPANT (current)) {
2504       self->participant_sets[i] = MXF_DMS1_PARTICIPANT (current);
2505     }
2506   }
2507
2508   return MXF_METADATA_BASE_CLASS (mxf_dms1_annotation_parent_class)->resolve (m,
2509       metadata);
2510 }
2511
2512 static gboolean
2513 mxf_dms1_annotation_handle_tag (MXFMetadataBase * metadata,
2514     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
2515     guint tag_size)
2516 {
2517   MXFDMS1Annotation *self = MXF_DMS1_ANNOTATION (metadata);
2518   gboolean ret = TRUE;
2519 #ifndef GST_DISABLE_GST_DEBUG
2520   gchar str[48];
2521 #endif
2522   MXFUL *tag_ul = NULL;
2523   static const guint8 annotation_kind_ul[] = {
2524     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03,
2525     0x02, 0x01, 0x06, 0x0e, 0x01, 0x00, 0x00
2526   };
2527   static const guint8 annotation_synopsis_ul[] = {
2528     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03,
2529     0x02, 0x01, 0x06, 0x09, 0x01, 0x00, 0x00
2530   };
2531   static const guint8 annotation_description_ul[] = {
2532     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03,
2533     0x02, 0x01, 0x06, 0x0a, 0x01, 0x00, 0x00
2534   };
2535   static const guint8 related_material_description_ul[] = {
2536     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03,
2537     0x02, 0x01, 0x06, 0x0f, 0x01, 0x00, 0x00
2538   };
2539   static const guint8 classification_sets_ul[] = {
2540     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
2541     0x01, 0x01, 0x04, 0x05, 0x40, 0x10, 0x00
2542   };
2543   static const guint8 cue_words_set_ul[] = {
2544     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
2545     0x01, 0x01, 0x04, 0x02, 0x40, 0x23, 0x01
2546   };
2547   static const guint8 related_material_locators_ul[] = {
2548     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
2549     0x01, 0x01, 0x04, 0x06, 0x0d, 0x00, 0x00
2550   };
2551   static const guint8 participant_sets_ul[] = {
2552     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x06,
2553     0x01, 0x01, 0x04, 0x03, 0x40, 0x13, 0x03
2554   };
2555
2556   if (!(tag_ul =
2557           (MXFUL *) g_hash_table_lookup (primer->mappings,
2558               GUINT_TO_POINTER (((guint) tag)))))
2559     return FALSE;
2560
2561   if (memcmp (tag_ul, &annotation_kind_ul, 16) == 0) {
2562     self->annotation_kind = mxf_utf16_to_utf8 (tag_data, tag_size);
2563     GST_DEBUG ("  annotation kind = %s", GST_STR_NULL (self->annotation_kind));
2564   } else if (memcmp (tag_ul, &annotation_synopsis_ul, 16) == 0) {
2565     self->annotation_synopsis = mxf_utf16_to_utf8 (tag_data, tag_size);
2566     GST_DEBUG ("  annotation synopsis = %s",
2567         GST_STR_NULL (self->annotation_synopsis));
2568   } else if (memcmp (tag_ul, &annotation_description_ul, 16) == 0) {
2569     self->annotation_description = mxf_utf16_to_utf8 (tag_data, tag_size);
2570     GST_DEBUG ("  annotation description = %s",
2571         GST_STR_NULL (self->annotation_description));
2572   } else if (memcmp (tag_ul, &related_material_description_ul, 16) == 0) {
2573     self->related_material_description = mxf_utf16_to_utf8 (tag_data, tag_size);
2574     GST_DEBUG ("  related material description = %s",
2575         GST_STR_NULL (self->related_material_description));
2576   } else if (memcmp (tag_ul, &classification_sets_ul, 16) == 0) {
2577     if (!mxf_uuid_array_parse (&self->classification_sets_uids,
2578             &self->n_classification_sets, tag_data, tag_size))
2579       goto error;
2580     GST_DEBUG ("  number of classification sets = %u",
2581         self->n_classification_sets);
2582 #ifndef GST_DISABLE_GST_DEBUG
2583     {
2584       guint i;
2585       for (i = 0; i < self->n_classification_sets; i++) {
2586         GST_DEBUG ("    classification sets %u = %s", i,
2587             mxf_uuid_to_string (&self->classification_sets_uids[i], str));
2588       }
2589     }
2590 #endif
2591   } else if (memcmp (tag_ul, &cue_words_set_ul, 16) == 0) {
2592     if (tag_size != 16)
2593       goto error;
2594
2595     memcpy (&self->cue_words_set_uid, tag_data, 16);
2596     GST_DEBUG ("  cue words set = %s",
2597         mxf_uuid_to_string (&self->cue_words_set_uid, str));
2598   } else if (memcmp (tag_ul, &related_material_locators_ul, 16) == 0) {
2599     if (!mxf_uuid_array_parse (&self->related_material_locators,
2600             &self->n_related_material_locators, tag_data, tag_size))
2601       goto error;
2602     GST_DEBUG ("  number of related material locators = %u",
2603         self->n_related_material_locators);
2604 #ifndef GST_DISABLE_GST_DEBUG
2605     {
2606       guint i;
2607       for (i = 0; i < self->n_related_material_locators; i++) {
2608         GST_DEBUG ("    related material locators %u = %s", i,
2609             mxf_uuid_to_string (&self->related_material_locators[i], str));
2610       }
2611     }
2612 #endif
2613   } else if (memcmp (tag_ul, &participant_sets_ul, 16) == 0) {
2614     if (!mxf_uuid_array_parse (&self->participant_sets_uids,
2615             &self->n_participant_sets, tag_data, tag_size))
2616       goto error;
2617     GST_DEBUG ("  number of participant sets = %u", self->n_participant_sets);
2618 #ifndef GST_DISABLE_GST_DEBUG
2619     {
2620       guint i;
2621       for (i = 0; i < self->n_participant_sets; i++) {
2622         GST_DEBUG ("    participant sets %u = %s", i,
2623             mxf_uuid_to_string (&self->participant_sets_uids[i], str));
2624       }
2625     }
2626 #endif
2627   } else {
2628     ret =
2629         MXF_METADATA_BASE_CLASS (mxf_dms1_annotation_parent_class)->handle_tag
2630         (metadata, primer, tag, tag_data, tag_size);
2631   }
2632
2633   return ret;
2634
2635 error:
2636
2637   GST_ERROR ("Invalid DMS1 annotation local tag 0x%04x of size %u", tag,
2638       tag_size);
2639
2640   return FALSE;
2641 }
2642
2643 static void
2644 mxf_dms1_annotation_init (MXFDMS1Annotation * self)
2645 {
2646 }
2647
2648 static void
2649 mxf_dms1_annotation_class_init (MXFDMS1AnnotationClass * klass)
2650 {
2651   GObjectClass *object_class = (GObjectClass *) klass;
2652   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
2653   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
2654
2655   object_class->finalize = mxf_dms1_annotation_finalize;
2656   metadatabase_class->handle_tag = mxf_dms1_annotation_handle_tag;
2657   metadatabase_class->resolve = mxf_dms1_annotation_resolve;
2658   dm_class->type = 0x170100;
2659 }
2660
2661 G_DEFINE_TYPE (MXFDMS1SettingPeriod, mxf_dms1_setting_period,
2662     MXF_TYPE_DMS1_THESAURUS);
2663
2664 static void
2665 mxf_dms1_setting_period_finalize (GObject * object)
2666 {
2667   MXFDMS1SettingPeriod *self = MXF_DMS1_SETTING_PERIOD (object);
2668
2669   g_free (self->time_period_keyword);
2670   self->time_period_keyword = NULL;
2671
2672   g_free (self->setting_period_description);
2673   self->setting_period_description = NULL;
2674
2675   G_OBJECT_CLASS (mxf_dms1_setting_period_parent_class)->finalize (object);
2676 }
2677
2678 static gboolean
2679 mxf_dms1_setting_period_handle_tag (MXFMetadataBase * metadata,
2680     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
2681     guint tag_size)
2682 {
2683   MXFDMS1SettingPeriod *self = MXF_DMS1_SETTING_PERIOD (metadata);
2684   gboolean ret = TRUE;
2685 #ifndef GST_DISABLE_GST_DEBUG
2686   gchar str[32];
2687 #endif
2688   MXFUL *tag_ul = NULL;
2689   static const guint8 setting_date_and_time_ul[] = {
2690     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x07,
2691     0x02, 0x01, 0x08, 0x02, 0x00, 0x00, 0x00
2692   };
2693   static const guint8 time_period_keyword_ul[] = {
2694     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x07,
2695     0x02, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00
2696   };
2697   static const guint8 setting_period_description_ul[] = {
2698     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x07,
2699     0x02, 0x01, 0x08, 0x03, 0x01, 0x00, 0x00
2700   };
2701
2702   if (!(tag_ul =
2703           (MXFUL *) g_hash_table_lookup (primer->mappings,
2704               GUINT_TO_POINTER (((guint) tag)))))
2705     return FALSE;
2706
2707   if (memcmp (tag_ul, &setting_date_and_time_ul, 16) == 0) {
2708     if (!mxf_timestamp_parse (&self->setting_date_and_time, tag_data, tag_size))
2709       goto error;
2710
2711     GST_DEBUG ("  last modified date = %s",
2712         mxf_timestamp_to_string (&self->setting_date_and_time, str));
2713   } else if (memcmp (tag_ul, &time_period_keyword_ul, 16) == 0) {
2714     self->time_period_keyword = mxf_utf16_to_utf8 (tag_data, tag_size);
2715     GST_DEBUG ("  time period keyword = %s",
2716         GST_STR_NULL (self->time_period_keyword));
2717   } else if (memcmp (tag_ul, &setting_period_description_ul, 16) == 0) {
2718     self->setting_period_description = mxf_utf16_to_utf8 (tag_data, tag_size);
2719     GST_DEBUG ("  setting period description = %s",
2720         GST_STR_NULL (self->setting_period_description));
2721   } else {
2722     ret =
2723         MXF_METADATA_BASE_CLASS
2724         (mxf_dms1_setting_period_parent_class)->handle_tag (metadata, primer,
2725         tag, tag_data, tag_size);
2726   }
2727
2728   return ret;
2729
2730 error:
2731
2732   GST_ERROR ("Invalid DMS1 setting period local tag 0x%04x of size %u", tag,
2733       tag_size);
2734
2735   return FALSE;
2736 }
2737
2738 static void
2739 mxf_dms1_setting_period_init (MXFDMS1SettingPeriod * self)
2740 {
2741 }
2742
2743 static void
2744 mxf_dms1_setting_period_class_init (MXFDMS1SettingPeriodClass * klass)
2745 {
2746   GObjectClass *object_class = (GObjectClass *) klass;
2747   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
2748   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
2749
2750   object_class->finalize = mxf_dms1_setting_period_finalize;
2751   metadatabase_class->handle_tag = mxf_dms1_setting_period_handle_tag;
2752   dm_class->type = 0x170200;
2753 }
2754
2755 G_DEFINE_TYPE (MXFDMS1Scripting, mxf_dms1_scripting, MXF_TYPE_DMS1_THESAURUS);
2756
2757 static void
2758 mxf_dms1_scripting_finalize (GObject * object)
2759 {
2760   MXFDMS1Scripting *self = MXF_DMS1_SCRIPTING (object);
2761
2762   g_free (self->scripting_kind);
2763   self->scripting_kind = NULL;
2764
2765   g_free (self->scripting_text);
2766   self->scripting_text = NULL;
2767
2768   g_free (self->scripting_locators);
2769   self->scripting_locators = NULL;
2770
2771   G_OBJECT_CLASS (mxf_dms1_scripting_parent_class)->finalize (object);
2772 }
2773
2774 static gboolean
2775 mxf_dms1_scripting_handle_tag (MXFMetadataBase * metadata,
2776     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
2777     guint tag_size)
2778 {
2779   MXFDMS1Scripting *self = MXF_DMS1_SCRIPTING (metadata);
2780   gboolean ret = TRUE;
2781 #ifndef GST_DISABLE_GST_DEBUG
2782   gchar str[48];
2783 #endif
2784   MXFUL *tag_ul = NULL;
2785   static const guint8 scripting_kind_ul[] = {
2786     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03,
2787     0x02, 0x01, 0x06, 0x0b, 0x01, 0x00, 0x00
2788   };
2789   static const guint8 scripting_text_ul[] = {
2790     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03,
2791     0x02, 0x01, 0x06, 0x0c, 0x01, 0x00, 0x00
2792   };
2793   static const guint8 scripting_locators_ul[] = {
2794     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08, 0x06,
2795     0x01, 0x01, 0x04, 0x06, 0x0e, 0x00, 0x00
2796   };
2797
2798   if (!(tag_ul =
2799           (MXFUL *) g_hash_table_lookup (primer->mappings,
2800               GUINT_TO_POINTER (((guint) tag)))))
2801     return FALSE;
2802
2803   if (memcmp (tag_ul, &scripting_kind_ul, 16) == 0) {
2804     self->scripting_kind = mxf_utf16_to_utf8 (tag_data, tag_size);
2805     GST_DEBUG ("  scripting kind = %s", GST_STR_NULL (self->scripting_kind));
2806   } else if (memcmp (tag_ul, &scripting_text_ul, 16) == 0) {
2807     self->scripting_text = mxf_utf16_to_utf8 (tag_data, tag_size);
2808     GST_DEBUG ("  scripting description = %s",
2809         GST_STR_NULL (self->scripting_text));
2810   } else if (memcmp (tag_ul, &scripting_locators_ul, 16) == 0) {
2811     if (!mxf_uuid_array_parse (&self->scripting_locators,
2812             &self->n_scripting_locators, tag_data, tag_size))
2813       goto error;
2814     GST_DEBUG ("  number of scripting locators = %u",
2815         self->n_scripting_locators);
2816 #ifndef GST_DISABLE_GST_DEBUG
2817     {
2818       guint i;
2819       for (i = 0; i < self->n_scripting_locators; i++) {
2820         GST_DEBUG ("   scripting locators %u = %s", i,
2821             mxf_uuid_to_string (&self->scripting_locators[i], str));
2822       }
2823     }
2824 #endif
2825   } else {
2826     ret =
2827         MXF_METADATA_BASE_CLASS (mxf_dms1_scripting_parent_class)->handle_tag
2828         (metadata, primer, tag, tag_data, tag_size);
2829   }
2830
2831   return ret;
2832
2833 error:
2834
2835   GST_ERROR ("Invalid DMS1 scripting local tag 0x%04x of size %u", tag,
2836       tag_size);
2837
2838   return FALSE;
2839 }
2840
2841 static void
2842 mxf_dms1_scripting_init (MXFDMS1Scripting * self)
2843 {
2844 }
2845
2846 static void
2847 mxf_dms1_scripting_class_init (MXFDMS1ScriptingClass * klass)
2848 {
2849   GObjectClass *object_class = (GObjectClass *) klass;
2850   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
2851   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
2852
2853   object_class->finalize = mxf_dms1_scripting_finalize;
2854   metadatabase_class->handle_tag = mxf_dms1_scripting_handle_tag;
2855   dm_class->type = 0x170300;
2856 }
2857
2858 G_DEFINE_TYPE (MXFDMS1Classification, mxf_dms1_classification,
2859     MXF_TYPE_DMS1_THESAURUS);
2860
2861 static void
2862 mxf_dms1_classification_finalize (GObject * object)
2863 {
2864   MXFDMS1Classification *self = MXF_DMS1_CLASSIFICATION (object);
2865
2866   g_free (self->name_value_sets_uids);
2867   self->name_value_sets_uids = NULL;
2868
2869   g_free (self->name_value_sets);
2870   self->name_value_sets = NULL;
2871
2872   G_OBJECT_CLASS (mxf_dms1_classification_parent_class)->finalize (object);
2873 }
2874
2875 static gboolean
2876 mxf_dms1_classification_resolve (MXFMetadataBase * m, GHashTable * metadata)
2877 {
2878   MXFDMS1Classification *self = MXF_DMS1_CLASSIFICATION (m);
2879   MXFMetadataBase *current = NULL;
2880   guint i;
2881
2882   if (self->name_value_sets)
2883     memset (self->name_value_sets, 0,
2884         sizeof (gpointer) * self->n_name_value_sets);
2885   else
2886     self->name_value_sets =
2887         g_new0 (MXFDMS1NameValue *, self->n_name_value_sets);
2888
2889   for (i = 0; i < self->n_name_value_sets; i++) {
2890     current = g_hash_table_lookup (metadata, &self->name_value_sets_uids[i]);
2891     if (current && MXF_IS_DMS1_NAME_VALUE (current)) {
2892       self->name_value_sets[i] = MXF_DMS1_NAME_VALUE (current);
2893     }
2894   }
2895
2896   return
2897       MXF_METADATA_BASE_CLASS (mxf_dms1_classification_parent_class)->resolve
2898       (m, metadata);
2899 }
2900
2901 static gboolean
2902 mxf_dms1_classification_handle_tag (MXFMetadataBase * metadata,
2903     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
2904     guint tag_size)
2905 {
2906   MXFDMS1Classification *self = MXF_DMS1_CLASSIFICATION (metadata);
2907   gboolean ret = TRUE;
2908 #ifndef GST_DISABLE_GST_DEBUG
2909   gchar str[48];
2910 #endif
2911   MXFUL *tag_ul = NULL;
2912   static const guint8 content_classification_ul[] = {
2913     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x03,
2914     0x02, 0x01, 0x03, 0x04, 0x00, 0x00, 0x00
2915   };
2916   static const guint8 name_value_sets_ul[] = {
2917     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
2918     0x01, 0x01, 0x04, 0x05, 0x40, 0x1f, 0x01
2919   };
2920
2921   if (!(tag_ul =
2922           (MXFUL *) g_hash_table_lookup (primer->mappings,
2923               GUINT_TO_POINTER (((guint) tag)))))
2924     return FALSE;
2925
2926   if (memcmp (tag_ul, &content_classification_ul, 16) == 0) {
2927     if (tag_size > 127)
2928       goto error;
2929
2930     memcpy (self->content_classification, tag_data, tag_size);
2931     GST_DEBUG ("  content classification = %s", self->content_classification);
2932   } else if (memcmp (tag_ul, &name_value_sets_ul, 16) == 0) {
2933     if (!mxf_uuid_array_parse (&self->name_value_sets_uids,
2934             &self->n_name_value_sets, tag_data, tag_size))
2935       goto error;
2936     GST_DEBUG ("  number of name-value sets = %u", self->n_name_value_sets);
2937 #ifndef GST_DISABLE_GST_DEBUG
2938     {
2939       guint i;
2940       for (i = 0; i < self->n_name_value_sets; i++) {
2941         GST_DEBUG ("    name-value sets %u = %s", i,
2942             mxf_uuid_to_string (&self->name_value_sets_uids[i], str));
2943       }
2944     }
2945 #endif
2946   } else {
2947     ret =
2948         MXF_METADATA_BASE_CLASS
2949         (mxf_dms1_classification_parent_class)->handle_tag (metadata, primer,
2950         tag, tag_data, tag_size);
2951   }
2952
2953   return ret;
2954
2955 error:
2956
2957   GST_ERROR ("Invalid DMS1 classification local tag 0x%04x of size %u", tag,
2958       tag_size);
2959
2960   return FALSE;
2961 }
2962
2963 static void
2964 mxf_dms1_classification_init (MXFDMS1Classification * self)
2965 {
2966 }
2967
2968 static void
2969 mxf_dms1_classification_class_init (MXFDMS1ClassificationClass * klass)
2970 {
2971   GObjectClass *object_class = (GObjectClass *) klass;
2972   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
2973   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
2974
2975   object_class->finalize = mxf_dms1_classification_finalize;
2976   metadatabase_class->handle_tag = mxf_dms1_classification_handle_tag;
2977   metadatabase_class->resolve = mxf_dms1_classification_resolve;
2978   dm_class->type = 0x170400;
2979 }
2980
2981 G_DEFINE_TYPE (MXFDMS1Shot, mxf_dms1_shot, MXF_TYPE_DMS1_TEXT_LANGUAGE);
2982
2983 static void
2984 mxf_dms1_shot_finalize (GObject * object)
2985 {
2986   MXFDMS1Shot *self = MXF_DMS1_SHOT (object);
2987
2988   g_free (self->shot_track_ids);
2989   self->shot_track_ids = NULL;
2990
2991   g_free (self->shot_description);
2992   self->shot_description = NULL;
2993
2994   g_free (self->shot_comment_kind);
2995   self->shot_comment_kind = NULL;
2996
2997   g_free (self->shot_comment);
2998   self->shot_comment = NULL;
2999
3000   g_free (self->key_point_sets_uids);
3001   self->key_point_sets_uids = NULL;
3002
3003   g_free (self->key_point_sets);
3004   self->key_point_sets = NULL;
3005
3006   G_OBJECT_CLASS (mxf_dms1_shot_parent_class)->finalize (object);
3007 }
3008
3009 static gboolean
3010 mxf_dms1_shot_resolve (MXFMetadataBase * m, GHashTable * metadata)
3011 {
3012   MXFDMS1Shot *self = MXF_DMS1_SHOT (m);
3013   MXFMetadataBase *current = NULL;
3014   guint i;
3015
3016   if (self->key_point_sets)
3017     memset (self->key_point_sets, 0,
3018         sizeof (gpointer) * self->n_key_point_sets);
3019   else
3020     self->key_point_sets = g_new0 (MXFDMS1KeyPoint *, self->n_key_point_sets);
3021
3022   current = g_hash_table_lookup (metadata, &self->cue_words_set_uid);
3023   if (current && MXF_IS_DMS1_CUE_WORDS (current)) {
3024     self->cue_words_set = MXF_DMS1_CUE_WORDS (current);
3025   }
3026
3027   for (i = 0; i < self->n_key_point_sets; i++) {
3028     current = g_hash_table_lookup (metadata, &self->key_point_sets_uids[i]);
3029     if (current && MXF_IS_DMS1_KEY_POINT (current)) {
3030       self->key_point_sets[i] = MXF_DMS1_KEY_POINT (current);
3031     }
3032   }
3033
3034   return MXF_METADATA_BASE_CLASS (mxf_dms1_shot_parent_class)->resolve (m,
3035       metadata);
3036 }
3037
3038 static gboolean
3039 mxf_dms1_shot_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer,
3040     guint16 tag, const guint8 * tag_data, guint tag_size)
3041 {
3042   MXFDMS1Shot *self = MXF_DMS1_SHOT (metadata);
3043   gboolean ret = TRUE;
3044 #ifndef GST_DISABLE_GST_DEBUG
3045   gchar str[48];
3046 #endif
3047   MXFUL *tag_ul = NULL;
3048   static const guint8 shot_start_position_ul[] = {
3049     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x07,
3050     0x02, 0x01, 0x03, 0x01, 0x09, 0x00, 0x00
3051   };
3052   static const guint8 shot_duration_ul[] = {
3053     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x07,
3054     0x02, 0x02, 0x01, 0x02, 0x04, 0x00, 0x00
3055   };
3056   static const guint8 shot_track_ids_ul[] = {
3057     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x01,
3058     0x07, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00
3059   };
3060   static const guint8 shot_description_ul[] = {
3061     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03,
3062     0x02, 0x01, 0x06, 0x0d, 0x01, 0x00, 0x00
3063   };
3064   static const guint8 shot_comment_kind_ul[] = {
3065     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x03,
3066     0x02, 0x05, 0x01, 0x01, 0x00, 0x00, 0x00
3067   };
3068   static const guint8 shot_comment_ul[] = {
3069     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x03,
3070     0x02, 0x05, 0x02, 0x01, 0x00, 0x00, 0x00
3071   };
3072   static const guint8 cue_words_set_ul[] = {
3073     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
3074     0x01, 0x01, 0x04, 0x02, 0x40, 0x23, 0x01
3075   };
3076   static const guint8 key_point_sets_ul[] = {
3077     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
3078     0x01, 0x01, 0x04, 0x05, 0x40, 0x12, 0x00
3079   };
3080
3081   if (!(tag_ul =
3082           (MXFUL *) g_hash_table_lookup (primer->mappings,
3083               GUINT_TO_POINTER (((guint) tag)))))
3084     return FALSE;
3085
3086   if (memcmp (tag_ul, &shot_start_position_ul, 16) == 0) {
3087     if (tag_size != 8)
3088       goto error;
3089
3090     self->shot_start_position = GST_READ_UINT64_BE (tag_data);
3091     GST_DEBUG ("  shot start position = %" G_GINT64_FORMAT,
3092         self->shot_start_position);
3093   } else if (memcmp (tag_ul, &shot_duration_ul, 16) == 0) {
3094     if (tag_size != 8)
3095       goto error;
3096
3097     self->shot_duration = GST_READ_UINT64_BE (tag_data);
3098     GST_DEBUG ("  shot duration = %" G_GINT64_FORMAT, self->shot_duration);
3099   } else if (memcmp (tag_ul, &shot_track_ids_ul, 16) == 0) {
3100     guint32 len, i;
3101
3102     len = GST_READ_UINT32_BE (tag_data);
3103     GST_DEBUG ("  number of shot track ids = %u", len);
3104     if (len == 0)
3105       return ret;
3106
3107     if (GST_READ_UINT32_BE (tag_data + 4) != 4)
3108       goto error;
3109     tag_data += 8;
3110     tag_size -= 8;
3111
3112     if (tag_size / 4 < len)
3113       goto error;
3114
3115     self->n_shot_track_ids = len;
3116     self->shot_track_ids = g_new0 (guint32, len);
3117
3118     for (i = 0; i < len; i++) {
3119       self->shot_track_ids[i] = GST_READ_UINT32_BE (tag_data);
3120       GST_DEBUG ("    shot track ids %u = %u", i, self->shot_track_ids[i]);
3121       tag_data += 4;
3122       tag_size -= 4;
3123     }
3124   } else if (memcmp (tag_ul, &shot_description_ul, 16) == 0) {
3125     self->shot_description = mxf_utf16_to_utf8 (tag_data, tag_size);
3126     GST_DEBUG ("  shot description = %s",
3127         GST_STR_NULL (self->shot_description));
3128   } else if (memcmp (tag_ul, &shot_comment_kind_ul, 16) == 0) {
3129     self->shot_comment_kind = mxf_utf16_to_utf8 (tag_data, tag_size);
3130     GST_DEBUG ("  shot comment kind = %s",
3131         GST_STR_NULL (self->shot_comment_kind));
3132   } else if (memcmp (tag_ul, &shot_comment_ul, 16) == 0) {
3133     self->shot_comment = mxf_utf16_to_utf8 (tag_data, tag_size);
3134     GST_DEBUG ("  shot comment = %s", GST_STR_NULL (self->shot_comment));
3135   } else if (memcmp (tag_ul, &cue_words_set_ul, 16) == 0) {
3136     if (tag_size != 16)
3137       goto error;
3138
3139     memcpy (&self->cue_words_set_uid, tag_data, 16);
3140     GST_DEBUG ("  cue words set = %s",
3141         mxf_uuid_to_string (&self->cue_words_set_uid, str));
3142   } else if (memcmp (tag_ul, &key_point_sets_ul, 16) == 0) {
3143     if (!mxf_uuid_array_parse (&self->key_point_sets_uids,
3144             &self->n_key_point_sets, tag_data, tag_size))
3145       goto error;
3146     GST_DEBUG ("  number of key point sets = %u", self->n_key_point_sets);
3147 #ifndef GST_DISABLE_GST_DEBUG
3148     {
3149       guint i;
3150       for (i = 0; i < self->n_key_point_sets; i++) {
3151         GST_DEBUG ("    key point sets %u = %s", i,
3152             mxf_uuid_to_string (&self->key_point_sets_uids[i], str));
3153       }
3154     }
3155 #endif
3156   } else {
3157     ret =
3158         MXF_METADATA_BASE_CLASS (mxf_dms1_shot_parent_class)->handle_tag
3159         (metadata, primer, tag, tag_data, tag_size);
3160   }
3161
3162   return ret;
3163
3164 error:
3165
3166   GST_ERROR ("Invalid DMS1 shot local tag 0x%04x of size %u", tag, tag_size);
3167
3168   return FALSE;
3169 }
3170
3171 static void
3172 mxf_dms1_shot_init (MXFDMS1Shot * self)
3173 {
3174 }
3175
3176 static void
3177 mxf_dms1_shot_class_init (MXFDMS1ShotClass * klass)
3178 {
3179   GObjectClass *object_class = (GObjectClass *) klass;
3180   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
3181   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
3182
3183   object_class->finalize = mxf_dms1_shot_finalize;
3184   metadatabase_class->handle_tag = mxf_dms1_shot_handle_tag;
3185   metadatabase_class->resolve = mxf_dms1_shot_resolve;
3186   dm_class->type = 0x170500;
3187 }
3188
3189 G_DEFINE_TYPE (MXFDMS1KeyPoint, mxf_dms1_key_point, MXF_TYPE_DMS1_THESAURUS);
3190
3191 static void
3192 mxf_dms1_key_point_finalize (GObject * object)
3193 {
3194   MXFDMS1KeyPoint *self = MXF_DMS1_KEY_POINT (object);
3195
3196   g_free (self->keypoint_kind);
3197   self->keypoint_kind = NULL;
3198
3199   g_free (self->keypoint_value);
3200   self->keypoint_value = NULL;
3201
3202   G_OBJECT_CLASS (mxf_dms1_key_point_parent_class)->finalize (object);
3203 }
3204
3205 static gboolean
3206 mxf_dms1_key_point_handle_tag (MXFMetadataBase * metadata,
3207     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
3208     guint tag_size)
3209 {
3210   MXFDMS1KeyPoint *self = MXF_DMS1_KEY_POINT (metadata);
3211   gboolean ret = TRUE;
3212   MXFUL *tag_ul = NULL;
3213   static const guint8 keypoint_kind_ul[] = {
3214     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x03,
3215     0x02, 0x01, 0x02, 0x10, 0x01, 0x00, 0x00
3216   };
3217   static const guint8 keypoint_value_ul[] = {
3218     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x03,
3219     0x02, 0x01, 0x02, 0x11, 0x01, 0x00, 0x00
3220   };
3221   static const guint8 keypoint_position_ul[] = {
3222     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x07,
3223     0x02, 0x01, 0x03, 0x01, 0x07, 0x00, 0x00
3224   };
3225
3226   if (!(tag_ul =
3227           (MXFUL *) g_hash_table_lookup (primer->mappings,
3228               GUINT_TO_POINTER (((guint) tag)))))
3229     return FALSE;
3230
3231   if (memcmp (tag_ul, &keypoint_kind_ul, 16) == 0) {
3232     self->keypoint_kind = mxf_utf16_to_utf8 (tag_data, tag_size);
3233     GST_DEBUG ("  keypoint kind = %s", GST_STR_NULL (self->keypoint_kind));
3234   } else if (memcmp (tag_ul, &keypoint_value_ul, 16) == 0) {
3235     self->keypoint_value = mxf_utf16_to_utf8 (tag_data, tag_size);
3236     GST_DEBUG ("  keypoint value = %s", GST_STR_NULL (self->keypoint_value));
3237   } else if (memcmp (tag_ul, &keypoint_position_ul, 16) == 0) {
3238     if (tag_size != 8)
3239       goto error;
3240
3241     self->keypoint_position = GST_READ_UINT64_BE (tag_data);
3242     GST_DEBUG ("  keypoint position = %" G_GINT64_FORMAT,
3243         self->keypoint_position);
3244   } else {
3245     ret =
3246         MXF_METADATA_BASE_CLASS (mxf_dms1_key_point_parent_class)->handle_tag
3247         (metadata, primer, tag, tag_data, tag_size);
3248   }
3249
3250   return ret;
3251
3252 error:
3253
3254   GST_ERROR ("Invalid DMS1 key point local tag 0x%04x of size %u", tag,
3255       tag_size);
3256
3257   return FALSE;
3258 }
3259
3260 static void
3261 mxf_dms1_key_point_init (MXFDMS1KeyPoint * self)
3262 {
3263 }
3264
3265 static void
3266 mxf_dms1_key_point_class_init (MXFDMS1KeyPointClass * klass)
3267 {
3268   GObjectClass *object_class = (GObjectClass *) klass;
3269   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
3270   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
3271
3272   object_class->finalize = mxf_dms1_key_point_finalize;
3273   metadatabase_class->handle_tag = mxf_dms1_key_point_handle_tag;
3274   dm_class->type = 0x170600;
3275 }
3276
3277 G_DEFINE_TYPE (MXFDMS1Participant, mxf_dms1_participant,
3278     MXF_TYPE_DMS1_THESAURUS);
3279
3280 static void
3281 mxf_dms1_participant_finalize (GObject * object)
3282 {
3283   MXFDMS1Participant *self = MXF_DMS1_PARTICIPANT (object);
3284
3285   g_free (self->contribution_status);
3286   self->contribution_status = NULL;
3287
3288   g_free (self->job_function);
3289   self->job_function = NULL;
3290
3291   g_free (self->role_or_identity_name);
3292   self->role_or_identity_name = NULL;
3293
3294   g_free (self->person_sets_uids);
3295   self->person_sets_uids = NULL;
3296
3297   g_free (self->person_sets);
3298   self->person_sets = NULL;
3299
3300   g_free (self->organisation_sets_uids);
3301   self->organisation_sets_uids = NULL;
3302
3303   g_free (self->organisation_sets);
3304   self->organisation_sets = NULL;
3305
3306   G_OBJECT_CLASS (mxf_dms1_participant_parent_class)->finalize (object);
3307 }
3308
3309 static gboolean
3310 mxf_dms1_participant_resolve (MXFMetadataBase * m, GHashTable * metadata)
3311 {
3312   MXFDMS1Participant *self = MXF_DMS1_PARTICIPANT (m);
3313   MXFMetadataBase *current = NULL;
3314   guint i;
3315
3316   if (self->person_sets)
3317     memset (self->person_sets, 0, sizeof (gpointer) * self->n_person_sets);
3318   else
3319     self->person_sets = g_new0 (MXFDMS1Person *, self->n_person_sets);
3320
3321   if (self->organisation_sets)
3322     memset (self->organisation_sets, 0,
3323         sizeof (gpointer) * self->n_organisation_sets);
3324   else
3325     self->organisation_sets =
3326         g_new0 (MXFDMS1Organisation *, self->n_organisation_sets);
3327
3328   for (i = 0; i < self->n_person_sets; i++) {
3329     current = g_hash_table_lookup (metadata, &self->person_sets_uids[i]);
3330     if (current && MXF_IS_DMS1_PERSON (current)) {
3331       self->person_sets[i] = MXF_DMS1_PERSON (current);
3332     }
3333   }
3334
3335   for (i = 0; i < self->n_organisation_sets; i++) {
3336     current = g_hash_table_lookup (metadata, &self->organisation_sets_uids[i]);
3337     if (current && MXF_IS_DMS1_ORGANISATION (current)) {
3338       self->organisation_sets[i] = MXF_DMS1_ORGANISATION (current);
3339     }
3340   }
3341
3342   return
3343       MXF_METADATA_BASE_CLASS (mxf_dms1_participant_parent_class)->resolve (m,
3344       metadata);
3345 }
3346
3347 static gboolean
3348 mxf_dms1_participant_handle_tag (MXFMetadataBase * metadata,
3349     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
3350     guint tag_size)
3351 {
3352   MXFDMS1Participant *self = MXF_DMS1_PARTICIPANT (metadata);
3353   gboolean ret = TRUE;
3354 #ifndef GST_DISABLE_GST_DEBUG
3355   gchar str[48];
3356 #endif
3357   MXFUL *tag_ul = NULL;
3358   static const guint8 participant_uid_ul[] = {
3359     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08, 0x01,
3360     0x01, 0x15, 0x40, 0x01, 0x01, 0x00, 0x00
3361   };
3362   static const guint8 contribution_status_ul[] = {
3363     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02,
3364     0x30, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00
3365   };
3366   static const guint8 job_function_ul[] = {
3367     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02,
3368     0x30, 0x05, 0x01, 0x01, 0x00, 0x00, 0x00
3369   };
3370   static const guint8 job_function_code_ul[] = {
3371     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02,
3372     0x30, 0x05, 0x01, 0x02, 0x00, 0x00, 0x00
3373   };
3374   static const guint8 role_or_identity_name_ul[] = {
3375     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02,
3376     0x30, 0x05, 0x02, 0x01, 0x00, 0x00, 0x00
3377   };
3378   static const guint8 person_sets_ul[] = {
3379     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
3380     0x01, 0x01, 0x04, 0x03, 0x40, 0x14, 0x00
3381   };
3382   static const guint8 organisation_sets_ul[] = {
3383     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
3384     0x01, 0x01, 0x04, 0x03, 0x40, 0x15, 0x02
3385   };
3386
3387   if (!(tag_ul =
3388           (MXFUL *) g_hash_table_lookup (primer->mappings,
3389               GUINT_TO_POINTER (((guint) tag)))))
3390     return FALSE;
3391
3392   if (memcmp (tag_ul, &participant_uid_ul, 16) == 0) {
3393     if (tag_size != 16)
3394       goto error;
3395
3396     memcpy (&self->participant_uid, tag_data, 16);
3397     GST_DEBUG ("  participant uid = %s",
3398         mxf_uuid_to_string (&self->participant_uid, str));
3399   } else if (memcmp (tag_ul, &contribution_status_ul, 16) == 0) {
3400     self->contribution_status = mxf_utf16_to_utf8 (tag_data, tag_size);
3401     GST_DEBUG ("  contribution status = %s",
3402         GST_STR_NULL (self->contribution_status));
3403   } else if (memcmp (tag_ul, &job_function_ul, 16) == 0) {
3404     self->job_function = mxf_utf16_to_utf8 (tag_data, tag_size);
3405     GST_DEBUG ("  job function = %s", GST_STR_NULL (self->job_function));
3406   } else if (memcmp (tag_ul, &job_function_code_ul, 16) == 0) {
3407     if (tag_size > 32)
3408       goto error;
3409
3410     memcpy (self->job_function_code, tag_data, tag_size);
3411     GST_DEBUG ("  job function code = %s", self->job_function_code);
3412   } else if (memcmp (tag_ul, &role_or_identity_name_ul, 16) == 0) {
3413     self->role_or_identity_name = mxf_utf16_to_utf8 (tag_data, tag_size);
3414     GST_DEBUG ("  role or identity name = %s",
3415         GST_STR_NULL (self->role_or_identity_name));
3416   } else if (memcmp (tag_ul, &person_sets_ul, 16) == 0) {
3417     if (!mxf_uuid_array_parse (&self->person_sets_uids, &self->n_person_sets,
3418             tag_data, tag_size))
3419       goto error;
3420     GST_DEBUG ("  number of person sets = %u", self->n_person_sets);
3421 #ifndef GST_DISABLE_GST_DEBUG
3422     {
3423       guint i;
3424       for (i = 0; i < self->n_person_sets; i++) {
3425         GST_DEBUG ("    person sets %u = %s", i,
3426             mxf_uuid_to_string (&self->person_sets_uids[i], str));
3427       }
3428     }
3429 #endif
3430   } else if (memcmp (tag_ul, &organisation_sets_ul, 16) == 0) {
3431     if (!mxf_uuid_array_parse (&self->organisation_sets_uids,
3432             &self->n_organisation_sets, tag_data, tag_size))
3433       goto error;
3434     GST_DEBUG ("  number of organisation sets = %u", self->n_organisation_sets);
3435 #ifndef GST_DISABLE_GST_DEBUG
3436     {
3437       guint i;
3438       for (i = 0; i < self->n_organisation_sets; i++) {
3439         GST_DEBUG ("    organisation sets %u = %s", i,
3440             mxf_uuid_to_string (&self->organisation_sets_uids[i], str));
3441       }
3442     }
3443 #endif
3444   } else {
3445     ret =
3446         MXF_METADATA_BASE_CLASS (mxf_dms1_participant_parent_class)->handle_tag
3447         (metadata, primer, tag, tag_data, tag_size);
3448   }
3449
3450   return ret;
3451
3452 error:
3453
3454   GST_ERROR ("Invalid DMS1 participant local tag 0x%04x of size %u", tag,
3455       tag_size);
3456
3457   return FALSE;
3458 }
3459
3460 static void
3461 mxf_dms1_participant_init (MXFDMS1Participant * self)
3462 {
3463 }
3464
3465 static void
3466 mxf_dms1_participant_class_init (MXFDMS1ParticipantClass * klass)
3467 {
3468   GObjectClass *object_class = (GObjectClass *) klass;
3469   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
3470   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
3471
3472   object_class->finalize = mxf_dms1_participant_finalize;
3473   metadatabase_class->handle_tag = mxf_dms1_participant_handle_tag;
3474   metadatabase_class->resolve = mxf_dms1_participant_resolve;
3475   dm_class->type = 0x180100;
3476 }
3477
3478 G_DEFINE_ABSTRACT_TYPE (MXFDMS1Contact, mxf_dms1_contact,
3479     MXF_TYPE_DMS1_THESAURUS);
3480
3481 static void
3482 mxf_dms1_contact_finalize (GObject * object)
3483 {
3484   MXFDMS1Contact *self = MXF_DMS1_CONTACT (object);
3485
3486   g_free (self->name_value_sets_uids);
3487   self->name_value_sets_uids = NULL;
3488
3489   g_free (self->name_value_sets);
3490   self->name_value_sets = NULL;
3491
3492   g_free (self->address_sets_uids);
3493   self->address_sets_uids = NULL;
3494
3495   g_free (self->address_sets);
3496   self->address_sets = NULL;
3497
3498   G_OBJECT_CLASS (mxf_dms1_contact_parent_class)->finalize (object);
3499 }
3500
3501 static gboolean
3502 mxf_dms1_contact_resolve (MXFMetadataBase * m, GHashTable * metadata)
3503 {
3504   MXFDMS1Contact *self = MXF_DMS1_CONTACT (m);
3505   MXFMetadataBase *current = NULL;
3506   guint i;
3507
3508   if (self->name_value_sets)
3509     memset (self->name_value_sets, 0,
3510         sizeof (gpointer) * self->n_name_value_sets);
3511   else
3512     self->name_value_sets =
3513         g_new0 (MXFDMS1NameValue *, self->n_name_value_sets);
3514
3515   if (self->address_sets)
3516     memset (self->address_sets, 0, sizeof (gpointer) * self->n_address_sets);
3517   else
3518     self->address_sets = g_new0 (MXFDMS1Address *, self->n_address_sets);
3519
3520   for (i = 0; i < self->n_name_value_sets; i++) {
3521     current = g_hash_table_lookup (metadata, &self->name_value_sets_uids[i]);
3522     if (current && MXF_IS_DMS1_NAME_VALUE (current)) {
3523       self->name_value_sets[i] = MXF_DMS1_NAME_VALUE (current);
3524     }
3525   }
3526
3527   for (i = 0; i < self->n_address_sets; i++) {
3528     current = g_hash_table_lookup (metadata, &self->address_sets_uids[i]);
3529     if (current && MXF_IS_DMS1_ADDRESS (current)) {
3530       self->address_sets[i] = MXF_DMS1_ADDRESS (current);
3531     }
3532   }
3533
3534   return MXF_METADATA_BASE_CLASS (mxf_dms1_contact_parent_class)->resolve (m,
3535       metadata);
3536 }
3537
3538 static gboolean
3539 mxf_dms1_contact_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer,
3540     guint16 tag, const guint8 * tag_data, guint tag_size)
3541 {
3542   MXFDMS1Contact *self = MXF_DMS1_CONTACT (metadata);
3543   gboolean ret = TRUE;
3544 #ifndef GST_DISABLE_GST_DEBUG
3545   gchar str[48];
3546 #endif
3547   MXFUL *tag_ul = NULL;
3548   static const guint8 contact_uid_ul[] = {
3549     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08, 0x01,
3550     0x01, 0x15, 0x40, 0x01, 0x02, 0x00, 0x00
3551   };
3552   static const guint8 name_value_sets_ul[] = {
3553     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
3554     0x01, 0x01, 0x04, 0x05, 0x40, 0x1f, 0x02
3555   };
3556   static const guint8 address_sets_ul[] = {
3557     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
3558     0x01, 0x01, 0x04, 0x05, 0x40, 0x17, 0x00
3559   };
3560
3561   if (!(tag_ul =
3562           (MXFUL *) g_hash_table_lookup (primer->mappings,
3563               GUINT_TO_POINTER (((guint) tag)))))
3564     return FALSE;
3565
3566   if (memcmp (tag_ul, &contact_uid_ul, 16) == 0) {
3567     if (tag_size != 16)
3568       goto error;
3569
3570     memcpy (&self->contact_uid, tag_data, 16);
3571     GST_DEBUG ("  contact uid = %s", mxf_uuid_to_string (&self->contact_uid,
3572             str));
3573   } else if (memcmp (tag_ul, &name_value_sets_ul, 16) == 0) {
3574     if (!mxf_uuid_array_parse (&self->name_value_sets_uids,
3575             &self->n_name_value_sets, tag_data, tag_size))
3576       goto error;
3577     GST_DEBUG ("  number of name-value sets = %u", self->n_name_value_sets);
3578 #ifndef GST_DISABLE_GST_DEBUG
3579     {
3580       guint i;
3581       for (i = 0; i < self->n_name_value_sets; i++) {
3582         GST_DEBUG ("    name-value sets %u = %s", i,
3583             mxf_uuid_to_string (&self->name_value_sets_uids[i], str));
3584       }
3585     }
3586 #endif
3587   } else if (memcmp (tag_ul, &address_sets_ul, 16) == 0) {
3588     if (!mxf_uuid_array_parse (&self->address_sets_uids, &self->n_address_sets,
3589             tag_data, tag_size))
3590       goto error;
3591     GST_DEBUG ("  number of address sets = %u", self->n_address_sets);
3592 #ifndef GST_DISABLE_GST_DEBUG
3593     {
3594       guint i;
3595       for (i = 0; i < self->n_address_sets; i++) {
3596         GST_DEBUG ("    address sets %u = %s", i,
3597             mxf_uuid_to_string (&self->address_sets_uids[i], str));
3598       }
3599     }
3600 #endif
3601   } else {
3602     ret =
3603         MXF_METADATA_BASE_CLASS (mxf_dms1_contact_parent_class)->handle_tag
3604         (metadata, primer, tag, tag_data, tag_size);
3605   }
3606
3607   return ret;
3608
3609 error:
3610
3611   GST_ERROR ("Invalid DMS1 contact local tag 0x%04x of size %u", tag, tag_size);
3612
3613   return FALSE;
3614 }
3615
3616 static void
3617 mxf_dms1_contact_init (MXFDMS1Contact * self)
3618 {
3619 }
3620
3621 static void
3622 mxf_dms1_contact_class_init (MXFDMS1ContactClass * klass)
3623 {
3624   GObjectClass *object_class = (GObjectClass *) klass;
3625   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
3626
3627   object_class->finalize = mxf_dms1_contact_finalize;
3628   metadatabase_class->handle_tag = mxf_dms1_contact_handle_tag;
3629   metadatabase_class->resolve = mxf_dms1_contact_resolve;
3630 }
3631
3632 G_DEFINE_TYPE (MXFDMS1Person, mxf_dms1_person, MXF_TYPE_DMS1_CONTACT);
3633
3634 static void
3635 mxf_dms1_person_finalize (GObject * object)
3636 {
3637   MXFDMS1Person *self = MXF_DMS1_PERSON (object);
3638
3639   g_free (self->family_name);
3640   self->family_name = NULL;
3641
3642   g_free (self->first_given_name);
3643   self->first_given_name = NULL;
3644
3645   g_free (self->other_given_names);
3646   self->other_given_names = NULL;
3647
3648   g_free (self->linking_name);
3649   self->linking_name = NULL;
3650
3651   g_free (self->salutation);
3652   self->salutation = NULL;
3653
3654   g_free (self->name_suffix);
3655   self->name_suffix = NULL;
3656
3657   g_free (self->honours_qualifications);
3658   self->honours_qualifications = NULL;
3659
3660   g_free (self->former_family_name);
3661   self->former_family_name = NULL;
3662
3663   g_free (self->person_description);
3664   self->person_description = NULL;
3665
3666   g_free (self->alternate_name);
3667   self->alternate_name = NULL;
3668
3669   g_free (self->nationality);
3670   self->nationality = NULL;
3671
3672   g_free (self->citizenship);
3673   self->citizenship = NULL;
3674
3675   g_free (self->organisation_sets_uids);
3676   self->organisation_sets_uids = NULL;
3677
3678   g_free (self->organisation_sets);
3679   self->organisation_sets = NULL;
3680
3681   G_OBJECT_CLASS (mxf_dms1_person_parent_class)->finalize (object);
3682 }
3683
3684 static gboolean
3685 mxf_dms1_person_resolve (MXFMetadataBase * m, GHashTable * metadata)
3686 {
3687   MXFDMS1Person *self = MXF_DMS1_PERSON (m);
3688   MXFMetadataBase *current = NULL;
3689   guint i;
3690
3691   if (self->organisation_sets)
3692     memset (self->organisation_sets, 0,
3693         sizeof (gpointer) * self->n_organisation_sets);
3694   else
3695     self->organisation_sets =
3696         g_new0 (MXFDMS1Organisation *, self->n_organisation_sets);
3697
3698   for (i = 0; i < self->n_organisation_sets; i++) {
3699     current = g_hash_table_lookup (metadata, &self->organisation_sets_uids[i]);
3700     if (current && MXF_IS_DMS1_ORGANISATION (current)) {
3701       self->organisation_sets[i] = MXF_DMS1_ORGANISATION (current);
3702     }
3703   }
3704
3705   return MXF_METADATA_BASE_CLASS (mxf_dms1_person_parent_class)->resolve (m,
3706       metadata);
3707 }
3708
3709 static gboolean
3710 mxf_dms1_person_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer,
3711     guint16 tag, const guint8 * tag_data, guint tag_size)
3712 {
3713   MXFDMS1Person *self = MXF_DMS1_PERSON (metadata);
3714   gboolean ret = TRUE;
3715 #ifndef GST_DISABLE_GST_DEBUG
3716   gchar str[48];
3717 #endif
3718   MXFUL *tag_ul = NULL;
3719   static const guint8 family_name_ul[] = {
3720     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02,
3721     0x30, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00
3722   };
3723   static const guint8 first_given_name_ul[] = {
3724     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x02,
3725     0x30, 0x06, 0x03, 0x01, 0x02, 0x01, 0x00
3726   };
3727   static const guint8 other_given_names_ul[] = {
3728     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x02,
3729     0x30, 0x06, 0x03, 0x01, 0x08, 0x01, 0x00
3730   };
3731   static const guint8 linking_name_ul[] = {
3732     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x02,
3733     0x30, 0x06, 0x03, 0x01, 0x0a, 0x01, 0x00
3734   };
3735   static const guint8 salutation_ul[] = {
3736     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x02,
3737     0x30, 0x06, 0x03, 0x01, 0x05, 0x01, 0x00
3738   };
3739   static const guint8 name_suffix_ul[] = {
3740     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x02,
3741     0x30, 0x06, 0x03, 0x01, 0x0b, 0x01, 0x00
3742   };
3743   static const guint8 honours_qualifications_ul[] = {
3744     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x02,
3745     0x30, 0x06, 0x03, 0x01, 0x06, 0x01, 0x00
3746   };
3747   static const guint8 former_family_name_ul[] = {
3748     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x02,
3749     0x30, 0x06, 0x03, 0x01, 0x0c, 0x01, 0x00
3750   };
3751   static const guint8 person_description_ul[] = {
3752     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02,
3753     0x30, 0x06, 0x03, 0x01, 0x07, 0x01, 0x00
3754   };
3755   static const guint8 alternate_name_ul[] = {
3756     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x02,
3757     0x30, 0x06, 0x03, 0x01, 0x09, 0x01, 0x00
3758   };
3759   static const guint8 nationality_ul[] = {
3760     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x02,
3761     0x30, 0x06, 0x03, 0x01, 0x0d, 0x01, 0x00
3762   };
3763   static const guint8 citizenship_ul[] = {
3764     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x02,
3765     0x30, 0x06, 0x03, 0x01, 0x0e, 0x01, 0x00
3766   };
3767   static const guint8 organisation_sets_ul[] = {
3768     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
3769     0x01, 0x01, 0x04, 0x03, 0x40, 0x15, 0x02
3770   };
3771
3772   if (!(tag_ul =
3773           (MXFUL *) g_hash_table_lookup (primer->mappings,
3774               GUINT_TO_POINTER (((guint) tag)))))
3775     return FALSE;
3776
3777   if (memcmp (tag_ul, &family_name_ul, 16) == 0) {
3778     self->family_name = mxf_utf16_to_utf8 (tag_data, tag_size);
3779     GST_DEBUG ("  family name = %s", GST_STR_NULL (self->family_name));
3780   } else if (memcmp (tag_ul, &first_given_name_ul, 16) == 0) {
3781     self->first_given_name = mxf_utf16_to_utf8 (tag_data, tag_size);
3782     GST_DEBUG ("  first given name = %s",
3783         GST_STR_NULL (self->first_given_name));
3784   } else if (memcmp (tag_ul, &other_given_names_ul, 16) == 0) {
3785     self->other_given_names = mxf_utf16_to_utf8 (tag_data, tag_size);
3786     GST_DEBUG ("  other given names = %s",
3787         GST_STR_NULL (self->other_given_names));
3788   } else if (memcmp (tag_ul, &linking_name_ul, 16) == 0) {
3789     self->linking_name = mxf_utf16_to_utf8 (tag_data, tag_size);
3790     GST_DEBUG ("  linking name = %s", GST_STR_NULL (self->linking_name));
3791   } else if (memcmp (tag_ul, &salutation_ul, 16) == 0) {
3792     self->salutation = mxf_utf16_to_utf8 (tag_data, tag_size);
3793     GST_DEBUG ("  salutation = %s", GST_STR_NULL (self->salutation));
3794   } else if (memcmp (tag_ul, &name_suffix_ul, 16) == 0) {
3795     self->name_suffix = mxf_utf16_to_utf8 (tag_data, tag_size);
3796     GST_DEBUG ("  name suffix = %s", GST_STR_NULL (self->name_suffix));
3797   } else if (memcmp (tag_ul, &honours_qualifications_ul, 16) == 0) {
3798     self->honours_qualifications = mxf_utf16_to_utf8 (tag_data, tag_size);
3799     GST_DEBUG ("  honours & qualifications = %s",
3800         GST_STR_NULL (self->honours_qualifications));
3801   } else if (memcmp (tag_ul, &former_family_name_ul, 16) == 0) {
3802     self->former_family_name = mxf_utf16_to_utf8 (tag_data, tag_size);
3803     GST_DEBUG ("  former family name = %s",
3804         GST_STR_NULL (self->former_family_name));
3805   } else if (memcmp (tag_ul, &person_description_ul, 16) == 0) {
3806     self->person_description = mxf_utf16_to_utf8 (tag_data, tag_size);
3807     GST_DEBUG ("  person description = %s",
3808         GST_STR_NULL (self->person_description));
3809   } else if (memcmp (tag_ul, &alternate_name_ul, 16) == 0) {
3810     self->alternate_name = mxf_utf16_to_utf8 (tag_data, tag_size);
3811     GST_DEBUG ("  alternate name = %s", GST_STR_NULL (self->alternate_name));
3812   } else if (memcmp (tag_ul, &nationality_ul, 16) == 0) {
3813     self->nationality = mxf_utf16_to_utf8 (tag_data, tag_size);
3814     GST_DEBUG ("  nationality = %s", GST_STR_NULL (self->nationality));
3815   } else if (memcmp (tag_ul, &citizenship_ul, 16) == 0) {
3816     self->citizenship = mxf_utf16_to_utf8 (tag_data, tag_size);
3817     GST_DEBUG ("  citizenship = %s", GST_STR_NULL (self->citizenship));
3818   } else if (memcmp (tag_ul, &organisation_sets_ul, 16) == 0) {
3819     if (!mxf_uuid_array_parse (&self->organisation_sets_uids,
3820             &self->n_organisation_sets, tag_data, tag_size))
3821       goto error;
3822     GST_DEBUG ("  number of organisation sets = %u", self->n_organisation_sets);
3823 #ifndef GST_DISABLE_GST_DEBUG
3824     {
3825       guint i;
3826       for (i = 0; i < self->n_organisation_sets; i++) {
3827         GST_DEBUG ("    organisation sets %u = %s", i,
3828             mxf_uuid_to_string (&self->organisation_sets_uids[i], str));
3829       }
3830     }
3831 #endif
3832   } else {
3833     ret =
3834         MXF_METADATA_BASE_CLASS (mxf_dms1_person_parent_class)->handle_tag
3835         (metadata, primer, tag, tag_data, tag_size);
3836   }
3837
3838   return ret;
3839
3840 error:
3841
3842   GST_ERROR ("Invalid DMS1 person local tag 0x%04x of size %u", tag, tag_size);
3843
3844   return FALSE;
3845 }
3846
3847 static void
3848 mxf_dms1_person_init (MXFDMS1Person * self)
3849 {
3850 }
3851
3852 static void
3853 mxf_dms1_person_class_init (MXFDMS1PersonClass * klass)
3854 {
3855   GObjectClass *object_class = (GObjectClass *) klass;
3856   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
3857   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
3858
3859   object_class->finalize = mxf_dms1_person_finalize;
3860   metadatabase_class->handle_tag = mxf_dms1_person_handle_tag;
3861   metadatabase_class->resolve = mxf_dms1_person_resolve;
3862   dm_class->type = 0x1a0200;
3863 }
3864
3865 G_DEFINE_TYPE (MXFDMS1Organisation, mxf_dms1_organisation,
3866     MXF_TYPE_DMS1_CONTACT);
3867
3868 static void
3869 mxf_dms1_organisation_finalize (GObject * object)
3870 {
3871   MXFDMS1Organisation *self = MXF_DMS1_ORGANISATION (object);
3872
3873   g_free (self->nature_of_organisation);
3874   self->nature_of_organisation = NULL;
3875
3876   g_free (self->organisation_main_name);
3877   self->organisation_main_name = NULL;
3878
3879   g_free (self->organisation_code);
3880   self->organisation_code = NULL;
3881
3882   g_free (self->contact_department);
3883   self->contact_department = NULL;
3884
3885   G_OBJECT_CLASS (mxf_dms1_organisation_parent_class)->finalize (object);
3886 }
3887
3888 static gboolean
3889 mxf_dms1_organisation_handle_tag (MXFMetadataBase * metadata,
3890     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
3891     guint tag_size)
3892 {
3893   MXFDMS1Organisation *self = MXF_DMS1_ORGANISATION (metadata);
3894   gboolean ret = TRUE;
3895   MXFUL *tag_ul = NULL;
3896   static const guint8 nature_of_organisation_ul[] = {
3897     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02,
3898     0x30, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00
3899   };
3900   static const guint8 organisation_main_name_ul[] = {
3901     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02,
3902     0x30, 0x06, 0x03, 0x03, 0x01, 0x01, 0x00
3903   };
3904   static const guint8 organisation_code_ul[] = {
3905     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x01,
3906     0x0a, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00
3907   };
3908   static const guint8 contact_department_ul[] = {
3909     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02,
3910     0x30, 0x06, 0x02, 0x01, 0x00, 0x00, 0x00
3911   };
3912
3913   if (!(tag_ul =
3914           (MXFUL *) g_hash_table_lookup (primer->mappings,
3915               GUINT_TO_POINTER (((guint) tag)))))
3916     return FALSE;
3917
3918   if (memcmp (tag_ul, &nature_of_organisation_ul, 16) == 0) {
3919     self->nature_of_organisation = mxf_utf16_to_utf8 (tag_data, tag_size);
3920     GST_DEBUG ("  nature of organisation = %s",
3921         GST_STR_NULL (self->nature_of_organisation));
3922   } else if (memcmp (tag_ul, &organisation_main_name_ul, 16) == 0) {
3923     self->organisation_main_name = mxf_utf16_to_utf8 (tag_data, tag_size);
3924     GST_DEBUG ("  organisation main name = %s",
3925         GST_STR_NULL (self->organisation_main_name));
3926   } else if (memcmp (tag_ul, &organisation_code_ul, 16) == 0) {
3927     self->organisation_code = mxf_utf16_to_utf8 (tag_data, tag_size);
3928     GST_DEBUG ("  organisation code = %s",
3929         GST_STR_NULL (self->organisation_code));
3930   } else if (memcmp (tag_ul, &contact_department_ul, 16) == 0) {
3931     self->contact_department = mxf_utf16_to_utf8 (tag_data, tag_size);
3932     GST_DEBUG ("  contact department = %s",
3933         GST_STR_NULL (self->contact_department));
3934   } else {
3935     ret =
3936         MXF_METADATA_BASE_CLASS (mxf_dms1_organisation_parent_class)->handle_tag
3937         (metadata, primer, tag, tag_data, tag_size);
3938   }
3939
3940   return ret;
3941 }
3942
3943 static void
3944 mxf_dms1_organisation_init (MXFDMS1Organisation * self)
3945 {
3946 }
3947
3948 static void
3949 mxf_dms1_organisation_class_init (MXFDMS1OrganisationClass * klass)
3950 {
3951   GObjectClass *object_class = (GObjectClass *) klass;
3952   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
3953   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
3954
3955   object_class->finalize = mxf_dms1_organisation_finalize;
3956   metadatabase_class->handle_tag = mxf_dms1_organisation_handle_tag;
3957   dm_class->type = 0x1a0300;
3958 }
3959
3960 G_DEFINE_TYPE (MXFDMS1Location, mxf_dms1_location, MXF_TYPE_DMS1_CONTACT);
3961
3962 static void
3963 mxf_dms1_location_finalize (GObject * object)
3964 {
3965   MXFDMS1Location *self = MXF_DMS1_LOCATION (object);
3966
3967   g_free (self->location_kind);
3968   self->location_kind = NULL;
3969
3970   g_free (self->location_description);
3971   self->location_description = NULL;
3972
3973   G_OBJECT_CLASS (mxf_dms1_location_parent_class)->finalize (object);
3974 }
3975
3976 static gboolean
3977 mxf_dms1_location_handle_tag (MXFMetadataBase * metadata,
3978     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
3979     guint tag_size)
3980 {
3981   MXFDMS1Location *self = MXF_DMS1_LOCATION (metadata);
3982   gboolean ret = TRUE;
3983   MXFUL *tag_ul = NULL;
3984   static const guint8 location_kind_ul[] = {
3985     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x07,
3986     0x01, 0x20, 0x02, 0x03, 0x01, 0x00, 0x00
3987   };
3988   static const guint8 location_description_ul[] = {
3989     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x07,
3990     0x01, 0x20, 0x02, 0x02, 0x01, 0x00, 0x00
3991   };
3992
3993   if (!(tag_ul =
3994           (MXFUL *) g_hash_table_lookup (primer->mappings,
3995               GUINT_TO_POINTER (((guint) tag)))))
3996     return FALSE;
3997
3998   if (memcmp (tag_ul, &location_kind_ul, 16) == 0) {
3999     self->location_kind = mxf_utf16_to_utf8 (tag_data, tag_size);
4000     GST_DEBUG ("  location kind = %s", GST_STR_NULL (self->location_kind));
4001   } else if (memcmp (tag_ul, &location_description_ul, 16) == 0) {
4002     self->location_description = mxf_utf16_to_utf8 (tag_data, tag_size);
4003     GST_DEBUG ("  location description = %s",
4004         GST_STR_NULL (self->location_description));
4005   } else {
4006     ret =
4007         MXF_METADATA_BASE_CLASS (mxf_dms1_location_parent_class)->handle_tag
4008         (metadata, primer, tag, tag_data, tag_size);
4009   }
4010
4011   return ret;
4012 }
4013
4014 static void
4015 mxf_dms1_location_init (MXFDMS1Location * self)
4016 {
4017 }
4018
4019 static void
4020 mxf_dms1_location_class_init (MXFDMS1LocationClass * klass)
4021 {
4022   GObjectClass *object_class = (GObjectClass *) klass;
4023   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
4024   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
4025
4026   object_class->finalize = mxf_dms1_location_finalize;
4027   metadatabase_class->handle_tag = mxf_dms1_location_handle_tag;
4028   dm_class->type = 0x1a0400;
4029 }
4030
4031 G_DEFINE_TYPE (MXFDMS1Address, mxf_dms1_address, MXF_TYPE_DMS1);
4032
4033 static void
4034 mxf_dms1_address_finalize (GObject * object)
4035 {
4036   MXFDMS1Address *self = MXF_DMS1_ADDRESS (object);
4037
4038   g_free (self->room_or_suite_number);
4039   self->room_or_suite_number = NULL;
4040
4041   g_free (self->room_or_suite_name);
4042   self->room_or_suite_name = NULL;
4043
4044   g_free (self->building_name);
4045   self->building_name = NULL;
4046
4047   g_free (self->street_number);
4048   self->street_number = NULL;
4049
4050   g_free (self->street_name);
4051   self->street_name = NULL;
4052
4053   g_free (self->postal_town);
4054   self->postal_town = NULL;
4055
4056   g_free (self->city);
4057   self->city = NULL;
4058
4059   g_free (self->state_or_province_or_country);
4060   self->state_or_province_or_country = NULL;
4061
4062   g_free (self->postal_code);
4063   self->postal_code = NULL;
4064
4065   g_free (self->country);
4066   self->country = NULL;
4067
4068   g_free (self->astronomical_body_name);
4069   self->astronomical_body_name = NULL;
4070
4071   g_free (self->communications_sets_uids);
4072   self->communications_sets_uids = NULL;
4073
4074   g_free (self->communications_sets);
4075   self->communications_sets = NULL;
4076
4077   g_free (self->name_value_sets_uids);
4078   self->name_value_sets_uids = NULL;
4079
4080   g_free (self->name_value_sets);
4081   self->name_value_sets = NULL;
4082
4083   G_OBJECT_CLASS (mxf_dms1_address_parent_class)->finalize (object);
4084 }
4085
4086 static gboolean
4087 mxf_dms1_address_resolve (MXFMetadataBase * m, GHashTable * metadata)
4088 {
4089   MXFDMS1Address *self = MXF_DMS1_ADDRESS (m);
4090   MXFMetadataBase *current = NULL;
4091   guint i;
4092
4093   if (self->communications_sets)
4094     memset (self->communications_sets, 0,
4095         sizeof (gpointer) * self->n_communications_sets);
4096   else
4097     self->communications_sets =
4098         g_new0 (MXFDMS1Communications *, self->n_communications_sets);
4099
4100   if (self->name_value_sets)
4101     memset (self->name_value_sets, 0,
4102         sizeof (gpointer) * self->n_name_value_sets);
4103   else
4104     self->name_value_sets =
4105         g_new0 (MXFDMS1NameValue *, self->n_name_value_sets);
4106
4107   for (i = 0; i < self->n_communications_sets; i++) {
4108     current =
4109         g_hash_table_lookup (metadata, &self->communications_sets_uids[i]);
4110     if (current && MXF_IS_DMS1_COMMUNICATIONS (current)) {
4111       self->communications_sets[i] = MXF_DMS1_COMMUNICATIONS (current);
4112     }
4113   }
4114
4115   for (i = 0; i < self->n_name_value_sets; i++) {
4116     current = g_hash_table_lookup (metadata, &self->name_value_sets_uids[i]);
4117     if (current && MXF_IS_DMS1_NAME_VALUE (current)) {
4118       self->name_value_sets[i] = MXF_DMS1_NAME_VALUE (current);
4119     }
4120   }
4121
4122   return MXF_METADATA_BASE_CLASS (mxf_dms1_address_parent_class)->resolve (m,
4123       metadata);
4124 }
4125
4126 static gboolean
4127 mxf_dms1_address_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer,
4128     guint16 tag, const guint8 * tag_data, guint tag_size)
4129 {
4130   MXFDMS1Address *self = MXF_DMS1_ADDRESS (metadata);
4131   gboolean ret = TRUE;
4132 #ifndef GST_DISABLE_GST_DEBUG
4133   gchar str[48];
4134 #endif
4135   MXFUL *tag_ul = NULL;
4136   static const guint8 room_or_suite_number_ul[] = {
4137     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x07,
4138     0x01, 0x20, 0x01, 0x04, 0x01, 0x01, 0x01
4139   };
4140   static const guint8 room_or_suite_name_ul[] = {
4141     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x07,
4142     0x01, 0x20, 0x01, 0x04, 0x01, 0x11, 0x01
4143   };
4144   static const guint8 building_name_ul[] = {
4145     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x07,
4146     0x01, 0x20, 0x01, 0x04, 0x01, 0x12, 0x01
4147   };
4148   static const guint8 place_name_ul[] = {
4149     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x07,
4150     0x01, 0x20, 0x01, 0x04, 0x01, 0x14, 0x01
4151   };
4152   static const guint8 street_number_ul[] = {
4153     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x07,
4154     0x01, 0x20, 0x01, 0x04, 0x01, 0x02, 0x01
4155   };
4156   static const guint8 street_name_ul[] = {
4157     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x07,
4158     0x01, 0x20, 0x01, 0x04, 0x01, 0x03, 0x01
4159   };
4160   static const guint8 postal_town_ul[] = {
4161     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x07,
4162     0x01, 0x20, 0x01, 0x04, 0x01, 0x04, 0x01
4163   };
4164   static const guint8 city_ul[] = {
4165     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x07,
4166     0x01, 0x20, 0x01, 0x04, 0x01, 0x05, 0x01
4167   };
4168   static const guint8 state_or_province_or_country_ul[] = {
4169     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x07,
4170     0x01, 0x20, 0x01, 0x04, 0x01, 0x06, 0x01
4171   };
4172   static const guint8 postal_code_ul[] = {
4173     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x07,
4174     0x01, 0x20, 0x01, 0x04, 0x01, 0x07, 0x01
4175   };
4176   static const guint8 country_ul[] = {
4177     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x07,
4178     0x01, 0x20, 0x01, 0x04, 0x01, 0x08, 0x01
4179   };
4180   static const guint8 geographical_coordinate_ul[] = {
4181     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x07,
4182     0x01, 0x20, 0x01, 0x04, 0x01, 0x15, 0x01
4183   };
4184   static const guint8 astronomical_body_name_ul[] = {
4185     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x07,
4186     0x01, 0x20, 0x01, 0x04, 0x01, 0x16, 0x01
4187   };
4188   static const guint8 communications_sets_ul[] = {
4189     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
4190     0x01, 0x01, 0x04, 0x05, 0x40, 0x19, 0x00
4191   };
4192   static const guint8 name_value_sets_ul[] = {
4193     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, 0x06,
4194     0x01, 0x01, 0x04, 0x05, 0x40, 0x1f, 0x04
4195   };
4196
4197   if (!(tag_ul =
4198           (MXFUL *) g_hash_table_lookup (primer->mappings,
4199               GUINT_TO_POINTER (((guint) tag)))))
4200     return FALSE;
4201
4202   if (memcmp (tag_ul, &room_or_suite_name_ul, 16) == 0) {
4203     self->room_or_suite_name = mxf_utf16_to_utf8 (tag_data, tag_size);
4204     GST_DEBUG ("  room or suite name = %s",
4205         GST_STR_NULL (self->room_or_suite_name));
4206   } else if (memcmp (tag_ul, &room_or_suite_number_ul, 16) == 0) {
4207     self->room_or_suite_number = mxf_utf16_to_utf8 (tag_data, tag_size);
4208     GST_DEBUG ("  room or suite number = %s",
4209         GST_STR_NULL (self->room_or_suite_number));
4210   } else if (memcmp (tag_ul, &building_name_ul, 16) == 0) {
4211     self->building_name = mxf_utf16_to_utf8 (tag_data, tag_size);
4212     GST_DEBUG ("  building name = %s", GST_STR_NULL (self->building_name));
4213   } else if (memcmp (tag_ul, &place_name_ul, 16) == 0) {
4214     self->place_name = mxf_utf16_to_utf8 (tag_data, tag_size);
4215     GST_DEBUG ("  place name = %s", GST_STR_NULL (self->place_name));
4216   } else if (memcmp (tag_ul, &street_number_ul, 16) == 0) {
4217     self->street_number = mxf_utf16_to_utf8 (tag_data, tag_size);
4218     GST_DEBUG ("  street number = %s", GST_STR_NULL (self->street_number));
4219   } else if (memcmp (tag_ul, &street_name_ul, 16) == 0) {
4220     self->street_name = mxf_utf16_to_utf8 (tag_data, tag_size);
4221     GST_DEBUG ("  street name = %s", GST_STR_NULL (self->street_name));
4222   } else if (memcmp (tag_ul, &postal_town_ul, 16) == 0) {
4223     self->postal_town = mxf_utf16_to_utf8 (tag_data, tag_size);
4224     GST_DEBUG ("  postal town = %s", GST_STR_NULL (self->postal_town));
4225   } else if (memcmp (tag_ul, &city_ul, 16) == 0) {
4226     self->city = mxf_utf16_to_utf8 (tag_data, tag_size);
4227     GST_DEBUG ("  city = %s", GST_STR_NULL (self->city));
4228   } else if (memcmp (tag_ul, &state_or_province_or_country_ul, 16) == 0) {
4229     self->state_or_province_or_country = mxf_utf16_to_utf8 (tag_data, tag_size);
4230     GST_DEBUG ("  state or province or country = %s",
4231         GST_STR_NULL (self->state_or_province_or_country));
4232   } else if (memcmp (tag_ul, &postal_code_ul, 16) == 0) {
4233     self->postal_code = mxf_utf16_to_utf8 (tag_data, tag_size);
4234     GST_DEBUG ("  postal code = %s", GST_STR_NULL (self->postal_code));
4235   } else if (memcmp (tag_ul, &country_ul, 16) == 0) {
4236     self->country = mxf_utf16_to_utf8 (tag_data, tag_size);
4237     GST_DEBUG ("  country = %s", GST_STR_NULL (self->country));
4238   } else if (memcmp (tag_ul, &geographical_coordinate_ul, 16) == 0) {
4239     if (tag_size != 12)
4240       goto error;
4241
4242     memcpy (&self->geographical_coordinate, tag_data, 12);
4243     /* TODO implement */
4244   } else if (memcmp (tag_ul, &astronomical_body_name_ul, 16) == 0) {
4245     self->astronomical_body_name = mxf_utf16_to_utf8 (tag_data, tag_size);
4246     GST_DEBUG ("  astronomical body name = %s",
4247         GST_STR_NULL (self->astronomical_body_name));
4248   } else if (memcmp (tag_ul, &communications_sets_ul, 16) == 0) {
4249     if (!mxf_uuid_array_parse (&self->communications_sets_uids,
4250             &self->n_communications_sets, tag_data, tag_size))
4251       goto error;
4252     GST_DEBUG ("  number of communications sets = %u",
4253         self->n_communications_sets);
4254 #ifndef GST_DISABLE_GST_DEBUG
4255     {
4256       guint i;
4257       for (i = 0; i < self->n_communications_sets; i++) {
4258         GST_DEBUG ("    communications sets %u = %s", i,
4259             mxf_uuid_to_string (&self->communications_sets_uids[i], str));
4260       }
4261     }
4262 #endif
4263   } else if (memcmp (tag_ul, &name_value_sets_ul, 16) == 0) {
4264     if (!mxf_uuid_array_parse (&self->name_value_sets_uids,
4265             &self->n_name_value_sets, tag_data, tag_size))
4266       goto error;
4267     GST_DEBUG ("  number of name-value sets = %u", self->n_name_value_sets);
4268 #ifndef GST_DISABLE_GST_DEBUG
4269     {
4270       guint i;
4271       for (i = 0; i < self->n_name_value_sets; i++) {
4272         GST_DEBUG ("    name-value sets %u = %s", i,
4273             mxf_uuid_to_string (&self->name_value_sets_uids[i], str));
4274       }
4275     }
4276 #endif
4277   } else {
4278     ret =
4279         MXF_METADATA_BASE_CLASS (mxf_dms1_address_parent_class)->handle_tag
4280         (metadata, primer, tag, tag_data, tag_size);
4281   }
4282
4283   return ret;
4284
4285 error:
4286
4287   GST_ERROR ("Invalid DMS1 address local tag 0x%04x of size %u", tag, tag_size);
4288
4289   return FALSE;
4290 }
4291
4292 static void
4293 mxf_dms1_address_init (MXFDMS1Address * self)
4294 {
4295 }
4296
4297 static void
4298 mxf_dms1_address_class_init (MXFDMS1AddressClass * klass)
4299 {
4300   GObjectClass *object_class = (GObjectClass *) klass;
4301   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
4302   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
4303
4304   object_class->finalize = mxf_dms1_address_finalize;
4305   metadatabase_class->handle_tag = mxf_dms1_address_handle_tag;
4306   metadatabase_class->resolve = mxf_dms1_address_resolve;
4307   dm_class->type = 0x1b0100;
4308 }
4309
4310 G_DEFINE_TYPE (MXFDMS1Communications, mxf_dms1_communications, MXF_TYPE_DMS1);
4311
4312 static void
4313 mxf_dms1_communications_finalize (GObject * object)
4314 {
4315   MXFDMS1Communications *self = MXF_DMS1_COMMUNICATIONS (object);
4316
4317   g_free (self->email_address);
4318   self->email_address = NULL;
4319
4320   g_free (self->web_page);
4321   self->web_page = NULL;
4322
4323   G_OBJECT_CLASS (mxf_dms1_communications_parent_class)->finalize (object);
4324 }
4325
4326 static gboolean
4327 mxf_dms1_communications_handle_tag (MXFMetadataBase * metadata,
4328     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
4329     guint tag_size)
4330 {
4331   MXFDMS1Communications *self = MXF_DMS1_COMMUNICATIONS (metadata);
4332   gboolean ret = TRUE;
4333   MXFUL *tag_ul = NULL;
4334   static const guint8 central_telephone_number_ul[] = {
4335     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x07,
4336     0x01, 0x20, 0x01, 0x10, 0x03, 0x04, 0x00
4337   };
4338   static const guint8 telephone_number_ul[] = {
4339     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x07,
4340     0x01, 0x20, 0x01, 0x10, 0x03, 0x01, 0x00
4341   };
4342   static const guint8 mobile_telephone_number_ul[] = {
4343     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x07,
4344     0x01, 0x20, 0x01, 0x10, 0x03, 0x05, 0x00
4345   };
4346   static const guint8 fax_number_ul[] = {
4347     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x07,
4348     0x01, 0x20, 0x01, 0x10, 0x03, 0x02, 0x00
4349   };
4350   static const guint8 email_address_ul[] = {
4351     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x07,
4352     0x01, 0x20, 0x01, 0x10, 0x03, 0x03, 0x01
4353   };
4354   static const guint8 web_page_ul[] = {
4355     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x07,
4356     0x01, 0x20, 0x01, 0x10, 0x03, 0x06, 0x01
4357   };
4358
4359   if (!(tag_ul =
4360           (MXFUL *) g_hash_table_lookup (primer->mappings,
4361               GUINT_TO_POINTER (((guint) tag)))))
4362     return FALSE;
4363
4364   if (memcmp (tag_ul, &central_telephone_number_ul, 16) == 0) {
4365     if (tag_size > 32)
4366       goto error;
4367     memcpy (self->central_telephone_number, tag_data, tag_size);
4368
4369     GST_DEBUG ("  central telephone number = %s",
4370         self->central_telephone_number);
4371   } else if (memcmp (tag_ul, &telephone_number_ul, 16) == 0) {
4372     if (tag_size > 32)
4373       goto error;
4374     memcpy (self->telephone_number, tag_data, tag_size);
4375
4376     GST_DEBUG ("  telephone number = %s", self->telephone_number);
4377   } else if (memcmp (tag_ul, &mobile_telephone_number_ul, 16) == 0) {
4378     if (tag_size > 32)
4379       goto error;
4380     memcpy (self->mobile_telephone_number, tag_data, tag_size);
4381
4382     GST_DEBUG ("  mobile telephone number = %s", self->mobile_telephone_number);
4383   } else if (memcmp (tag_ul, &fax_number_ul, 16) == 0) {
4384     if (tag_size > 32)
4385       goto error;
4386     memcpy (self->fax_number, tag_data, tag_size);
4387
4388     GST_DEBUG ("  fax number = %s", self->fax_number);
4389   } else if (memcmp (tag_ul, &email_address_ul, 16) == 0) {
4390     self->email_address = mxf_utf16_to_utf8 (tag_data, tag_size);
4391     GST_DEBUG ("  email address = %s", GST_STR_NULL (self->email_address));
4392   } else if (memcmp (tag_ul, &web_page_ul, 16) == 0) {
4393     self->web_page = mxf_utf16_to_utf8 (tag_data, tag_size);
4394     GST_DEBUG ("  web page = %s", GST_STR_NULL (self->web_page));
4395   } else {
4396     ret =
4397         MXF_METADATA_BASE_CLASS
4398         (mxf_dms1_communications_parent_class)->handle_tag (metadata, primer,
4399         tag, tag_data, tag_size);
4400   }
4401
4402   return ret;
4403
4404 error:
4405
4406   GST_ERROR ("Invalid DMS1 communications local tag 0x%04x of size %u", tag,
4407       tag_size);
4408
4409   return FALSE;
4410 }
4411
4412 static void
4413 mxf_dms1_communications_init (MXFDMS1Communications * self)
4414 {
4415 }
4416
4417 static void
4418 mxf_dms1_communications_class_init (MXFDMS1CommunicationsClass * klass)
4419 {
4420   GObjectClass *object_class = (GObjectClass *) klass;
4421   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
4422   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
4423
4424   object_class->finalize = mxf_dms1_communications_finalize;
4425   metadatabase_class->handle_tag = mxf_dms1_communications_handle_tag;
4426   dm_class->type = 0x1b0200;
4427 }
4428
4429 G_DEFINE_TYPE (MXFDMS1Contract, mxf_dms1_contract, MXF_TYPE_DMS1_THESAURUS);
4430
4431 static void
4432 mxf_dms1_contract_finalize (GObject * object)
4433 {
4434   MXFDMS1Contract *self = MXF_DMS1_CONTRACT (object);
4435
4436   g_free (self->rights_sets_uids);
4437   self->rights_sets_uids = NULL;
4438
4439   g_free (self->rights_sets);
4440   self->rights_sets = NULL;
4441
4442   g_free (self->participant_sets_uids);
4443   self->participant_sets_uids = NULL;
4444
4445   g_free (self->participant_sets);
4446   self->participant_sets = NULL;
4447
4448   G_OBJECT_CLASS (mxf_dms1_contract_parent_class)->finalize (object);
4449 }
4450
4451 static gboolean
4452 mxf_dms1_contract_resolve (MXFMetadataBase * m, GHashTable * metadata)
4453 {
4454   MXFDMS1Contract *self = MXF_DMS1_CONTRACT (m);
4455   MXFMetadataBase *current = NULL;
4456   guint i;
4457
4458   if (self->rights_sets)
4459     memset (self->rights_sets, 0, sizeof (gpointer) * self->n_rights_sets);
4460   else
4461     self->rights_sets = g_new0 (MXFDMS1Rights *, self->n_rights_sets);
4462
4463   if (self->participant_sets)
4464     memset (self->participant_sets, 0,
4465         sizeof (gpointer) * self->n_participant_sets);
4466   else
4467     self->participant_sets =
4468         g_new0 (MXFDMS1Participant *, self->n_participant_sets);
4469
4470   for (i = 0; i < self->n_rights_sets; i++) {
4471     current = g_hash_table_lookup (metadata, &self->rights_sets_uids[i]);
4472     if (current && MXF_IS_DMS1_RIGHTS (current)) {
4473       self->rights_sets[i] = MXF_DMS1_RIGHTS (current);
4474     }
4475   }
4476
4477   for (i = 0; i < self->n_participant_sets; i++) {
4478     current = g_hash_table_lookup (metadata, &self->participant_sets_uids[i]);
4479     if (current && MXF_IS_DMS1_PARTICIPANT (current)) {
4480       self->participant_sets[i] = MXF_DMS1_PARTICIPANT (current);
4481     }
4482   }
4483
4484   return MXF_METADATA_BASE_CLASS (mxf_dms1_contract_parent_class)->resolve (m,
4485       metadata);
4486 }
4487
4488 static gboolean
4489 mxf_dms1_contract_handle_tag (MXFMetadataBase * metadata,
4490     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
4491     guint tag_size)
4492 {
4493   MXFDMS1Contract *self = MXF_DMS1_CONTRACT (metadata);
4494   gboolean ret = TRUE;
4495 #ifndef GST_DISABLE_GST_DEBUG
4496   gchar str[48];
4497 #endif
4498   MXFUL *tag_ul = NULL;
4499   static const guint8 supply_contract_number_ul[] = {
4500     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x02,
4501     0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00
4502   };
4503   static const guint8 rights_sets_ul[] = {
4504     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
4505     0x01, 0x01, 0x04, 0x05, 0x40, 0x1a, 0x00
4506   };
4507   static const guint8 participant_sets_ul[] = {
4508     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
4509     0x01, 0x01, 0x04, 0x03, 0x40, 0x13, 0x02
4510   };
4511
4512   if (!(tag_ul =
4513           (MXFUL *) g_hash_table_lookup (primer->mappings,
4514               GUINT_TO_POINTER (((guint) tag)))))
4515     return FALSE;
4516
4517   if (memcmp (tag_ul, &supply_contract_number_ul, 16) == 0) {
4518     if (tag_size > 32)
4519       goto error;
4520
4521     memcpy (self->supply_contract_number, tag_data, tag_size);
4522     GST_DEBUG ("  supply contract number = %s", self->supply_contract_number);
4523   } else if (memcmp (tag_ul, &rights_sets_ul, 16) == 0) {
4524     if (!mxf_uuid_array_parse (&self->rights_sets_uids, &self->n_rights_sets,
4525             tag_data, tag_size))
4526       goto error;
4527     GST_DEBUG ("  number of rights sets = %u", self->n_rights_sets);
4528 #ifndef GST_DISABLE_GST_DEBUG
4529     {
4530       guint i;
4531       for (i = 0; i < self->n_rights_sets; i++) {
4532         GST_DEBUG ("    rights sets %u = %s", i,
4533             mxf_uuid_to_string (&self->rights_sets_uids[i], str));
4534       }
4535     }
4536 #endif
4537   } else if (memcmp (tag_ul, &participant_sets_ul, 16) == 0) {
4538     if (!mxf_uuid_array_parse (&self->participant_sets_uids,
4539             &self->n_participant_sets, tag_data, tag_size))
4540       goto error;
4541     GST_DEBUG ("  number of participant sets = %u", self->n_participant_sets);
4542 #ifndef GST_DISABLE_GST_DEBUG
4543     {
4544       guint i;
4545       for (i = 0; i < self->n_participant_sets; i++) {
4546         GST_DEBUG ("    participant sets %u = %s", i,
4547             mxf_uuid_to_string (&self->participant_sets_uids[i], str));
4548       }
4549     }
4550 #endif
4551   } else {
4552     ret =
4553         MXF_METADATA_BASE_CLASS (mxf_dms1_contract_parent_class)->handle_tag
4554         (metadata, primer, tag, tag_data, tag_size);
4555   }
4556
4557   return ret;
4558
4559 error:
4560
4561   GST_ERROR ("Invalid DMS1 contract local tag 0x%04x of size %u", tag,
4562       tag_size);
4563
4564   return FALSE;
4565 }
4566
4567 static void
4568 mxf_dms1_contract_init (MXFDMS1Contract * self)
4569 {
4570 }
4571
4572 static void
4573 mxf_dms1_contract_class_init (MXFDMS1ContractClass * klass)
4574 {
4575   GObjectClass *object_class = (GObjectClass *) klass;
4576   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
4577   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
4578
4579   object_class->finalize = mxf_dms1_contract_finalize;
4580   metadatabase_class->handle_tag = mxf_dms1_contract_handle_tag;
4581   metadatabase_class->resolve = mxf_dms1_contract_resolve;
4582   dm_class->type = 0x1c0100;
4583 }
4584
4585 G_DEFINE_TYPE (MXFDMS1Rights, mxf_dms1_rights, MXF_TYPE_DMS1_THESAURUS);
4586
4587 static void
4588 mxf_dms1_rights_finalize (GObject * object)
4589 {
4590   MXFDMS1Rights *self = MXF_DMS1_RIGHTS (object);
4591
4592   g_free (self->copyright_owner);
4593   self->copyright_owner = NULL;
4594
4595   g_free (self->rights_holder);
4596   self->rights_holder = NULL;
4597
4598   g_free (self->rights_managment_authority);
4599   self->rights_managment_authority = NULL;
4600
4601   g_free (self->region_or_area_of_ip_license);
4602   self->region_or_area_of_ip_license = NULL;
4603
4604   g_free (self->intellectual_property_type);
4605   self->intellectual_property_type = NULL;
4606
4607   g_free (self->right_condition);
4608   self->right_condition = NULL;
4609
4610   g_free (self->right_remarks);
4611   self->right_remarks = NULL;
4612
4613   g_free (self->intellectual_property_right);
4614   self->intellectual_property_right = NULL;
4615
4616   G_OBJECT_CLASS (mxf_dms1_rights_parent_class)->finalize (object);
4617 }
4618
4619 static gboolean
4620 mxf_dms1_rights_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer,
4621     guint16 tag, const guint8 * tag_data, guint tag_size)
4622 {
4623   MXFDMS1Rights *self = MXF_DMS1_RIGHTS (metadata);
4624   gboolean ret = TRUE;
4625   MXFUL *tag_ul = NULL;
4626 #ifndef GST_DISABLE_GST_DEBUG
4627   gchar str[32];
4628 #endif
4629   static const guint8 copyright_owner_ul[] = {
4630     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02,
4631     0x05, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00
4632   };
4633   static const guint8 rights_holder_ul[] = {
4634     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02,
4635     0x05, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00
4636   };
4637   static const guint8 rights_managment_authority_ul[] = {
4638     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02,
4639     0x05, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00
4640   };
4641   static const guint8 region_or_area_of_ip_license_ul[] = {
4642     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x07,
4643     0x01, 0x20, 0x01, 0x03, 0x05, 0x01, 0x00
4644   };
4645   static const guint8 intellectual_property_type_ul[] = {
4646     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02,
4647     0x05, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00
4648   };
4649   static const guint8 right_condition_ul[] = {
4650     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02,
4651     0x05, 0x04, 0x03, 0x01, 0x00, 0x00, 0x00
4652   };
4653   static const guint8 right_remarks_ul[] = {
4654     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08, 0x02,
4655     0x05, 0x04, 0x04, 0x01, 0x00, 0x00, 0x00
4656   };
4657   static const guint8 intellectual_property_right_ul[] = {
4658     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x02,
4659     0x05, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00
4660   };
4661   static const guint8 rights_start_date_and_time_ul[] = {
4662     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x07,
4663     0x02, 0x01, 0x20, 0x02, 0x00, 0x00, 0x00
4664   };
4665   static const guint8 rights_stop_date_and_time_ul[] = {
4666     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x07,
4667     0x02, 0x01, 0x20, 0x03, 0x00, 0x00, 0x00
4668   };
4669   static const guint8 maximum_number_of_usages_ul[] = {
4670     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x02,
4671     0x05, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00
4672   };
4673
4674   if (!(tag_ul =
4675           (MXFUL *) g_hash_table_lookup (primer->mappings,
4676               GUINT_TO_POINTER (((guint) tag)))))
4677     return FALSE;
4678
4679   if (memcmp (tag_ul, &copyright_owner_ul, 16) == 0) {
4680     self->copyright_owner = mxf_utf16_to_utf8 (tag_data, tag_size);
4681     GST_DEBUG ("  copyright owner = %s", GST_STR_NULL (self->copyright_owner));
4682   } else if (memcmp (tag_ul, &rights_holder_ul, 16) == 0) {
4683     self->rights_holder = mxf_utf16_to_utf8 (tag_data, tag_size);
4684     GST_DEBUG ("  rights holder = %s", GST_STR_NULL (self->rights_holder));
4685   } else if (memcmp (tag_ul, &rights_managment_authority_ul, 16) == 0) {
4686     self->rights_managment_authority = mxf_utf16_to_utf8 (tag_data, tag_size);
4687     GST_DEBUG ("  rights managment authority = %s",
4688         GST_STR_NULL (self->rights_managment_authority));
4689   } else if (memcmp (tag_ul, &region_or_area_of_ip_license_ul, 16) == 0) {
4690     self->region_or_area_of_ip_license = mxf_utf16_to_utf8 (tag_data, tag_size);
4691     GST_DEBUG ("  region or area of ip license = %s",
4692         GST_STR_NULL (self->region_or_area_of_ip_license));
4693   } else if (memcmp (tag_ul, &intellectual_property_type_ul, 16) == 0) {
4694     self->intellectual_property_type = mxf_utf16_to_utf8 (tag_data, tag_size);
4695     GST_DEBUG ("  intellectual property type = %s",
4696         GST_STR_NULL (self->intellectual_property_type));
4697   } else if (memcmp (tag_ul, &right_condition_ul, 16) == 0) {
4698     self->right_condition = mxf_utf16_to_utf8 (tag_data, tag_size);
4699     GST_DEBUG ("  right condition = %s", GST_STR_NULL (self->right_condition));
4700   } else if (memcmp (tag_ul, &right_remarks_ul, 16) == 0) {
4701     self->right_remarks = mxf_utf16_to_utf8 (tag_data, tag_size);
4702     GST_DEBUG ("  right remarks = %s", GST_STR_NULL (self->right_remarks));
4703   } else if (memcmp (tag_ul, &intellectual_property_right_ul, 16) == 0) {
4704     self->intellectual_property_right = mxf_utf16_to_utf8 (tag_data, tag_size);
4705     GST_DEBUG ("  intellectual property right = %s",
4706         GST_STR_NULL (self->intellectual_property_right));
4707   } else if (memcmp (tag_ul, &rights_start_date_and_time_ul, 16) == 0) {
4708     if (!mxf_timestamp_parse (&self->rights_start_date_and_time, tag_data,
4709             tag_size))
4710       goto error;
4711
4712     GST_DEBUG ("  rights start date and time = %s",
4713         mxf_timestamp_to_string (&self->rights_start_date_and_time, str));
4714   } else if (memcmp (tag_ul, &rights_stop_date_and_time_ul, 16) == 0) {
4715     if (!mxf_timestamp_parse (&self->rights_stop_date_and_time, tag_data,
4716             tag_size))
4717       goto error;
4718
4719     GST_DEBUG ("  rights stop date and time = %s",
4720         mxf_timestamp_to_string (&self->rights_stop_date_and_time, str));
4721   } else if (memcmp (tag_ul, &maximum_number_of_usages_ul, 16) == 0) {
4722     if (tag_size != 2)
4723       goto error;
4724
4725     self->maximum_number_of_usages = GST_READ_UINT16_BE (tag_data);
4726     GST_DEBUG ("  maximum number of usages = %u",
4727         self->maximum_number_of_usages);
4728   } else {
4729     ret =
4730         MXF_METADATA_BASE_CLASS (mxf_dms1_rights_parent_class)->handle_tag
4731         (metadata, primer, tag, tag_data, tag_size);
4732   }
4733
4734   return ret;
4735
4736 error:
4737
4738   GST_ERROR ("Invalid DMS1 rights local tag 0x%04x of size %u", tag, tag_size);
4739
4740   return FALSE;
4741 }
4742
4743 static void
4744 mxf_dms1_rights_init (MXFDMS1Rights * self)
4745 {
4746 }
4747
4748 static void
4749 mxf_dms1_rights_class_init (MXFDMS1RightsClass * klass)
4750 {
4751   GObjectClass *object_class = (GObjectClass *) klass;
4752   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
4753   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
4754
4755   object_class->finalize = mxf_dms1_rights_finalize;
4756   metadatabase_class->handle_tag = mxf_dms1_rights_handle_tag;
4757   dm_class->type = 0x1c0200;
4758 }
4759
4760 G_DEFINE_TYPE (MXFDMS1PictureFormat, mxf_dms1_picture_format, MXF_TYPE_DMS1);
4761
4762 static void
4763 mxf_dms1_picture_format_finalize (GObject * object)
4764 {
4765   MXFDMS1PictureFormat *self = MXF_DMS1_PICTURE_FORMAT (object);
4766
4767   g_free (self->colour_descriptor);
4768   self->colour_descriptor = NULL;
4769
4770   G_OBJECT_CLASS (mxf_dms1_picture_format_parent_class)->finalize (object);
4771 }
4772
4773 static gboolean
4774 mxf_dms1_picture_format_handle_tag (MXFMetadataBase * metadata,
4775     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
4776     guint tag_size)
4777 {
4778   MXFDMS1PictureFormat *self = MXF_DMS1_PICTURE_FORMAT (metadata);
4779   gboolean ret = TRUE;
4780   MXFUL *tag_ul = NULL;
4781   static const guint8 viewport_aspect_ratio_ul[] = {
4782     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, 0x04,
4783     0x01, 0x01, 0x01, 0x03, 0x00, 0x00, 0x00
4784   };
4785   static const guint8 perceived_display_format_ul[] = {
4786     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x04,
4787     0x01, 0x01, 0x01, 0x08, 0x00, 0x00, 0x00
4788   };
4789   static const guint8 colour_descriptor_ul[] = {
4790     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x03,
4791     0x02, 0x01, 0x06, 0x04, 0x01, 0x00, 0x00
4792   };
4793
4794   if (!(tag_ul =
4795           (MXFUL *) g_hash_table_lookup (primer->mappings,
4796               GUINT_TO_POINTER (((guint) tag)))))
4797     return FALSE;
4798
4799   if (memcmp (tag_ul, &viewport_aspect_ratio_ul, 16) == 0) {
4800     if (!mxf_fraction_parse (&self->viewport_aspect_ratio, tag_data, tag_size))
4801       goto error;
4802
4803     GST_DEBUG ("  viewport aspect ratio = %u/%u", self->viewport_aspect_ratio.n,
4804         self->viewport_aspect_ratio.d);
4805   } else if (memcmp (tag_ul, &perceived_display_format_ul, 16) == 0) {
4806     if (tag_size > 32)
4807       goto error;
4808
4809     memcpy (self->perceived_display_format, tag_data, tag_size);
4810     GST_DEBUG ("  perceived display format = %s",
4811         self->perceived_display_format);
4812   } else if (memcmp (tag_ul, &colour_descriptor_ul, 16) == 0) {
4813     self->colour_descriptor = mxf_utf16_to_utf8 (tag_data, tag_size);
4814     GST_DEBUG ("  colour descriptor = %s",
4815         GST_STR_NULL (self->colour_descriptor));
4816   } else {
4817     ret =
4818         MXF_METADATA_BASE_CLASS
4819         (mxf_dms1_picture_format_parent_class)->handle_tag (metadata, primer,
4820         tag, tag_data, tag_size);
4821   }
4822
4823   return ret;
4824
4825 error:
4826
4827   GST_ERROR ("Invalid DMS1 picture format local tag 0x%04x of size %u", tag,
4828       tag_size);
4829
4830   return FALSE;
4831 }
4832
4833 static void
4834 mxf_dms1_picture_format_init (MXFDMS1PictureFormat * self)
4835 {
4836 }
4837
4838 static void
4839 mxf_dms1_picture_format_class_init (MXFDMS1PictureFormatClass * klass)
4840 {
4841   GObjectClass *object_class = (GObjectClass *) klass;
4842   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
4843   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
4844
4845   object_class->finalize = mxf_dms1_picture_format_finalize;
4846   metadatabase_class->handle_tag = mxf_dms1_picture_format_handle_tag;
4847   dm_class->type = 0x1d0100;
4848 }
4849
4850 G_DEFINE_TYPE (MXFDMS1DeviceParameters, mxf_dms1_device_parameters,
4851     MXF_TYPE_DMS1_THESAURUS);
4852
4853 static void
4854 mxf_dms1_device_parameters_finalize (GObject * object)
4855 {
4856   MXFDMS1DeviceParameters *self = MXF_DMS1_DEVICE_PARAMETERS (object);
4857
4858   g_free (self->device_type);
4859   self->device_type = NULL;
4860
4861   g_free (self->manufacturer);
4862   self->manufacturer = NULL;
4863
4864   g_free (self->device_model);
4865   self->device_model = NULL;
4866
4867   g_free (self->device_serial_number);
4868   self->device_serial_number = NULL;
4869
4870   g_free (self->device_usage_description);
4871   self->device_usage_description = NULL;
4872
4873   g_free (self->name_value_sets_uids);
4874   self->name_value_sets_uids = NULL;
4875
4876   g_free (self->name_value_sets);
4877   self->name_value_sets = NULL;
4878
4879   G_OBJECT_CLASS (mxf_dms1_device_parameters_parent_class)->finalize (object);
4880 }
4881
4882 static gboolean
4883 mxf_dms1_device_parameters_resolve (MXFMetadataBase * m, GHashTable * metadata)
4884 {
4885   MXFDMS1DeviceParameters *self = MXF_DMS1_DEVICE_PARAMETERS (m);
4886   MXFMetadataBase *current = NULL;
4887   guint i;
4888
4889   if (self->name_value_sets)
4890     memset (self->name_value_sets, 0,
4891         sizeof (gpointer) * self->n_name_value_sets);
4892   else
4893     self->name_value_sets =
4894         g_new0 (MXFDMS1NameValue *, self->n_name_value_sets);
4895
4896   for (i = 0; i < self->n_name_value_sets; i++) {
4897     current = g_hash_table_lookup (metadata, &self->name_value_sets_uids[i]);
4898     if (current && MXF_IS_DMS1_NAME_VALUE (current)) {
4899       self->name_value_sets[i] = MXF_DMS1_NAME_VALUE (current);
4900     }
4901   }
4902
4903   return
4904       MXF_METADATA_BASE_CLASS (mxf_dms1_device_parameters_parent_class)->resolve
4905       (m, metadata);
4906 }
4907
4908 static gboolean
4909 mxf_dms1_device_parameters_handle_tag (MXFMetadataBase * metadata,
4910     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
4911     guint tag_size)
4912 {
4913   MXFDMS1DeviceParameters *self = MXF_DMS1_DEVICE_PARAMETERS (metadata);
4914   gboolean ret = TRUE;
4915 #ifndef GST_DISABLE_GST_DEBUG
4916   gchar str[48];
4917 #endif
4918   MXFUL *tag_ul = NULL;
4919   static const guint8 device_type_ul[] = {
4920     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x01,
4921     0x01, 0x20, 0x08, 0x01, 0x00, 0x00, 0x00
4922   };
4923   static const guint8 device_designation_ul[] = {
4924     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x01,
4925     0x01, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00
4926   };
4927   static const guint8 device_asset_number_ul[] = {
4928     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x01,
4929     0x01, 0x20, 0x0c, 0x00, 0x00, 0x00, 0x00
4930   };
4931   static const guint8 ieee_device_identifier_ul[] = {
4932     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, 0x01,
4933     0x01, 0x20, 0x05, 0x00, 0x00, 0x00, 0x00
4934   };
4935   static const guint8 manufacturer_ul[] = {
4936     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, 0x01,
4937     0x0a, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00
4938   };
4939   static const guint8 device_model_ul[] = {
4940     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x01,
4941     0x01, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00
4942   };
4943   static const guint8 device_serial_number_ul[] = {
4944     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x01,
4945     0x01, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00
4946   };
4947   static const guint8 device_usage_description_ul[] = {
4948     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03,
4949     0x03, 0x03, 0x10, 0x01, 0x01, 0x00, 0x00
4950   };
4951   static const guint8 name_value_sets_ul[] = {
4952     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
4953     0x01, 0x01, 0x04, 0x05, 0x40, 0x1f, 0x03
4954   };
4955
4956   if (!(tag_ul =
4957           (MXFUL *) g_hash_table_lookup (primer->mappings,
4958               GUINT_TO_POINTER (((guint) tag)))))
4959     return FALSE;
4960
4961   if (memcmp (tag_ul, &device_type_ul, 16) == 0) {
4962     self->device_type = mxf_utf16_to_utf8 (tag_data, tag_size);
4963     GST_DEBUG ("  device type = %s", GST_STR_NULL (self->device_type));
4964   } else if (memcmp (tag_ul, &device_designation_ul, 16) == 0) {
4965     if (tag_size > 32)
4966       goto error;
4967
4968     memcpy (self->device_designation, tag_data, tag_size);
4969     GST_DEBUG ("  device designation = %s", self->device_designation);
4970   } else if (memcmp (tag_ul, &device_asset_number_ul, 16) == 0) {
4971     if (tag_size > 32)
4972       goto error;
4973
4974     memcpy (self->device_asset_number, tag_data, tag_size);
4975     GST_DEBUG ("  device asset number = %s", self->device_asset_number);
4976   } else if (memcmp (tag_ul, &ieee_device_identifier_ul, 16) == 0) {
4977     if (tag_size != 6)
4978       goto error;
4979
4980     memcpy (self->ieee_device_identifier, tag_data, 6);
4981     GST_DEBUG
4982         ("  IEEE device identifier = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
4983         self->ieee_device_identifier[0], self->ieee_device_identifier[1],
4984         self->ieee_device_identifier[2], self->ieee_device_identifier[3],
4985         self->ieee_device_identifier[4], self->ieee_device_identifier[5]);
4986   } else if (memcmp (tag_ul, &manufacturer_ul, 16) == 0) {
4987     self->manufacturer = mxf_utf16_to_utf8 (tag_data, tag_size);
4988     GST_DEBUG ("  manufacturer = %s", GST_STR_NULL (self->manufacturer));
4989   } else if (memcmp (tag_ul, &device_model_ul, 16) == 0) {
4990     if (tag_size > 32)
4991       goto error;
4992
4993     memcpy (self->device_model, tag_data, tag_size);
4994     GST_DEBUG ("  device model = %s", self->device_model);
4995   } else if (memcmp (tag_ul, &device_serial_number_ul, 16) == 0) {
4996     if (tag_size > 32)
4997       goto error;
4998
4999     memcpy (self->device_serial_number, tag_data, tag_size);
5000     GST_DEBUG ("  device serial number = %s", self->device_serial_number);
5001   } else if (memcmp (tag_ul, &device_usage_description_ul, 16) == 0) {
5002     self->device_usage_description = mxf_utf16_to_utf8 (tag_data, tag_size);
5003     GST_DEBUG ("  device usage description = %s",
5004         GST_STR_NULL (self->device_usage_description));
5005   } else if (memcmp (tag_ul, &name_value_sets_ul, 16) == 0) {
5006     if (!mxf_uuid_array_parse (&self->name_value_sets_uids,
5007             &self->n_name_value_sets, tag_data, tag_size))
5008       goto error;
5009     GST_DEBUG ("  number of name-value sets = %u", self->n_name_value_sets);
5010 #ifndef GST_DISABLE_GST_DEBUG
5011     {
5012       guint i;
5013       for (i = 0; i < self->n_name_value_sets; i++) {
5014         GST_DEBUG ("    name-value sets %u = %s", i,
5015             mxf_uuid_to_string (&self->name_value_sets_uids[i], str));
5016       }
5017     }
5018 #endif
5019   } else {
5020     ret =
5021         MXF_METADATA_BASE_CLASS
5022         (mxf_dms1_device_parameters_parent_class)->handle_tag (metadata, primer,
5023         tag, tag_data, tag_size);
5024   }
5025
5026   return ret;
5027
5028 error:
5029
5030   GST_ERROR ("Invalid DMS1 device parameters local tag 0x%04x of size %u", tag,
5031       tag_size);
5032
5033   return FALSE;
5034 }
5035
5036 static void
5037 mxf_dms1_device_parameters_init (MXFDMS1DeviceParameters * self)
5038 {
5039 }
5040
5041 static void
5042 mxf_dms1_device_parameters_class_init (MXFDMS1DeviceParametersClass * klass)
5043 {
5044   GObjectClass *object_class = (GObjectClass *) klass;
5045   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
5046   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
5047
5048   object_class->finalize = mxf_dms1_device_parameters_finalize;
5049   metadatabase_class->handle_tag = mxf_dms1_device_parameters_handle_tag;
5050   metadatabase_class->resolve = mxf_dms1_device_parameters_resolve;
5051   dm_class->type = 0x1e0100;
5052 }
5053
5054 G_DEFINE_TYPE (MXFDMS1NameValue, mxf_dms1_name_value, MXF_TYPE_DMS1);
5055
5056 static void
5057 mxf_dms1_name_value_finalize (GObject * object)
5058 {
5059   MXFDMS1NameValue *self = MXF_DMS1_NAME_VALUE (object);
5060
5061   g_free (self->item_name);
5062   self->item_name = NULL;
5063
5064   g_free (self->item_value);
5065   self->item_value = NULL;
5066
5067   G_OBJECT_CLASS (mxf_dms1_name_value_parent_class)->finalize (object);
5068 }
5069
5070 static gboolean
5071 mxf_dms1_name_value_handle_tag (MXFMetadataBase * metadata,
5072     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
5073     guint tag_size)
5074 {
5075   MXFDMS1NameValue *self = MXF_DMS1_NAME_VALUE (metadata);
5076   gboolean ret = TRUE;
5077 #ifndef GST_DISABLE_GST_DEBUG
5078   gchar str[48];
5079 #endif
5080   MXFUL *tag_ul = NULL;
5081   static const guint8 item_name_ul[] = {
5082     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03,
5083     0x01, 0x02, 0x0a, 0x01, 0x01, 0x00, 0x00
5084   };
5085   static const guint8 item_value_ul[] = {
5086     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x03,
5087     0x01, 0x02, 0x0a, 0x02, 0x01, 0x00, 0x00
5088   };
5089   static const guint8 smpte_universal_label_locator_ul[] = {
5090     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x01,
5091     0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00
5092   };
5093
5094   if (!(tag_ul =
5095           (MXFUL *) g_hash_table_lookup (primer->mappings,
5096               GUINT_TO_POINTER (((guint) tag)))))
5097     return FALSE;
5098
5099   if (memcmp (tag_ul, &item_name_ul, 16) == 0) {
5100     self->item_name = mxf_utf16_to_utf8 (tag_data, tag_size);
5101     GST_DEBUG ("  item name = %s", GST_STR_NULL (self->item_name));
5102   } else if (memcmp (tag_ul, &item_value_ul, 16) == 0) {
5103     self->item_value = mxf_utf16_to_utf8 (tag_data, tag_size);
5104     GST_DEBUG ("  item value = %s", GST_STR_NULL (self->item_value));
5105   } else if (memcmp (tag_ul, &smpte_universal_label_locator_ul, 16) == 0) {
5106     if (tag_size != 16)
5107       goto error;
5108
5109     memcpy (&self->smpte_universal_label_locator, tag_data, 16);
5110     GST_DEBUG ("  SMPTE universal label locator = %s",
5111         mxf_uuid_to_string (&self->smpte_universal_label_locator, str));
5112   } else {
5113     ret =
5114         MXF_METADATA_BASE_CLASS (mxf_dms1_name_value_parent_class)->handle_tag
5115         (metadata, primer, tag, tag_data, tag_size);
5116   }
5117
5118   return ret;
5119
5120 error:
5121
5122   GST_ERROR ("Invalid DMS1 name-value local tag 0x%04x of size %u", tag,
5123       tag_size);
5124
5125   return FALSE;
5126 }
5127
5128 static void
5129 mxf_dms1_name_value_init (MXFDMS1NameValue * self)
5130 {
5131 }
5132
5133 static void
5134 mxf_dms1_name_value_class_init (MXFDMS1NameValueClass * klass)
5135 {
5136   GObjectClass *object_class = (GObjectClass *) klass;
5137   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
5138   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
5139
5140   object_class->finalize = mxf_dms1_name_value_finalize;
5141   metadatabase_class->handle_tag = mxf_dms1_name_value_handle_tag;
5142   dm_class->type = 0x1f0100;
5143 }
5144
5145 G_DEFINE_TYPE (MXFDMS1Processing, mxf_dms1_processing, MXF_TYPE_DMS1);
5146
5147 static void
5148 mxf_dms1_processing_finalize (GObject * object)
5149 {
5150   MXFDMS1Processing *self = MXF_DMS1_PROCESSING (object);
5151
5152   g_free (self->descriptive_comment);
5153   self->descriptive_comment = NULL;
5154
5155   g_free (self->graphic_usage_type);
5156   self->graphic_usage_type = NULL;
5157
5158   G_OBJECT_CLASS (mxf_dms1_processing_parent_class)->finalize (object);
5159 }
5160
5161 static gboolean
5162 mxf_dms1_processing_handle_tag (MXFMetadataBase * metadata,
5163     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
5164     guint tag_size)
5165 {
5166   MXFDMS1Processing *self = MXF_DMS1_PROCESSING (metadata);
5167   gboolean ret = TRUE;
5168   MXFUL *tag_ul = NULL;
5169   static const guint8 quality_flag_ul[] = {
5170     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x05,
5171     0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00
5172   };
5173   static const guint8 descriptive_comment_ul[] = {
5174     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x03,
5175     0x02, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00
5176   };
5177   static const guint8 logo_flag_ul[] = {
5178     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03, 0x05,
5179     0x01, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00
5180   };
5181   static const guint8 graphic_usage_type_ul[] = {
5182     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x05,
5183     0x01, 0x01, 0x07, 0x01, 0x00, 0x00, 0x00
5184   };
5185   static const guint8 process_steps_ul[] = {
5186     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x05,
5187     0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00
5188   };
5189   static const guint8 generation_copy_number_ul[] = {
5190     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x05,
5191     0x01, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00
5192   };
5193   static const guint8 generation_clone_number_ul[] = {
5194     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x05,
5195     0x01, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00
5196   };
5197
5198   if (!(tag_ul =
5199           (MXFUL *) g_hash_table_lookup (primer->mappings,
5200               GUINT_TO_POINTER (((guint) tag)))))
5201     return FALSE;
5202
5203   if (memcmp (tag_ul, &quality_flag_ul, 16) == 0) {
5204     if (tag_size != 1)
5205       goto error;
5206
5207     self->quality_flag = GST_READ_UINT8 (tag_data);
5208     GST_DEBUG ("  quality flag = %u", self->quality_flag);
5209   } else if (memcmp (tag_ul, &descriptive_comment_ul, 16) == 0) {
5210     self->descriptive_comment = mxf_utf16_to_utf8 (tag_data, tag_size);
5211     GST_DEBUG ("  descriptive comment = %s",
5212         GST_STR_NULL (self->descriptive_comment));
5213   } else if (memcmp (tag_ul, &logo_flag_ul, 16) == 0) {
5214     if (tag_size != 1)
5215       goto error;
5216
5217     self->logo_flag = GST_READ_UINT8 (tag_data);
5218     GST_DEBUG ("  logo flag = %u", self->logo_flag);
5219   } else if (memcmp (tag_ul, &graphic_usage_type_ul, 16) == 0) {
5220     self->graphic_usage_type = mxf_utf16_to_utf8 (tag_data, tag_size);
5221     GST_DEBUG ("  graphic usage type = %s",
5222         GST_STR_NULL (self->graphic_usage_type));
5223   } else if (memcmp (tag_ul, &process_steps_ul, 16) == 0) {
5224     if (tag_size != 2)
5225       goto error;
5226
5227     self->process_steps = GST_READ_UINT16_BE (tag_data);
5228     GST_DEBUG ("  process steps = %u", self->process_steps);
5229   } else if (memcmp (tag_ul, &generation_copy_number_ul, 16) == 0) {
5230     if (tag_size != 2)
5231       goto error;
5232
5233     self->generation_copy_number = GST_READ_UINT16_BE (tag_data);
5234     GST_DEBUG ("  generation copy number = %u", self->generation_copy_number);
5235   } else if (memcmp (tag_ul, &generation_clone_number_ul, 16) == 0) {
5236     if (tag_size != 2)
5237       goto error;
5238
5239     self->generation_clone_number = GST_READ_UINT16_BE (tag_data);
5240     GST_DEBUG ("  generation clone number = %u", self->generation_clone_number);
5241   } else {
5242     ret =
5243         MXF_METADATA_BASE_CLASS (mxf_dms1_processing_parent_class)->handle_tag
5244         (metadata, primer, tag, tag_data, tag_size);
5245   }
5246
5247   return ret;
5248
5249 error:
5250
5251   GST_ERROR ("Invalid DMS1 processing local tag 0x%04x of size %u", tag,
5252       tag_size);
5253
5254   return FALSE;
5255 }
5256
5257 static void
5258 mxf_dms1_processing_init (MXFDMS1Processing * self)
5259 {
5260 }
5261
5262 static void
5263 mxf_dms1_processing_class_init (MXFDMS1ProcessingClass * klass)
5264 {
5265   GObjectClass *object_class = (GObjectClass *) klass;
5266   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
5267   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
5268
5269   object_class->finalize = mxf_dms1_processing_finalize;
5270   metadatabase_class->handle_tag = mxf_dms1_processing_handle_tag;
5271   dm_class->type = 0x200100;
5272 }
5273
5274 G_DEFINE_TYPE (MXFDMS1Project, mxf_dms1_project, MXF_TYPE_DMS1);
5275
5276 static void
5277 mxf_dms1_project_finalize (GObject * object)
5278 {
5279   MXFDMS1Project *self = MXF_DMS1_PROJECT (object);
5280
5281   g_free (self->project_name_or_title);
5282   self->project_name_or_title = NULL;
5283
5284   G_OBJECT_CLASS (mxf_dms1_project_parent_class)->finalize (object);
5285 }
5286
5287 static gboolean
5288 mxf_dms1_project_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer,
5289     guint16 tag, const guint8 * tag_data, guint tag_size)
5290 {
5291   MXFDMS1Project *self = MXF_DMS1_PROJECT (metadata);
5292   gboolean ret = TRUE;
5293   MXFUL *tag_ul = NULL;
5294   static const guint8 project_number_ul[] = {
5295     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, 0x01,
5296     0x03, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00
5297   };
5298   static const guint8 project_name_or_title_ul[] = {
5299     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x01,
5300     0x03, 0x01, 0x08, 0x01, 0x00, 0x00, 0x00
5301   };
5302
5303   if (!(tag_ul =
5304           (MXFUL *) g_hash_table_lookup (primer->mappings,
5305               GUINT_TO_POINTER (((guint) tag)))))
5306     return FALSE;
5307
5308   if (memcmp (tag_ul, &project_number_ul, 16) == 0) {
5309     if (tag_size > 32)
5310       goto error;
5311
5312     memcpy (self->project_number, tag_data, tag_size);
5313
5314     GST_DEBUG ("  project number = %s", self->project_number);
5315   } else if (memcmp (tag_ul, &project_name_or_title_ul, 16) == 0) {
5316     self->project_name_or_title = mxf_utf16_to_utf8 (tag_data, tag_size);
5317     GST_DEBUG ("  project name or title = %s",
5318         GST_STR_NULL (self->project_name_or_title));
5319   } else {
5320     ret =
5321         MXF_METADATA_BASE_CLASS (mxf_dms1_project_parent_class)->handle_tag
5322         (metadata, primer, tag, tag_data, tag_size);
5323   }
5324
5325   return ret;
5326
5327 error:
5328
5329   GST_ERROR ("Invalid DMS1 project local tag 0x%04x of size %u", tag, tag_size);
5330
5331   return FALSE;
5332 }
5333
5334 static void
5335 mxf_dms1_project_init (MXFDMS1Project * self)
5336 {
5337 }
5338
5339 static void
5340 mxf_dms1_project_class_init (MXFDMS1ProjectClass * klass)
5341 {
5342   GObjectClass *object_class = (GObjectClass *) klass;
5343   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
5344   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
5345
5346   object_class->finalize = mxf_dms1_project_finalize;
5347   metadatabase_class->handle_tag = mxf_dms1_project_handle_tag;
5348   dm_class->type = 0x200200;
5349 }
5350
5351 G_DEFINE_TYPE (MXFDMS1ContactsList, mxf_dms1_contacts_list, MXF_TYPE_DMS1);
5352
5353 static void
5354 mxf_dms1_contacts_list_finalize (GObject * object)
5355 {
5356   MXFDMS1ContactsList *self = MXF_DMS1_CONTACTS_LIST (object);
5357
5358   g_free (self->person_sets_uids);
5359   self->person_sets_uids = NULL;
5360
5361   g_free (self->person_sets);
5362   self->person_sets = NULL;
5363
5364   g_free (self->organisation_sets_uids);
5365   self->organisation_sets_uids = NULL;
5366
5367   g_free (self->organisation_sets);
5368   self->organisation_sets = NULL;
5369
5370   g_free (self->location_sets_uids);
5371   self->location_sets_uids = NULL;
5372
5373   g_free (self->location_sets);
5374   self->location_sets = NULL;
5375
5376   G_OBJECT_CLASS (mxf_dms1_contacts_list_parent_class)->finalize (object);
5377 }
5378
5379 static gboolean
5380 mxf_dms1_contacts_list_resolve (MXFMetadataBase * m, GHashTable * metadata)
5381 {
5382   MXFDMS1ContactsList *self = MXF_DMS1_CONTACTS_LIST (m);
5383   MXFMetadataBase *current = NULL;
5384   guint i;
5385
5386   if (self->person_sets)
5387     memset (self->person_sets, 0, sizeof (gpointer) * self->n_person_sets);
5388   else
5389     self->person_sets = g_new0 (MXFDMS1Person *, self->n_person_sets);
5390
5391   if (self->organisation_sets)
5392     memset (self->organisation_sets, 0,
5393         sizeof (gpointer) * self->n_organisation_sets);
5394   else
5395     self->organisation_sets =
5396         g_new0 (MXFDMS1Organisation *, self->n_organisation_sets);
5397
5398   if (self->location_sets)
5399     memset (self->location_sets, 0, sizeof (gpointer) * self->n_location_sets);
5400   else
5401     self->location_sets = g_new0 (MXFDMS1Location *, self->n_location_sets);
5402
5403   for (i = 0; i < self->n_person_sets; i++) {
5404     current = g_hash_table_lookup (metadata, &self->person_sets_uids[i]);
5405     if (current && MXF_IS_DMS1_PERSON (current)) {
5406       self->person_sets[i] = MXF_DMS1_PERSON (current);
5407     }
5408   }
5409
5410   for (i = 0; i < self->n_organisation_sets; i++) {
5411     current = g_hash_table_lookup (metadata, &self->organisation_sets_uids[i]);
5412     if (current && MXF_IS_DMS1_ORGANISATION (current)) {
5413       self->organisation_sets[i] = MXF_DMS1_ORGANISATION (current);
5414     }
5415   }
5416
5417   for (i = 0; i < self->n_location_sets; i++) {
5418     current = g_hash_table_lookup (metadata, &self->location_sets_uids[i]);
5419     if (current && MXF_IS_DMS1_LOCATION (current)) {
5420       self->location_sets[i] = MXF_DMS1_LOCATION (current);
5421     }
5422   }
5423
5424   return
5425       MXF_METADATA_BASE_CLASS (mxf_dms1_contacts_list_parent_class)->resolve (m,
5426       metadata);
5427 }
5428
5429 static gboolean
5430 mxf_dms1_contacts_list_handle_tag (MXFMetadataBase * metadata,
5431     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
5432     guint tag_size)
5433 {
5434   MXFDMS1ContactsList *self = MXF_DMS1_CONTACTS_LIST (metadata);
5435   gboolean ret = TRUE;
5436 #ifndef GST_DISABLE_GST_DEBUG
5437   gchar str[48];
5438 #endif
5439   MXFUL *tag_ul = NULL;
5440   static const guint8 person_sets_ul[] = {
5441     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
5442     0x01, 0x01, 0x04, 0x03, 0x40, 0x14, 0x00
5443   };
5444   static const guint8 organisation_sets_ul[] = {
5445     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
5446     0x01, 0x01, 0x04, 0x03, 0x40, 0x15, 0x00
5447   };
5448   static const guint8 location_sets_ul[] = {
5449     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, 0x06,
5450     0x01, 0x01, 0x04, 0x03, 0x40, 0x16, 0x00
5451   };
5452
5453   if (!(tag_ul =
5454           (MXFUL *) g_hash_table_lookup (primer->mappings,
5455               GUINT_TO_POINTER (((guint) tag)))))
5456     return FALSE;
5457
5458   if (memcmp (tag_ul, &person_sets_ul, 16) == 0) {
5459     if (!mxf_uuid_array_parse (&self->person_sets_uids, &self->n_person_sets,
5460             tag_data, tag_size))
5461       goto error;
5462     GST_DEBUG ("  number of person sets = %u", self->n_person_sets);
5463 #ifndef GST_DISABLE_GST_DEBUG
5464     {
5465       guint i;
5466       for (i = 0; i < self->n_person_sets; i++) {
5467         GST_DEBUG ("    person sets %u = %s", i,
5468             mxf_uuid_to_string (&self->person_sets_uids[i], str));
5469       }
5470     }
5471 #endif
5472   } else if (memcmp (tag_ul, &organisation_sets_ul, 16) == 0) {
5473     if (!mxf_uuid_array_parse (&self->organisation_sets_uids,
5474             &self->n_organisation_sets, tag_data, tag_size))
5475       goto error;
5476     GST_DEBUG ("  number of organisation sets = %u", self->n_organisation_sets);
5477 #ifndef GST_DISABLE_GST_DEBUG
5478     {
5479       guint i;
5480       for (i = 0; i < self->n_organisation_sets; i++) {
5481         GST_DEBUG ("    organisation sets %u = %s", i,
5482             mxf_uuid_to_string (&self->organisation_sets_uids[i], str));
5483       }
5484     }
5485 #endif
5486   } else if (memcmp (tag_ul, &location_sets_ul, 16) == 0) {
5487     if (!mxf_uuid_array_parse (&self->location_sets_uids,
5488             &self->n_location_sets, tag_data, tag_size))
5489       goto error;
5490     GST_DEBUG ("  number of location sets = %u", self->n_location_sets);
5491 #ifndef GST_DISABLE_GST_DEBUG
5492     {
5493       guint i;
5494       for (i = 0; i < self->n_location_sets; i++) {
5495         GST_DEBUG ("    location sets %u = %s", i,
5496             mxf_uuid_to_string (&self->location_sets_uids[i], str));
5497       }
5498     }
5499 #endif
5500   } else {
5501     ret =
5502         MXF_METADATA_BASE_CLASS
5503         (mxf_dms1_contacts_list_parent_class)->handle_tag (metadata, primer,
5504         tag, tag_data, tag_size);
5505   }
5506
5507   return ret;
5508
5509 error:
5510
5511   GST_ERROR ("Invalid DMS1 contacts list local tag 0x%04x of size %u", tag,
5512       tag_size);
5513
5514   return FALSE;
5515 }
5516
5517 static void
5518 mxf_dms1_contacts_list_init (MXFDMS1ContactsList * self)
5519 {
5520 }
5521
5522 static void
5523 mxf_dms1_contacts_list_class_init (MXFDMS1ContactsListClass * klass)
5524 {
5525   GObjectClass *object_class = (GObjectClass *) klass;
5526   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
5527   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
5528
5529   object_class->finalize = mxf_dms1_contacts_list_finalize;
5530   metadatabase_class->handle_tag = mxf_dms1_contacts_list_handle_tag;
5531   metadatabase_class->resolve = mxf_dms1_contacts_list_resolve;
5532   dm_class->type = 0x190100;
5533 }
5534
5535 G_DEFINE_TYPE (MXFDMS1CueWords, mxf_dms1_cue_words,
5536     MXF_TYPE_DMS1_TEXT_LANGUAGE);
5537
5538 static void
5539 mxf_dms1_cue_words_finalize (GObject * object)
5540 {
5541   MXFDMS1CueWords *self = MXF_DMS1_CUE_WORDS (object);
5542
5543   g_free (self->in_cue_words);
5544   self->in_cue_words = NULL;
5545
5546   g_free (self->out_cue_words);
5547   self->out_cue_words = NULL;
5548
5549   G_OBJECT_CLASS (mxf_dms1_cue_words_parent_class)->finalize (object);
5550 }
5551
5552 static gboolean
5553 mxf_dms1_cue_words_handle_tag (MXFMetadataBase * metadata,
5554     MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
5555     guint tag_size)
5556 {
5557   MXFDMS1CueWords *self = MXF_DMS1_CUE_WORDS (metadata);
5558   gboolean ret = TRUE;
5559   MXFUL *tag_ul = NULL;
5560   static const guint8 in_cue_words_ul[] = {
5561     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x03,
5562     0x02, 0x01, 0x02, 0x0d, 0x01, 0x00, 0x00
5563   };
5564   static const guint8 out_cue_words_ul[] = {
5565     0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, 0x03,
5566     0x02, 0x01, 0x02, 0x0e, 0x01, 0x00, 0x00
5567   };
5568
5569   if (!(tag_ul =
5570           (MXFUL *) g_hash_table_lookup (primer->mappings,
5571               GUINT_TO_POINTER (((guint) tag)))))
5572     return FALSE;
5573
5574   if (memcmp (tag_ul, &in_cue_words_ul, 16) == 0) {
5575     self->in_cue_words = mxf_utf16_to_utf8 (tag_data, tag_size);
5576     GST_DEBUG ("  in cue words = %s", GST_STR_NULL (self->in_cue_words));
5577   } else if (memcmp (tag_ul, &out_cue_words_ul, 16) == 0) {
5578     self->out_cue_words = mxf_utf16_to_utf8 (tag_data, tag_size);
5579     GST_DEBUG ("  out cue words = %s", GST_STR_NULL (self->out_cue_words));
5580   } else {
5581     ret =
5582         MXF_METADATA_BASE_CLASS (mxf_dms1_cue_words_parent_class)->handle_tag
5583         (metadata, primer, tag, tag_data, tag_size);
5584   }
5585
5586   return ret;
5587 }
5588
5589 static void
5590 mxf_dms1_cue_words_init (MXFDMS1CueWords * self)
5591 {
5592 }
5593
5594 static void
5595 mxf_dms1_cue_words_class_init (MXFDMS1CueWordsClass * klass)
5596 {
5597   GObjectClass *object_class = (GObjectClass *) klass;
5598   MXFMetadataBaseClass *metadatabase_class = (MXFMetadataBaseClass *) klass;
5599   MXFDescriptiveMetadataClass *dm_class = (MXFDescriptiveMetadataClass *) klass;
5600
5601   object_class->finalize = mxf_dms1_cue_words_finalize;
5602   metadatabase_class->handle_tag = mxf_dms1_cue_words_handle_tag;
5603   dm_class->type = 0x170800;
5604 }
5605
5606 #define _add_dm_type(type) G_STMT_START { \
5607   GType tmp = type; \
5608   \
5609   g_array_append_val (dms1_sets, tmp); \
5610 } G_STMT_END
5611
5612 void
5613 mxf_dms1_initialize (void)
5614 {
5615   GArray *dms1_sets = g_array_new (TRUE, TRUE, sizeof (GType));
5616
5617   _add_dm_type (MXF_TYPE_DMS1_PRODUCTION_FRAMEWORK);
5618   _add_dm_type (MXF_TYPE_DMS1_CLIP_FRAMEWORK);
5619   _add_dm_type (MXF_TYPE_DMS1_SCENE_FRAMEWORK);
5620   _add_dm_type (MXF_TYPE_DMS1_TITLES);
5621   _add_dm_type (MXF_TYPE_DMS1_IDENTIFICATION);
5622   _add_dm_type (MXF_TYPE_DMS1_GROUP_RELATIONSHIP);
5623   _add_dm_type (MXF_TYPE_DMS1_BRANDING);
5624   _add_dm_type (MXF_TYPE_DMS1_EVENT);
5625   _add_dm_type (MXF_TYPE_DMS1_PUBLICATION);
5626   _add_dm_type (MXF_TYPE_DMS1_AWARD);
5627   _add_dm_type (MXF_TYPE_DMS1_CAPTIONS_DESCRIPTION);
5628   _add_dm_type (MXF_TYPE_DMS1_ANNOTATION);
5629   _add_dm_type (MXF_TYPE_DMS1_SETTING_PERIOD);
5630   _add_dm_type (MXF_TYPE_DMS1_SCRIPTING);
5631   _add_dm_type (MXF_TYPE_DMS1_CLASSIFICATION);
5632   _add_dm_type (MXF_TYPE_DMS1_SHOT);
5633   _add_dm_type (MXF_TYPE_DMS1_KEY_POINT);
5634   _add_dm_type (MXF_TYPE_DMS1_PARTICIPANT);
5635   _add_dm_type (MXF_TYPE_DMS1_PERSON);
5636   _add_dm_type (MXF_TYPE_DMS1_ORGANISATION);
5637   _add_dm_type (MXF_TYPE_DMS1_LOCATION);
5638   _add_dm_type (MXF_TYPE_DMS1_ADDRESS);
5639   _add_dm_type (MXF_TYPE_DMS1_COMMUNICATIONS);
5640   _add_dm_type (MXF_TYPE_DMS1_CONTRACT);
5641   _add_dm_type (MXF_TYPE_DMS1_RIGHTS);
5642   _add_dm_type (MXF_TYPE_DMS1_PICTURE_FORMAT);
5643   _add_dm_type (MXF_TYPE_DMS1_DEVICE_PARAMETERS);
5644   _add_dm_type (MXF_TYPE_DMS1_NAME_VALUE);
5645   _add_dm_type (MXF_TYPE_DMS1_PROCESSING);
5646   _add_dm_type (MXF_TYPE_DMS1_PROJECT);
5647   _add_dm_type (MXF_TYPE_DMS1_CONTACTS_LIST);
5648   _add_dm_type (MXF_TYPE_DMS1_CUE_WORDS);
5649
5650   mxf_descriptive_metadata_register (0x01, (GType *) g_array_free (dms1_sets,
5651           FALSE));
5652 }
5653
5654 #undef _add_dm_type
5655
5656 #undef ADD_SET