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 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <gst/gst.h>
25 #include <string.h>
26
27 #include "mxftypes.h"
28 #include "mxfmetadata.h"
29 #include "mxfquark.h"
30
31 GST_DEBUG_CATEGORY_EXTERN (mxf_debug);
32 #define GST_CAT_DEFAULT mxf_debug
33
34 G_DEFINE_ABSTRACT_TYPE (MXFMetadataBase, mxf_metadata_base, G_TYPE_OBJECT);
35
36 static void
mxf_metadata_base_finalize(GObject * object)37 mxf_metadata_base_finalize (GObject * object)
38 {
39 MXFMetadataBase *self = MXF_METADATA_BASE (object);
40
41 if (self->other_tags) {
42 g_hash_table_destroy (self->other_tags);
43 self->other_tags = NULL;
44 }
45
46 G_OBJECT_CLASS (mxf_metadata_base_parent_class)->finalize (object);
47 }
48
49 static gboolean
mxf_metadata_base_handle_tag(MXFMetadataBase * self,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)50 mxf_metadata_base_handle_tag (MXFMetadataBase * self, MXFPrimerPack * primer,
51 guint16 tag, const guint8 * tag_data, guint tag_size)
52 {
53 return (mxf_local_tag_add_to_hash_table (primer, tag, tag_data, tag_size,
54 &self->other_tags));
55 }
56
57 static gboolean
mxf_metadata_base_resolve_default(MXFMetadataBase * self,GHashTable * metadata)58 mxf_metadata_base_resolve_default (MXFMetadataBase * self,
59 GHashTable * metadata)
60 {
61 return TRUE;
62 }
63
64 static GstStructure *
mxf_metadata_base_to_structure_default(MXFMetadataBase * self)65 mxf_metadata_base_to_structure_default (MXFMetadataBase * self)
66 {
67 MXFMetadataBaseClass *klass = MXF_METADATA_BASE_GET_CLASS (self);
68 GstStructure *ret;
69 gchar str[48];
70
71 g_return_val_if_fail (klass->name_quark != 0, NULL);
72
73 ret = gst_structure_new_id_empty (klass->name_quark);
74
75 if (!mxf_uuid_is_zero (&self->instance_uid)) {
76 mxf_uuid_to_string (&self->instance_uid, str);
77 gst_structure_id_set (ret, MXF_QUARK (INSTANCE_UID), G_TYPE_STRING, str,
78 NULL);
79 }
80
81 if (!mxf_uuid_is_zero (&self->generation_uid)) {
82 mxf_uuid_to_string (&self->generation_uid, str);
83 gst_structure_id_set (ret, MXF_QUARK (GENERATION_UID), G_TYPE_STRING, str,
84 NULL);
85 }
86
87 if (self->other_tags) {
88 MXFLocalTag *tag;
89 GValue va = { 0, };
90 GValue v = { 0, };
91 GstStructure *s;
92 GstBuffer *buf;
93 GstMapInfo map;
94 GHashTableIter iter;
95
96 g_hash_table_iter_init (&iter, self->other_tags);
97 g_value_init (&va, GST_TYPE_ARRAY);
98
99 while (g_hash_table_iter_next (&iter, NULL, (gpointer) & tag)) {
100 g_value_init (&v, GST_TYPE_STRUCTURE);
101 s = gst_structure_new_id_empty (MXF_QUARK (TAG));
102
103 mxf_ul_to_string (&tag->ul, str);
104
105 buf = gst_buffer_new_and_alloc (tag->size);
106 gst_buffer_map (buf, &map, GST_MAP_WRITE);
107 memcpy (map.data, tag->data, tag->size);
108 gst_buffer_unmap (buf, &map);
109
110 gst_structure_id_set (s, MXF_QUARK (NAME), G_TYPE_STRING, str,
111 MXF_QUARK (DATA), GST_TYPE_BUFFER, buf, NULL);
112
113 gst_value_set_structure (&v, s);
114 gst_structure_free (s);
115 gst_buffer_unref (buf);
116 gst_value_array_append_value (&va, &v);
117 g_value_unset (&v);
118 }
119
120 gst_structure_id_set_value (ret, MXF_QUARK (OTHER_TAGS), &va);
121 g_value_unset (&va);
122 }
123
124 return ret;
125 }
126
127 static void
mxf_metadata_base_init(MXFMetadataBase * self)128 mxf_metadata_base_init (MXFMetadataBase * self)
129 {
130
131 }
132
133 static void
mxf_metadata_base_class_init(MXFMetadataBaseClass * klass)134 mxf_metadata_base_class_init (MXFMetadataBaseClass * klass)
135 {
136 GObjectClass *object_class = (GObjectClass *) klass;
137
138 object_class->finalize = mxf_metadata_base_finalize;
139 klass->handle_tag = mxf_metadata_base_handle_tag;
140 klass->resolve = mxf_metadata_base_resolve_default;
141 klass->to_structure = mxf_metadata_base_to_structure_default;
142 }
143
144 gboolean
mxf_metadata_base_parse(MXFMetadataBase * self,MXFPrimerPack * primer,const guint8 * data,guint size)145 mxf_metadata_base_parse (MXFMetadataBase * self, MXFPrimerPack * primer,
146 const guint8 * data, guint size)
147 {
148 guint16 tag, tag_size;
149 const guint8 *tag_data;
150
151 g_return_val_if_fail (MXF_IS_METADATA_BASE (self), FALSE);
152 g_return_val_if_fail (primer != NULL, FALSE);
153
154 if (size == 0)
155 return FALSE;
156
157 g_return_val_if_fail (data != NULL, FALSE);
158
159 while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
160 if (tag_size == 0 || tag == 0x0000)
161 goto next;
162
163 if (!MXF_METADATA_BASE_GET_CLASS (self)->handle_tag (self, primer, tag,
164 tag_data, tag_size))
165 return FALSE;
166 next:
167 data += 4 + tag_size;
168 size -= 4 + tag_size;
169 }
170
171 return TRUE;
172 }
173
174 gboolean
mxf_metadata_base_resolve(MXFMetadataBase * self,GHashTable * metadata)175 mxf_metadata_base_resolve (MXFMetadataBase * self, GHashTable * metadata)
176 {
177 MXFMetadataBaseClass *klass;
178 gboolean ret = TRUE;
179
180 g_return_val_if_fail (MXF_IS_METADATA_BASE (self), FALSE);
181 g_return_val_if_fail (metadata != NULL, FALSE);
182
183 if (self->resolved == MXF_METADATA_BASE_RESOLVE_STATE_SUCCESS)
184 return TRUE;
185 else if (self->resolved != MXF_METADATA_BASE_RESOLVE_STATE_NONE)
186 return FALSE;
187
188 self->resolved = MXF_METADATA_BASE_RESOLVE_STATE_RUNNING;
189
190 klass = MXF_METADATA_BASE_GET_CLASS (self);
191
192 if (klass->resolve)
193 ret = klass->resolve (self, metadata);
194
195 self->resolved =
196 (ret) ? MXF_METADATA_BASE_RESOLVE_STATE_SUCCESS :
197 MXF_METADATA_BASE_RESOLVE_STATE_FAILURE;
198
199 return ret;
200 }
201
202 GstStructure *
mxf_metadata_base_to_structure(MXFMetadataBase * self)203 mxf_metadata_base_to_structure (MXFMetadataBase * self)
204 {
205 MXFMetadataBaseClass *klass;
206
207 g_return_val_if_fail (MXF_IS_METADATA_BASE (self), NULL);
208
209 g_return_val_if_fail (self->resolved ==
210 MXF_METADATA_BASE_RESOLVE_STATE_SUCCESS, NULL);
211
212 klass = MXF_METADATA_BASE_GET_CLASS (self);
213
214 if (klass->to_structure)
215 return klass->to_structure (self);
216
217 return NULL;
218 }
219
220 GstBuffer *
mxf_metadata_base_to_buffer(MXFMetadataBase * self,MXFPrimerPack * primer)221 mxf_metadata_base_to_buffer (MXFMetadataBase * self, MXFPrimerPack * primer)
222 {
223 MXFMetadataBaseClass *klass;
224 GstBuffer *ret;
225 GstMapInfo map;
226 GList *tags, *l;
227 guint size = 0, slen;
228 guint8 ber[9];
229 MXFLocalTag *t, *last;
230 guint8 *data;
231
232 g_return_val_if_fail (MXF_IS_METADATA_BASE (self), NULL);
233 g_return_val_if_fail (primer != NULL, NULL);
234
235 klass = MXF_METADATA_BASE_GET_CLASS (self);
236 g_return_val_if_fail (klass->write_tags, NULL);
237
238 tags = klass->write_tags (self, primer);
239 g_return_val_if_fail (tags != NULL, NULL);
240
241 /* Add unknown tags */
242 if (self->other_tags) {
243 MXFLocalTag *tmp;
244 GHashTableIter iter;
245
246 g_hash_table_iter_init (&iter, self->other_tags);
247
248 while (g_hash_table_iter_next (&iter, NULL, (gpointer) & t)) {
249 tmp = g_slice_dup (MXFLocalTag, t);
250 if (t->g_slice) {
251 tmp->data = g_slice_alloc (t->size);
252 mxf_primer_pack_add_mapping (primer, 0x0000, &t->ul);
253 memcpy (tmp->data, t->data, t->size);
254 } else {
255 tmp->data = g_memdup (t->data, t->size);
256 }
257 tags = g_list_prepend (tags, tmp);
258 }
259 }
260
261 l = g_list_last (tags);
262 last = l->data;
263 tags = g_list_delete_link (tags, l);
264 /* Last element contains the metadata UL */
265 g_return_val_if_fail (last->size == 0, NULL);
266
267 for (l = tags; l; l = l->next) {
268 t = l->data;
269 g_assert (G_MAXUINT - t->size >= size);
270 size += 4 + t->size;
271 }
272
273 slen = mxf_ber_encode_size (size, ber);
274 size += 16 + slen;
275
276 ret = gst_buffer_new_and_alloc (size);
277 gst_buffer_map (ret, &map, GST_MAP_WRITE);
278
279 memcpy (map.data, &last->ul, 16);
280 mxf_local_tag_free (last);
281 last = NULL;
282 memcpy (map.data + 16, ber, slen);
283
284 data = map.data + 16 + slen;
285 size -= 16 + slen;
286
287 for (l = tags; l; l = l->next) {
288 guint16 local_tag;
289
290 g_assert (size >= 4);
291 t = l->data;
292
293 local_tag =
294 GPOINTER_TO_UINT (g_hash_table_lookup (primer->reverse_mappings,
295 &t->ul));
296 g_assert (local_tag != 0);
297
298 GST_WRITE_UINT16_BE (data, local_tag);
299 GST_WRITE_UINT16_BE (data + 2, t->size);
300 data += 4;
301 size -= 4;
302 g_assert (size >= t->size);
303
304 memcpy (data, t->data, t->size);
305 data += t->size;
306 size -= t->size;
307
308 mxf_local_tag_free (t);
309 }
310
311 g_list_free (tags);
312
313 gst_buffer_unmap (ret, &map);
314
315 return ret;
316 }
317
318 G_DEFINE_ABSTRACT_TYPE (MXFMetadata, mxf_metadata, MXF_TYPE_METADATA_BASE);
319
320 static gboolean
mxf_metadata_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)321 mxf_metadata_handle_tag (MXFMetadataBase * metadata, MXFPrimerPack * primer,
322 guint16 tag, const guint8 * tag_data, guint tag_size)
323 {
324 #ifndef GST_DISABLE_GST_DEBUG
325 gchar str[48];
326 #endif
327 MXFMetadata *self = MXF_METADATA (metadata);
328 gboolean ret = TRUE;
329
330 switch (tag) {
331 case 0x3c0a:
332 if (tag_size != 16)
333 goto error;
334 memcpy (&self->parent.instance_uid, tag_data, 16);
335 GST_DEBUG (" instance uid = %s",
336 mxf_uuid_to_string (&self->parent.instance_uid, str));
337 break;
338 case 0x0102:
339 if (tag_size != 16)
340 goto error;
341 memcpy (&self->parent.generation_uid, tag_data, 16);
342 GST_DEBUG (" generation uid = %s",
343 mxf_uuid_to_string (&self->parent.generation_uid, str));
344 break;
345 default:
346 ret =
347 MXF_METADATA_BASE_CLASS (mxf_metadata_parent_class)->handle_tag
348 (metadata, primer, tag, tag_data, tag_size);
349 break;
350 }
351
352 return ret;
353
354 error:
355
356 GST_ERROR ("Invalid metadata local tag 0x%04x of size %u", tag, tag_size);
357
358 return FALSE;
359 }
360
361 static GList *
mxf_metadata_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)362 mxf_metadata_write_tags (MXFMetadataBase * m, MXFPrimerPack * primer)
363 {
364 MXFMetadata *self = MXF_METADATA (m);
365 GList *ret = NULL;
366 MXFLocalTag *t;
367 MXFMetadataClass *klass;
368
369 g_return_val_if_fail (MXF_IS_METADATA (self), NULL);
370 klass = MXF_METADATA_GET_CLASS (self);
371
372 /* Last element contains the metadata key */
373 t = g_slice_new0 (MXFLocalTag);
374 memcpy (&t->ul, MXF_UL (METADATA), 16);
375 GST_WRITE_UINT16_BE (&t->ul.u[13], klass->type);
376 ret = g_list_prepend (ret, t);
377
378 t = g_slice_new0 (MXFLocalTag);
379 memcpy (&t->ul, MXF_UL (INSTANCE_UID), 16);
380 t->size = 16;
381 t->data = g_slice_alloc (16);
382 t->g_slice = TRUE;
383 memcpy (t->data, &self->parent.instance_uid, 16);
384 mxf_primer_pack_add_mapping (primer, 0x3c0a, &t->ul);
385 ret = g_list_prepend (ret, t);
386
387 if (!mxf_uuid_is_zero (&self->parent.generation_uid)) {
388 t = g_slice_new0 (MXFLocalTag);
389 memcpy (&t->ul, MXF_UL (GENERATION_UID), 16);
390 t->size = 16;
391 t->data = g_slice_alloc (16);
392 t->g_slice = TRUE;
393 memcpy (t->data, &self->parent.generation_uid, 16);
394 mxf_primer_pack_add_mapping (primer, 0x0102, &t->ul);
395 ret = g_list_prepend (ret, t);
396 }
397
398 return ret;
399 }
400
401 static void
mxf_metadata_class_init(MXFMetadataClass * klass)402 mxf_metadata_class_init (MXFMetadataClass * klass)
403 {
404 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
405
406 metadata_base_class->handle_tag = mxf_metadata_handle_tag;
407 metadata_base_class->write_tags = mxf_metadata_write_tags;
408 }
409
410 static void
mxf_metadata_init(MXFMetadata * self)411 mxf_metadata_init (MXFMetadata * self)
412 {
413 }
414
415 static GArray *_mxf_metadata_registry = NULL;
416
417 #define _add_metadata_type(type) G_STMT_START { \
418 GType t = type; \
419 \
420 g_array_append_val (_mxf_metadata_registry, t); \
421 } G_STMT_END
422
423 void
mxf_metadata_init_types(void)424 mxf_metadata_init_types (void)
425 {
426 g_return_if_fail (_mxf_metadata_registry == NULL);
427
428 _mxf_metadata_registry = g_array_new (FALSE, TRUE, sizeof (GType));
429
430 _add_metadata_type (MXF_TYPE_METADATA_PREFACE);
431 _add_metadata_type (MXF_TYPE_METADATA_IDENTIFICATION);
432 _add_metadata_type (MXF_TYPE_METADATA_CONTENT_STORAGE);
433 _add_metadata_type (MXF_TYPE_METADATA_ESSENCE_CONTAINER_DATA);
434 _add_metadata_type (MXF_TYPE_METADATA_MATERIAL_PACKAGE);
435 _add_metadata_type (MXF_TYPE_METADATA_SOURCE_PACKAGE);
436 _add_metadata_type (MXF_TYPE_METADATA_TIMELINE_TRACK);
437 _add_metadata_type (MXF_TYPE_METADATA_EVENT_TRACK);
438 _add_metadata_type (MXF_TYPE_METADATA_STATIC_TRACK);
439 _add_metadata_type (MXF_TYPE_METADATA_SEQUENCE);
440 _add_metadata_type (MXF_TYPE_METADATA_SOURCE_CLIP);
441 _add_metadata_type (MXF_TYPE_METADATA_FILLER);
442 _add_metadata_type (MXF_TYPE_METADATA_TIMECODE_COMPONENT);
443 _add_metadata_type (MXF_TYPE_METADATA_DM_SEGMENT);
444 _add_metadata_type (MXF_TYPE_METADATA_DM_SOURCE_CLIP);
445 _add_metadata_type (MXF_TYPE_METADATA_FILE_DESCRIPTOR);
446 _add_metadata_type (MXF_TYPE_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR);
447 _add_metadata_type (MXF_TYPE_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR);
448 _add_metadata_type (MXF_TYPE_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR);
449 _add_metadata_type (MXF_TYPE_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR);
450 _add_metadata_type (MXF_TYPE_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR);
451 _add_metadata_type (MXF_TYPE_METADATA_MULTIPLE_DESCRIPTOR);
452 _add_metadata_type (MXF_TYPE_METADATA_NETWORK_LOCATOR);
453 _add_metadata_type (MXF_TYPE_METADATA_TEXT_LOCATOR);
454 }
455
456 #undef _add_metadata_type
457
458 void
mxf_metadata_register(GType type)459 mxf_metadata_register (GType type)
460 {
461 g_return_if_fail (g_type_is_a (type, MXF_TYPE_METADATA));
462
463 g_array_append_val (_mxf_metadata_registry, type);
464 }
465
466 MXFMetadata *
mxf_metadata_new(guint16 type,MXFPrimerPack * primer,guint64 offset,const guint8 * data,guint size)467 mxf_metadata_new (guint16 type, MXFPrimerPack * primer, guint64 offset,
468 const guint8 * data, guint size)
469 {
470 guint i;
471 GType t = G_TYPE_INVALID;
472 MXFMetadata *ret = NULL;
473
474 g_return_val_if_fail (type != 0, NULL);
475 g_return_val_if_fail (primer != NULL, NULL);
476 g_return_val_if_fail (_mxf_metadata_registry != NULL, NULL);
477
478 for (i = 0; i < _mxf_metadata_registry->len; i++) {
479 GType tmp = g_array_index (_mxf_metadata_registry, GType, i);
480 MXFMetadataClass *klass = MXF_METADATA_CLASS (g_type_class_ref (tmp));
481
482 if (klass->type == type) {
483 g_type_class_unref (klass);
484 t = tmp;
485 break;
486 }
487 g_type_class_unref (klass);
488 }
489
490 if (t == G_TYPE_INVALID) {
491 GST_WARNING
492 ("No handler for type 0x%04x found -- using generic metadata parser",
493 type);
494 return NULL;
495 }
496
497
498 GST_DEBUG ("Metadata type 0x%04x is handled by type %s", type,
499 g_type_name (t));
500
501 ret = (MXFMetadata *) g_type_create_instance (t);
502 if (!mxf_metadata_base_parse (MXF_METADATA_BASE (ret), primer, data, size)) {
503 GST_ERROR ("Parsing metadata failed");
504 g_object_unref (ret);
505 return NULL;
506 }
507
508 ret->parent.offset = offset;
509 return ret;
510 }
511
512 G_DEFINE_TYPE (MXFMetadataPreface, mxf_metadata_preface, MXF_TYPE_METADATA);
513
514 static void
mxf_metadata_preface_finalize(GObject * object)515 mxf_metadata_preface_finalize (GObject * object)
516 {
517 MXFMetadataPreface *self = MXF_METADATA_PREFACE (object);
518
519 g_free (self->identifications_uids);
520 self->identifications_uids = NULL;
521
522 g_free (self->identifications);
523 self->identifications = NULL;
524
525 g_free (self->essence_containers);
526 self->essence_containers = NULL;
527
528 g_free (self->dm_schemes);
529 self->dm_schemes = NULL;
530
531 G_OBJECT_CLASS (mxf_metadata_preface_parent_class)->finalize (object);
532 }
533
534 static gboolean
mxf_metadata_preface_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)535 mxf_metadata_preface_handle_tag (MXFMetadataBase * metadata,
536 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
537 guint tag_size)
538 {
539 MXFMetadataPreface *self = MXF_METADATA_PREFACE (metadata);
540 #ifndef GST_DISABLE_GST_DEBUG
541 gchar str[48];
542 #endif
543 gboolean ret = TRUE;
544
545 switch (tag) {
546 case 0x3b02:
547 if (!mxf_timestamp_parse (&self->last_modified_date, tag_data, tag_size))
548 goto error;
549 GST_DEBUG (" last modified date = %s",
550 mxf_timestamp_to_string (&self->last_modified_date, str));
551 break;
552 case 0x3b05:
553 if (tag_size != 2)
554 goto error;
555 self->version = GST_READ_UINT16_BE (tag_data);
556 GST_DEBUG (" version = %u.%u", (self->version >> 8),
557 (self->version & 0x0f));
558 break;
559 case 0x3b07:
560 if (tag_size != 4)
561 goto error;
562 self->object_model_version = GST_READ_UINT32_BE (tag_data);
563 GST_DEBUG (" object model version = %u", self->object_model_version);
564 break;
565 case 0x3b08:
566 if (tag_size != 16)
567 goto error;
568 memcpy (&self->primary_package_uid, tag_data, 16);
569 GST_DEBUG (" primary package = %s",
570 mxf_uuid_to_string (&self->primary_package_uid, str));
571 break;
572 case 0x3b06:
573 if (!mxf_uuid_array_parse (&self->identifications_uids,
574 &self->n_identifications, tag_data, tag_size))
575 goto error;
576
577 GST_DEBUG (" number of identifications = %u", self->n_identifications);
578 #ifndef GST_DISABLE_GST_DEBUG
579 {
580 guint i;
581 for (i = 0; i < self->n_identifications; i++) {
582 GST_DEBUG (" identification %u = %s", i,
583 mxf_uuid_to_string (&self->identifications_uids[i], str));
584 }
585 }
586 #endif
587 break;
588 case 0x3b03:
589 if (tag_size != 16)
590 goto error;
591 memcpy (&self->content_storage_uid, tag_data, 16);
592 GST_DEBUG (" content storage = %s",
593 mxf_uuid_to_string (&self->content_storage_uid, str));
594 break;
595 case 0x3b09:
596 if (tag_size != 16)
597 goto error;
598 memcpy (&self->operational_pattern, tag_data, 16);
599 GST_DEBUG (" operational pattern = %s",
600 mxf_ul_to_string (&self->operational_pattern, str));
601 break;
602 case 0x3b0a:
603 if (!mxf_ul_array_parse (&self->essence_containers,
604 &self->n_essence_containers, tag_data, tag_size))
605 goto error;
606
607 GST_DEBUG (" number of essence containers = %u",
608 self->n_essence_containers);
609 #ifndef GST_DISABLE_GST_DEBUG
610 {
611 guint i;
612 for (i = 0; i < self->n_essence_containers; i++) {
613 GST_DEBUG (" essence container %u = %s", i,
614 mxf_ul_to_string (&self->essence_containers[i], str));
615 }
616 }
617 #endif
618 break;
619 case 0x3b0b:
620 if (!mxf_ul_array_parse (&self->dm_schemes, &self->n_dm_schemes, tag_data,
621 tag_size))
622 goto error;
623 GST_DEBUG (" number of DM schemes = %u", self->n_dm_schemes);
624
625 #ifndef GST_DISABLE_GST_DEBUG
626 {
627 guint i;
628 for (i = 0; i < self->n_dm_schemes; i++) {
629 GST_DEBUG (" DM schemes %u = %s", i,
630 mxf_ul_to_string (&self->dm_schemes[i], str));
631 }
632 }
633 #endif
634 break;
635 default:
636 ret =
637 MXF_METADATA_BASE_CLASS
638 (mxf_metadata_preface_parent_class)->handle_tag (metadata, primer,
639 tag, tag_data, tag_size);
640 break;
641 }
642
643 return ret;
644
645 error:
646
647 GST_ERROR ("Invalid preface local tag 0x%04x of size %u", tag, tag_size);
648
649 return FALSE;
650 }
651
652 static gboolean
mxf_metadata_preface_resolve(MXFMetadataBase * m,GHashTable * metadata)653 mxf_metadata_preface_resolve (MXFMetadataBase * m, GHashTable * metadata)
654 {
655 MXFMetadataPreface *self = MXF_METADATA_PREFACE (m);
656 MXFMetadataBase *current = NULL;
657 guint i;
658 #ifndef GST_DISABLE_GST_DEBUG
659 gchar str[48];
660 #endif
661
662 if (!mxf_uuid_is_zero (&self->primary_package_uid)) {
663 current = g_hash_table_lookup (metadata, &self->primary_package_uid);
664 if (!current || !MXF_IS_METADATA_GENERIC_PACKAGE (current)) {
665 GST_ERROR ("Primary package %s not found",
666 mxf_uuid_to_string (&self->primary_package_uid, str));
667 } else {
668 if (mxf_metadata_base_resolve (current, metadata)) {
669 self->primary_package = MXF_METADATA_GENERIC_PACKAGE (current);
670 }
671 }
672 }
673 current = NULL;
674
675 current = g_hash_table_lookup (metadata, &self->content_storage_uid);
676 if (!current || !MXF_IS_METADATA_CONTENT_STORAGE (current)) {
677 GST_ERROR ("Content storage %s not found",
678 mxf_uuid_to_string (&self->content_storage_uid, str));
679 return FALSE;
680 } else {
681 if (mxf_metadata_base_resolve (current, metadata)) {
682 self->content_storage = MXF_METADATA_CONTENT_STORAGE (current);
683 } else {
684 GST_ERROR ("Couldn't resolve content storage %s",
685 mxf_uuid_to_string (&self->content_storage_uid, str));
686 return FALSE;
687 }
688 }
689 current = NULL;
690
691 if (self->identifications)
692 memset (self->identifications, 0,
693 sizeof (gpointer) * self->n_identifications);
694 else
695 self->identifications =
696 g_new0 (MXFMetadataIdentification *, self->n_identifications);
697 for (i = 0; i < self->n_identifications; i++) {
698 current = g_hash_table_lookup (metadata, &self->identifications_uids[i]);
699 if (current && MXF_IS_METADATA_IDENTIFICATION (current)) {
700 if (mxf_metadata_base_resolve (current, metadata))
701 self->identifications[i] = MXF_METADATA_IDENTIFICATION (current);
702 }
703 current = NULL;
704 }
705
706 return
707 MXF_METADATA_BASE_CLASS (mxf_metadata_preface_parent_class)->resolve (m,
708 metadata);
709 }
710
711 static GstStructure *
mxf_metadata_preface_to_structure(MXFMetadataBase * m)712 mxf_metadata_preface_to_structure (MXFMetadataBase * m)
713 {
714 GstStructure *ret =
715 MXF_METADATA_BASE_CLASS (mxf_metadata_preface_parent_class)->to_structure
716 (m);
717 MXFMetadataPreface *self = MXF_METADATA_PREFACE (m);
718 gchar str[48];
719 guint i;
720
721 if (!mxf_timestamp_is_unknown (&self->last_modified_date)) {
722 mxf_timestamp_to_string (&self->last_modified_date, str);
723 gst_structure_id_set (ret, MXF_QUARK (LAST_MODIFIED_DATE), G_TYPE_STRING,
724 str, NULL);
725 }
726
727 if (self->version != 0)
728 gst_structure_id_set (ret, MXF_QUARK (VERSION), G_TYPE_UINT, self->version,
729 NULL);
730
731 if (self->object_model_version != 0)
732 gst_structure_id_set (ret, MXF_QUARK (OBJECT_MODEL_VERSION), G_TYPE_UINT,
733 self->object_model_version, NULL);
734
735 if (!mxf_uuid_is_zero (&self->primary_package_uid)) {
736 mxf_uuid_to_string (&self->primary_package_uid, str);
737 gst_structure_id_set (ret, MXF_QUARK (PRIMARY_PACKAGE), G_TYPE_STRING, str,
738 NULL);
739 }
740
741 if (self->n_identifications > 0) {
742 GValue arr = { 0, }
743 , val = {
744 0,};
745
746 g_value_init (&arr, GST_TYPE_ARRAY);
747
748 for (i = 0; i < self->n_identifications; i++) {
749 GstStructure *s;
750
751 if (self->identifications[i] == NULL)
752 continue;
753
754 g_value_init (&val, GST_TYPE_STRUCTURE);
755
756 s = mxf_metadata_base_to_structure (MXF_METADATA_BASE
757 (self->identifications[i]));
758 gst_value_set_structure (&val, s);
759 gst_structure_free (s);
760 gst_value_array_append_value (&arr, &val);
761 g_value_unset (&val);
762 }
763
764 if (gst_value_array_get_size (&arr) > 0)
765 gst_structure_id_set_value (ret, MXF_QUARK (IDENTIFICATIONS), &arr);
766
767 g_value_unset (&arr);
768 }
769
770 if (self->content_storage) {
771 GstStructure *s =
772 mxf_metadata_base_to_structure (MXF_METADATA_BASE
773 (self->content_storage));
774 gst_structure_id_set (ret, MXF_QUARK (CONTENT_STORAGE), GST_TYPE_STRUCTURE,
775 s, NULL);
776 gst_structure_free (s);
777 }
778
779 if (!mxf_ul_is_zero (&self->operational_pattern)) {
780 mxf_ul_to_string (&self->operational_pattern, str);
781 gst_structure_id_set (ret, MXF_QUARK (OPERATIONAL_PATTERN), G_TYPE_STRING,
782 str, NULL);
783 }
784
785 if (self->n_essence_containers > 0) {
786 GValue arr = { 0, }
787 , val = {
788 0,};
789
790 g_value_init (&arr, GST_TYPE_ARRAY);
791
792 for (i = 0; i < self->n_essence_containers; i++) {
793 if (mxf_ul_is_zero (&self->essence_containers[i]))
794 continue;
795
796 g_value_init (&val, G_TYPE_STRING);
797
798 mxf_ul_to_string (&self->essence_containers[i], str);
799 g_value_set_string (&val, str);
800
801 gst_value_array_append_value (&arr, &val);
802 g_value_unset (&val);
803 }
804
805 if (gst_value_array_get_size (&arr) > 0)
806 gst_structure_id_set_value (ret, MXF_QUARK (ESSENCE_CONTAINERS), &arr);
807
808 g_value_unset (&arr);
809 }
810
811 if (self->n_dm_schemes > 0) {
812 GValue arr = { 0, }
813 , val = {
814 0,};
815
816 g_value_init (&arr, GST_TYPE_ARRAY);
817
818 for (i = 0; i < self->n_dm_schemes; i++) {
819 if (mxf_ul_is_zero (&self->dm_schemes[i]))
820 continue;
821
822 g_value_init (&val, G_TYPE_STRING);
823
824 mxf_ul_to_string (&self->dm_schemes[i], str);
825 g_value_set_string (&val, str);
826
827 gst_value_array_append_value (&arr, &val);
828 g_value_unset (&val);
829 }
830
831 if (gst_value_array_get_size (&arr) > 0)
832 gst_structure_id_set_value (ret, MXF_QUARK (DM_SCHEMES), &arr);
833
834 g_value_unset (&arr);
835 }
836
837 return ret;
838 }
839
840 static GList *
mxf_metadata_preface_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)841 mxf_metadata_preface_write_tags (MXFMetadataBase * m, MXFPrimerPack * primer)
842 {
843 MXFMetadataPreface *self = MXF_METADATA_PREFACE (m);
844 GList *ret =
845 MXF_METADATA_BASE_CLASS (mxf_metadata_preface_parent_class)->write_tags
846 (m, primer);
847 MXFLocalTag *t;
848 guint i;
849
850 t = g_slice_new0 (MXFLocalTag);
851 memcpy (&t->ul, MXF_UL (LAST_MODIFIED_DATE), 16);
852 t->size = 8;
853 t->data = g_slice_alloc (8);
854 t->g_slice = TRUE;
855 mxf_timestamp_write (&self->last_modified_date, t->data);
856 mxf_primer_pack_add_mapping (primer, 0x3b02, &t->ul);
857 ret = g_list_prepend (ret, t);
858
859 t = g_slice_new0 (MXFLocalTag);
860 memcpy (&t->ul, MXF_UL (VERSION), 16);
861 t->size = 2;
862 t->data = g_slice_alloc (2);
863 t->g_slice = TRUE;
864 GST_WRITE_UINT16_BE (t->data, self->version);
865 mxf_primer_pack_add_mapping (primer, 0x3b05, &t->ul);
866 ret = g_list_prepend (ret, t);
867
868 if (self->object_model_version) {
869 t = g_slice_new0 (MXFLocalTag);
870 memcpy (&t->ul, MXF_UL (OBJECT_MODEL_VERSION), 16);
871 t->size = 4;
872 t->data = g_slice_alloc (4);
873 t->g_slice = TRUE;
874 GST_WRITE_UINT32_BE (t->data, self->object_model_version);
875 mxf_primer_pack_add_mapping (primer, 0x3b07, &t->ul);
876 ret = g_list_prepend (ret, t);
877 }
878
879 if (!mxf_uuid_is_zero (&self->primary_package_uid)) {
880 t = g_slice_new0 (MXFLocalTag);
881 memcpy (&t->ul, MXF_UL (PRIMARY_PACKAGE), 16);
882 t->size = 16;
883 t->data = g_slice_alloc (16);
884 t->g_slice = TRUE;
885 memcpy (t->data, &self->primary_package_uid, 16);
886 mxf_primer_pack_add_mapping (primer, 0x3b08, &t->ul);
887 ret = g_list_prepend (ret, t);
888 }
889
890 t = g_slice_new0 (MXFLocalTag);
891 memcpy (&t->ul, MXF_UL (IDENTIFICATIONS), 16);
892 t->size = 8 + 16 * self->n_identifications;
893 t->data = g_slice_alloc0 (t->size);
894 t->g_slice = TRUE;
895 mxf_primer_pack_add_mapping (primer, 0x3b06, &t->ul);
896 GST_WRITE_UINT32_BE (t->data, self->n_identifications);
897 GST_WRITE_UINT32_BE (t->data + 4, 16);
898 for (i = 0; i < self->n_identifications; i++) {
899 if (!self->identifications[i])
900 continue;
901
902 memcpy (t->data + 8 + 16 * i,
903 &MXF_METADATA_BASE (self->identifications[i])->instance_uid, 16);
904 }
905 ret = g_list_prepend (ret, t);
906
907 t = g_slice_new0 (MXFLocalTag);
908 memcpy (&t->ul, MXF_UL (CONTENT_STORAGE), 16);
909 t->size = 16;
910 t->data = g_slice_alloc (t->size);
911 t->g_slice = TRUE;
912 mxf_primer_pack_add_mapping (primer, 0x3b03, &t->ul);
913 memcpy (t->data, &MXF_METADATA_BASE (self->content_storage)->instance_uid,
914 16);
915 ret = g_list_prepend (ret, t);
916
917 t = g_slice_new0 (MXFLocalTag);
918 memcpy (&t->ul, MXF_UL (OPERATIONAL_PATTERN), 16);
919 t->size = 16;
920 t->data = g_slice_alloc (t->size);
921 t->g_slice = TRUE;
922 mxf_primer_pack_add_mapping (primer, 0x3b09, &t->ul);
923 memcpy (t->data, &self->operational_pattern, 16);
924 ret = g_list_prepend (ret, t);
925
926 t = g_slice_new0 (MXFLocalTag);
927 memcpy (&t->ul, MXF_UL (ESSENCE_CONTAINERS), 16);
928 t->size = 8 + 16 * self->n_essence_containers;
929 t->data = g_slice_alloc0 (t->size);
930 t->g_slice = TRUE;
931 mxf_primer_pack_add_mapping (primer, 0x3b0a, &t->ul);
932 GST_WRITE_UINT32_BE (t->data, self->n_essence_containers);
933 GST_WRITE_UINT32_BE (t->data + 4, 16);
934 for (i = 0; i < self->n_essence_containers; i++) {
935 memcpy (t->data + 8 + 16 * i, &self->essence_containers[i], 16);
936 }
937 ret = g_list_prepend (ret, t);
938
939 t = g_slice_new0 (MXFLocalTag);
940 memcpy (&t->ul, MXF_UL (DM_SCHEMES), 16);
941 t->size = 8 + 16 * self->n_dm_schemes;
942 t->data = g_slice_alloc0 (t->size);
943 t->g_slice = TRUE;
944 mxf_primer_pack_add_mapping (primer, 0x3b0b, &t->ul);
945 GST_WRITE_UINT32_BE (t->data, self->n_dm_schemes);
946 GST_WRITE_UINT32_BE (t->data + 4, 16);
947 for (i = 0; i < self->n_dm_schemes; i++) {
948 memcpy (t->data + 8 + 16 * i, &self->dm_schemes[i], 16);
949 }
950 ret = g_list_prepend (ret, t);
951
952 return ret;
953 }
954
955 static void
mxf_metadata_preface_init(MXFMetadataPreface * self)956 mxf_metadata_preface_init (MXFMetadataPreface * self)
957 {
958
959 }
960
961 static void
mxf_metadata_preface_class_init(MXFMetadataPrefaceClass * klass)962 mxf_metadata_preface_class_init (MXFMetadataPrefaceClass * klass)
963 {
964 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
965 GObjectClass *object_class = (GObjectClass *) klass;
966 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
967
968 object_class->finalize = mxf_metadata_preface_finalize;
969 metadata_base_class->handle_tag = mxf_metadata_preface_handle_tag;
970 metadata_base_class->resolve = mxf_metadata_preface_resolve;
971 metadata_base_class->to_structure = mxf_metadata_preface_to_structure;
972 metadata_base_class->write_tags = mxf_metadata_preface_write_tags;
973 metadata_base_class->name_quark = MXF_QUARK (PREFACE);
974 metadata_class->type = 0x012f;
975 }
976
977 G_DEFINE_TYPE (MXFMetadataIdentification, mxf_metadata_identification,
978 MXF_TYPE_METADATA);
979
980 static void
mxf_metadata_identification_finalize(GObject * object)981 mxf_metadata_identification_finalize (GObject * object)
982 {
983 MXFMetadataIdentification *self = MXF_METADATA_IDENTIFICATION (object);
984
985 g_free (self->company_name);
986 self->company_name = NULL;
987
988 g_free (self->product_name);
989 self->product_name = NULL;
990
991 g_free (self->version_string);
992 self->version_string = NULL;
993
994 g_free (self->platform);
995 self->platform = NULL;
996
997 G_OBJECT_CLASS (mxf_metadata_identification_parent_class)->finalize (object);
998 }
999
1000 static gboolean
mxf_metadata_identification_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)1001 mxf_metadata_identification_handle_tag (MXFMetadataBase * metadata,
1002 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
1003 guint tag_size)
1004 {
1005 MXFMetadataIdentification *self = MXF_METADATA_IDENTIFICATION (metadata);
1006 gboolean ret = TRUE;
1007 #ifndef GST_DISABLE_GST_DEBUG
1008 gchar str[48];
1009 #endif
1010
1011 switch (tag) {
1012 case 0x3c09:
1013 if (tag_size != 16)
1014 goto error;
1015 memcpy (&self->this_generation_uid, tag_data, 16);
1016 GST_DEBUG (" this generation uid = %s",
1017 mxf_uuid_to_string (&self->this_generation_uid, str));
1018 break;
1019 case 0x3c01:
1020 self->company_name = mxf_utf16_to_utf8 (tag_data, tag_size);
1021 GST_DEBUG (" company name = %s", GST_STR_NULL (self->company_name));
1022 break;
1023 case 0x3c02:
1024 self->product_name = mxf_utf16_to_utf8 (tag_data, tag_size);
1025 GST_DEBUG (" product name = %s", GST_STR_NULL (self->product_name));
1026 break;
1027 case 0x3c03:
1028 if (!mxf_product_version_parse (&self->product_version,
1029 tag_data, tag_size))
1030 goto error;
1031 GST_DEBUG (" product version = %u.%u.%u.%u.%u",
1032 self->product_version.major,
1033 self->product_version.minor,
1034 self->product_version.patch,
1035 self->product_version.build, self->product_version.release);
1036 break;
1037 case 0x3c04:
1038 self->version_string = mxf_utf16_to_utf8 (tag_data, tag_size);
1039 GST_DEBUG (" version string = %s", GST_STR_NULL (self->version_string));
1040 break;
1041 case 0x3c05:
1042 if (tag_size != 16)
1043 goto error;
1044 memcpy (&self->product_uid, tag_data, 16);
1045 GST_DEBUG (" product uid = %s",
1046 mxf_uuid_to_string (&self->product_uid, str));
1047 break;
1048 case 0x3c06:
1049 if (!mxf_timestamp_parse (&self->modification_date, tag_data, tag_size))
1050 goto error;
1051 GST_DEBUG (" modification date = %s",
1052 mxf_timestamp_to_string (&self->modification_date, str));
1053 break;
1054 case 0x3c07:
1055 if (!mxf_product_version_parse (&self->toolkit_version,
1056 tag_data, tag_size))
1057 goto error;
1058 GST_DEBUG (" toolkit version = %u.%u.%u.%u.%u",
1059 self->toolkit_version.major,
1060 self->toolkit_version.minor,
1061 self->toolkit_version.patch,
1062 self->toolkit_version.build, self->toolkit_version.release);
1063 break;
1064 case 0x3c08:
1065 self->platform = mxf_utf16_to_utf8 (tag_data, tag_size);
1066 GST_DEBUG (" platform = %s", GST_STR_NULL (self->platform));
1067 break;
1068 default:
1069 ret =
1070 MXF_METADATA_BASE_CLASS
1071 (mxf_metadata_identification_parent_class)->handle_tag (metadata,
1072 primer, tag, tag_data, tag_size);
1073 break;
1074 }
1075
1076 return ret;
1077
1078 error:
1079 GST_ERROR ("Invalid identification local tag 0x%04x of size %u", tag,
1080 tag_size);
1081
1082 return FALSE;
1083 }
1084
1085 static GstStructure *
mxf_metadata_identification_to_structure(MXFMetadataBase * m)1086 mxf_metadata_identification_to_structure (MXFMetadataBase * m)
1087 {
1088 GstStructure *ret =
1089 MXF_METADATA_BASE_CLASS
1090 (mxf_metadata_identification_parent_class)->to_structure (m);
1091 MXFMetadataIdentification *self = MXF_METADATA_IDENTIFICATION (m);
1092 gchar str[48];
1093
1094 if (!mxf_uuid_is_zero (&self->this_generation_uid)) {
1095 mxf_uuid_to_string (&self->this_generation_uid, str);
1096 gst_structure_id_set (ret, MXF_QUARK (THIS_GENERATION_UID), G_TYPE_STRING,
1097 str, NULL);
1098 }
1099
1100 if (self->company_name)
1101 gst_structure_id_set (ret, MXF_QUARK (COMPANY_NAME), G_TYPE_STRING,
1102 self->company_name, NULL);
1103
1104 if (self->product_name)
1105 gst_structure_id_set (ret, MXF_QUARK (PRODUCT_NAME), G_TYPE_STRING,
1106 self->product_name, NULL);
1107
1108 if (self->product_version.major ||
1109 self->product_version.minor ||
1110 self->product_version.patch ||
1111 self->product_version.build || self->product_version.release) {
1112 g_snprintf (str, 48, "%u.%u.%u.%u.%u", self->product_version.major,
1113 self->product_version.minor,
1114 self->product_version.patch,
1115 self->product_version.build, self->product_version.release);
1116 gst_structure_id_set (ret, MXF_QUARK (PRODUCT_VERSION), G_TYPE_STRING, str,
1117 NULL);
1118 }
1119
1120 if (self->version_string)
1121 gst_structure_id_set (ret, MXF_QUARK (VERSION_STRING), G_TYPE_STRING,
1122 self->version_string, NULL);
1123
1124 if (!mxf_uuid_is_zero (&self->product_uid)) {
1125 mxf_uuid_to_string (&self->product_uid, str);
1126 gst_structure_id_set (ret, MXF_QUARK (PRODUCT_UID), G_TYPE_STRING, str,
1127 NULL);
1128 }
1129
1130 if (!mxf_timestamp_is_unknown (&self->modification_date)) {
1131 mxf_timestamp_to_string (&self->modification_date, str);
1132 gst_structure_id_set (ret, MXF_QUARK (MODIFICATION_DATE), G_TYPE_STRING,
1133 str, NULL);
1134 }
1135
1136 if (self->toolkit_version.major ||
1137 self->toolkit_version.minor ||
1138 self->toolkit_version.patch ||
1139 self->toolkit_version.build || self->toolkit_version.release) {
1140 g_snprintf (str, 48, "%u.%u.%u.%u.%u", self->toolkit_version.major,
1141 self->toolkit_version.minor,
1142 self->toolkit_version.patch,
1143 self->toolkit_version.build, self->toolkit_version.release);
1144 gst_structure_id_set (ret, MXF_QUARK (TOOLKIT_VERSION), G_TYPE_STRING, str,
1145 NULL);
1146 }
1147
1148 if (self->platform)
1149 gst_structure_id_set (ret, MXF_QUARK (PLATFORM), G_TYPE_STRING,
1150 self->platform, NULL);
1151
1152 return ret;
1153 }
1154
1155 static GList *
mxf_metadata_identification_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)1156 mxf_metadata_identification_write_tags (MXFMetadataBase * m,
1157 MXFPrimerPack * primer)
1158 {
1159 MXFMetadataIdentification *self = MXF_METADATA_IDENTIFICATION (m);
1160 GList *ret =
1161 MXF_METADATA_BASE_CLASS
1162 (mxf_metadata_identification_parent_class)->write_tags (m, primer);
1163 MXFLocalTag *t;
1164
1165 if (self->company_name) {
1166 t = g_slice_new0 (MXFLocalTag);
1167 memcpy (&t->ul, MXF_UL (COMPANY_NAME), 16);
1168 t->data = mxf_utf8_to_utf16 (self->company_name, &t->size);
1169 mxf_primer_pack_add_mapping (primer, 0x3c01, &t->ul);
1170 ret = g_list_prepend (ret, t);
1171 }
1172
1173 if (self->product_name) {
1174 t = g_slice_new0 (MXFLocalTag);
1175 memcpy (&t->ul, MXF_UL (PRODUCT_NAME), 16);
1176 t->data = mxf_utf8_to_utf16 (self->product_name, &t->size);
1177 mxf_primer_pack_add_mapping (primer, 0x3c02, &t->ul);
1178 ret = g_list_prepend (ret, t);
1179 }
1180
1181 if (!mxf_product_version_is_valid (&self->product_version)) {
1182 t = g_slice_new0 (MXFLocalTag);
1183 memcpy (&t->ul, MXF_UL (PRODUCT_VERSION), 16);
1184 t->size = 10;
1185 t->data = g_slice_alloc (t->size);
1186 t->g_slice = TRUE;
1187 mxf_product_version_write (&self->product_version, t->data);
1188 mxf_primer_pack_add_mapping (primer, 0x3c03, &t->ul);
1189 ret = g_list_prepend (ret, t);
1190 }
1191
1192 if (self->version_string) {
1193 t = g_slice_new0 (MXFLocalTag);
1194 memcpy (&t->ul, MXF_UL (VERSION_STRING), 16);
1195 t->data = mxf_utf8_to_utf16 (self->version_string, &t->size);
1196 mxf_primer_pack_add_mapping (primer, 0x3c04, &t->ul);
1197 ret = g_list_prepend (ret, t);
1198 }
1199
1200 if (!mxf_uuid_is_zero (&self->product_uid)) {
1201 t = g_slice_new0 (MXFLocalTag);
1202 memcpy (&t->ul, MXF_UL (PRODUCT_UID), 16);
1203 t->size = 16;
1204 t->data = g_slice_alloc (t->size);
1205 t->g_slice = TRUE;
1206 memcpy (t->data, &self->product_uid, 16);
1207 mxf_primer_pack_add_mapping (primer, 0x3c05, &t->ul);
1208 ret = g_list_prepend (ret, t);
1209 }
1210
1211 if (!mxf_timestamp_is_unknown (&self->modification_date)) {
1212 t = g_slice_new0 (MXFLocalTag);
1213 memcpy (&t->ul, MXF_UL (MODIFICATION_DATE), 16);
1214 t->size = 8;
1215 t->data = g_slice_alloc (t->size);
1216 t->g_slice = TRUE;
1217 mxf_timestamp_write (&self->modification_date, t->data);
1218 mxf_primer_pack_add_mapping (primer, 0x3c06, &t->ul);
1219 ret = g_list_prepend (ret, t);
1220 }
1221
1222 if (!mxf_product_version_is_valid (&self->toolkit_version)) {
1223 t = g_slice_new0 (MXFLocalTag);
1224 memcpy (&t->ul, MXF_UL (TOOLKIT_VERSION), 16);
1225 t->size = 10;
1226 t->data = g_slice_alloc (t->size);
1227 t->g_slice = TRUE;
1228 mxf_product_version_write (&self->toolkit_version, t->data);
1229 mxf_primer_pack_add_mapping (primer, 0x3c07, &t->ul);
1230 ret = g_list_prepend (ret, t);
1231 }
1232
1233 if (self->platform) {
1234 t = g_slice_new0 (MXFLocalTag);
1235 memcpy (&t->ul, MXF_UL (PLATFORM), 16);
1236 t->data = mxf_utf8_to_utf16 (self->platform, &t->size);
1237 mxf_primer_pack_add_mapping (primer, 0x3c08, &t->ul);
1238 ret = g_list_prepend (ret, t);
1239 }
1240
1241 if (!mxf_uuid_is_zero (&self->this_generation_uid)) {
1242 t = g_slice_new0 (MXFLocalTag);
1243 memcpy (&t->ul, MXF_UL (THIS_GENERATION_UID), 16);
1244 t->size = 16;
1245 t->data = g_slice_alloc (t->size);
1246 t->g_slice = TRUE;
1247 memcpy (t->data, &self->this_generation_uid, 16);
1248 mxf_primer_pack_add_mapping (primer, 0x3c09, &t->ul);
1249 ret = g_list_prepend (ret, t);
1250 }
1251
1252 return ret;
1253 }
1254
1255 static void
mxf_metadata_identification_init(MXFMetadataIdentification * self)1256 mxf_metadata_identification_init (MXFMetadataIdentification * self)
1257 {
1258
1259 }
1260
1261 static void
mxf_metadata_identification_class_init(MXFMetadataIdentificationClass * klass)1262 mxf_metadata_identification_class_init (MXFMetadataIdentificationClass * klass)
1263 {
1264 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
1265 GObjectClass *object_class = (GObjectClass *) klass;
1266 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
1267
1268 object_class->finalize = mxf_metadata_identification_finalize;
1269 metadata_base_class->handle_tag = mxf_metadata_identification_handle_tag;
1270 metadata_base_class->name_quark = MXF_QUARK (IDENTIFICATION);
1271 metadata_base_class->to_structure = mxf_metadata_identification_to_structure;
1272 metadata_base_class->write_tags = mxf_metadata_identification_write_tags;
1273 metadata_class->type = 0x0130;
1274 }
1275
1276 G_DEFINE_TYPE (MXFMetadataContentStorage, mxf_metadata_content_storage,
1277 MXF_TYPE_METADATA);
1278
1279 static void
mxf_metadata_content_storage_finalize(GObject * object)1280 mxf_metadata_content_storage_finalize (GObject * object)
1281 {
1282 MXFMetadataContentStorage *self = MXF_METADATA_CONTENT_STORAGE (object);
1283
1284 g_free (self->packages);
1285 self->packages = NULL;
1286 g_free (self->packages_uids);
1287 self->packages_uids = NULL;
1288 g_free (self->essence_container_data);
1289 self->essence_container_data = NULL;
1290 g_free (self->essence_container_data_uids);
1291 self->essence_container_data_uids = NULL;
1292
1293 G_OBJECT_CLASS (mxf_metadata_content_storage_parent_class)->finalize (object);
1294 }
1295
1296 static gboolean
mxf_metadata_content_storage_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)1297 mxf_metadata_content_storage_handle_tag (MXFMetadataBase * metadata,
1298 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
1299 guint tag_size)
1300 {
1301 MXFMetadataContentStorage *self = MXF_METADATA_CONTENT_STORAGE (metadata);
1302 gboolean ret = TRUE;
1303 #ifndef GST_DISABLE_GST_DEBUG
1304 gchar str[48];
1305 #endif
1306
1307 switch (tag) {
1308 case 0x1901:
1309 if (!mxf_uuid_array_parse (&self->packages_uids, &self->n_packages,
1310 tag_data, tag_size))
1311 goto error;
1312 GST_DEBUG (" number of packages = %u", self->n_packages);
1313 #ifndef GST_DISABLE_GST_DEBUG
1314 {
1315 guint i;
1316 for (i = 0; i < self->n_packages; i++) {
1317 GST_DEBUG (" package %u = %s", i,
1318 mxf_uuid_to_string (&self->packages_uids[i], str));
1319 }
1320 }
1321 #endif
1322 break;
1323 case 0x1902:
1324 if (!mxf_uuid_array_parse (&self->essence_container_data_uids,
1325 &self->n_essence_container_data, tag_data, tag_size))
1326 goto error;
1327
1328 GST_DEBUG (" number of essence container data = %u",
1329 self->n_essence_container_data);
1330 #ifndef GST_DISABLE_GST_DEBUG
1331 {
1332 guint i;
1333 for (i = 0; i < self->n_essence_container_data; i++) {
1334 GST_DEBUG (" essence container data %u = %s", i,
1335 mxf_uuid_to_string (&self->essence_container_data_uids[i], str));
1336 }
1337 }
1338 #endif
1339 break;
1340 default:
1341 ret =
1342 MXF_METADATA_BASE_CLASS
1343 (mxf_metadata_content_storage_parent_class)->handle_tag (metadata,
1344 primer, tag, tag_data, tag_size);
1345 break;
1346 }
1347
1348 return ret;
1349
1350 error:
1351
1352 GST_ERROR ("Invalid content storage local tag 0x%04x of size %u", tag,
1353 tag_size);
1354
1355 return FALSE;
1356 }
1357
1358 static gboolean
mxf_metadata_content_storage_resolve(MXFMetadataBase * m,GHashTable * metadata)1359 mxf_metadata_content_storage_resolve (MXFMetadataBase * m,
1360 GHashTable * metadata)
1361 {
1362 MXFMetadataContentStorage *self = MXF_METADATA_CONTENT_STORAGE (m);
1363 MXFMetadataBase *current = NULL;
1364 guint i;
1365 gboolean have_package = FALSE;
1366 gboolean have_ecd = FALSE;
1367 #ifndef GST_DISABLE_GST_DEBUG
1368 gchar str[48];
1369 #endif
1370
1371 if (self->packages)
1372 memset (self->packages, 0, sizeof (gpointer) * self->n_packages);
1373 else
1374 self->packages = g_new0 (MXFMetadataGenericPackage *, self->n_packages);
1375
1376 for (i = 0; i < self->n_packages; i++) {
1377 current = g_hash_table_lookup (metadata, &self->packages_uids[i]);
1378 if (current && MXF_IS_METADATA_GENERIC_PACKAGE (current)) {
1379 if (mxf_metadata_base_resolve (current, metadata)) {
1380 self->packages[i] = MXF_METADATA_GENERIC_PACKAGE (current);
1381 have_package = TRUE;
1382 } else {
1383 GST_ERROR ("Couldn't resolve package %s",
1384 mxf_uuid_to_string (&self->packages_uids[i], str));
1385 }
1386 } else {
1387 GST_ERROR ("Package %s not found",
1388 mxf_uuid_to_string (&self->packages_uids[i], str));
1389 }
1390 }
1391
1392 if (self->essence_container_data)
1393 memset (self->essence_container_data, 0,
1394 sizeof (gpointer) * self->n_essence_container_data);
1395 else
1396 self->essence_container_data =
1397 g_new0 (MXFMetadataEssenceContainerData *,
1398 self->n_essence_container_data);
1399 for (i = 0; i < self->n_essence_container_data; i++) {
1400 current =
1401 g_hash_table_lookup (metadata, &self->essence_container_data_uids[i]);
1402 if (current && MXF_IS_METADATA_ESSENCE_CONTAINER_DATA (current)) {
1403 if (mxf_metadata_base_resolve (current, metadata)) {
1404 self->essence_container_data[i] =
1405 MXF_METADATA_ESSENCE_CONTAINER_DATA (current);
1406 have_ecd = TRUE;
1407 } else {
1408 GST_ERROR ("Couldn't resolve essence container data %s",
1409 mxf_uuid_to_string (&self->essence_container_data_uids[i], str));
1410 }
1411 } else {
1412 GST_ERROR ("Essence container data %s not found",
1413 mxf_uuid_to_string (&self->essence_container_data_uids[i], str));
1414 }
1415 }
1416
1417 if (!have_package) {
1418 GST_ERROR ("Couldn't resolve any package");
1419 return FALSE;
1420 } else if (!have_ecd) {
1421 GST_ERROR ("Couldn't resolve any essence container data");
1422 return FALSE;
1423 }
1424
1425 return
1426 MXF_METADATA_BASE_CLASS
1427 (mxf_metadata_content_storage_parent_class)->resolve (m, metadata);
1428 }
1429
1430 static GstStructure *
mxf_metadata_content_storage_to_structure(MXFMetadataBase * m)1431 mxf_metadata_content_storage_to_structure (MXFMetadataBase * m)
1432 {
1433 GstStructure *ret =
1434 MXF_METADATA_BASE_CLASS
1435 (mxf_metadata_content_storage_parent_class)->to_structure (m);
1436 MXFMetadataContentStorage *self = MXF_METADATA_CONTENT_STORAGE (m);
1437 guint i;
1438
1439 if (self->n_packages > 0) {
1440 GValue arr = { 0, }
1441 , val = {
1442 0,};
1443
1444 g_value_init (&arr, GST_TYPE_ARRAY);
1445
1446 for (i = 0; i < self->n_packages; i++) {
1447 GstStructure *s;
1448
1449 if (self->packages[i] == NULL)
1450 continue;
1451
1452 g_value_init (&val, GST_TYPE_STRUCTURE);
1453
1454 s = mxf_metadata_base_to_structure (MXF_METADATA_BASE (self->packages
1455 [i]));
1456 gst_value_set_structure (&val, s);
1457 gst_structure_free (s);
1458 gst_value_array_append_value (&arr, &val);
1459 g_value_unset (&val);
1460 }
1461
1462 if (gst_value_array_get_size (&arr) > 0)
1463 gst_structure_id_set_value (ret, MXF_QUARK (PACKAGES), &arr);
1464
1465 g_value_unset (&arr);
1466 }
1467
1468 if (self->n_essence_container_data > 0) {
1469 GValue arr = { 0, }
1470 , val = {
1471 0,};
1472
1473 g_value_init (&arr, GST_TYPE_ARRAY);
1474
1475 for (i = 0; i < self->n_essence_container_data; i++) {
1476 GstStructure *s;
1477
1478 if (self->essence_container_data[i] == NULL)
1479 continue;
1480
1481 g_value_init (&val, GST_TYPE_STRUCTURE);
1482
1483 s = mxf_metadata_base_to_structure (MXF_METADATA_BASE
1484 (self->essence_container_data[i]));
1485 gst_value_set_structure (&val, s);
1486 gst_structure_free (s);
1487 gst_value_array_append_value (&arr, &val);
1488 g_value_unset (&val);
1489 }
1490
1491 if (gst_value_array_get_size (&arr) > 0)
1492 gst_structure_id_set_value (ret, MXF_QUARK (ESSENCE_CONTAINER_DATA),
1493 &arr);
1494
1495 g_value_unset (&arr);
1496 }
1497
1498 return ret;
1499 }
1500
1501 static GList *
mxf_metadata_content_storage_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)1502 mxf_metadata_content_storage_write_tags (MXFMetadataBase * m,
1503 MXFPrimerPack * primer)
1504 {
1505 MXFMetadataContentStorage *self = MXF_METADATA_CONTENT_STORAGE (m);
1506 GList *ret =
1507 MXF_METADATA_BASE_CLASS
1508 (mxf_metadata_content_storage_parent_class)->write_tags (m, primer);
1509 MXFLocalTag *t;
1510 guint i;
1511
1512 if (self->packages) {
1513 t = g_slice_new0 (MXFLocalTag);
1514 memcpy (&t->ul, MXF_UL (PACKAGES), 16);
1515 t->size = 8 + 16 * self->n_packages;
1516 t->data = g_slice_alloc0 (t->size);
1517 t->g_slice = TRUE;
1518 GST_WRITE_UINT32_BE (t->data, self->n_packages);
1519 GST_WRITE_UINT32_BE (t->data + 4, 16);
1520 for (i = 0; i < self->n_packages; i++) {
1521 if (!self->packages[i])
1522 continue;
1523
1524 memcpy (t->data + 8 + i * 16,
1525 &MXF_METADATA_BASE (self->packages[i])->instance_uid, 16);
1526 }
1527
1528 mxf_primer_pack_add_mapping (primer, 0x1901, &t->ul);
1529 ret = g_list_prepend (ret, t);
1530 }
1531
1532 if (self->essence_container_data) {
1533 t = g_slice_new0 (MXFLocalTag);
1534 memcpy (&t->ul, MXF_UL (ESSENCE_CONTAINER_DATA), 16);
1535 t->size = 8 + 16 * self->n_essence_container_data;
1536 t->data = g_slice_alloc0 (t->size);
1537 t->g_slice = TRUE;
1538 GST_WRITE_UINT32_BE (t->data, self->n_essence_container_data);
1539 GST_WRITE_UINT32_BE (t->data + 4, 16);
1540 for (i = 0; i < self->n_essence_container_data; i++) {
1541 if (!self->essence_container_data[i])
1542 continue;
1543
1544 memcpy (t->data + 8 + i * 16,
1545 &MXF_METADATA_BASE (self->essence_container_data[i])->instance_uid,
1546 16);
1547 }
1548
1549 mxf_primer_pack_add_mapping (primer, 0x1902, &t->ul);
1550 ret = g_list_prepend (ret, t);
1551 }
1552
1553 return ret;
1554 }
1555
1556 static void
mxf_metadata_content_storage_init(MXFMetadataContentStorage * self)1557 mxf_metadata_content_storage_init (MXFMetadataContentStorage * self)
1558 {
1559
1560 }
1561
1562 static void
mxf_metadata_content_storage_class_init(MXFMetadataContentStorageClass * klass)1563 mxf_metadata_content_storage_class_init (MXFMetadataContentStorageClass * klass)
1564 {
1565 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
1566 GObjectClass *object_class = (GObjectClass *) klass;
1567 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
1568
1569 object_class->finalize = mxf_metadata_content_storage_finalize;
1570 metadata_base_class->handle_tag = mxf_metadata_content_storage_handle_tag;
1571 metadata_base_class->resolve = mxf_metadata_content_storage_resolve;
1572 metadata_base_class->name_quark = MXF_QUARK (CONTENT_STORAGE);
1573 metadata_base_class->to_structure = mxf_metadata_content_storage_to_structure;
1574 metadata_base_class->write_tags = mxf_metadata_content_storage_write_tags;
1575 metadata_class->type = 0x0118;
1576 }
1577
1578 G_DEFINE_TYPE (MXFMetadataEssenceContainerData,
1579 mxf_metadata_essence_container_data, MXF_TYPE_METADATA);
1580
1581 static gboolean
mxf_metadata_essence_container_data_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)1582 mxf_metadata_essence_container_data_handle_tag (MXFMetadataBase * metadata,
1583 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
1584 guint tag_size)
1585 {
1586 MXFMetadataEssenceContainerData *self =
1587 MXF_METADATA_ESSENCE_CONTAINER_DATA (metadata);
1588 gboolean ret = TRUE;
1589 #ifndef GST_DISABLE_GST_DEBUG
1590 gchar str[96];
1591 #endif
1592
1593 switch (tag) {
1594 case 0x2701:
1595 if (tag_size != 32)
1596 goto error;
1597 memcpy (&self->linked_package_uid, tag_data, 32);
1598 GST_DEBUG (" linked package = %s",
1599 mxf_umid_to_string (&self->linked_package_uid, str));
1600 break;
1601 case 0x3f06:
1602 if (tag_size != 4)
1603 goto error;
1604 self->index_sid = GST_READ_UINT32_BE (tag_data);
1605 GST_DEBUG (" index sid = %u", self->index_sid);
1606 break;
1607 case 0x3f07:
1608 if (tag_size != 4)
1609 goto error;
1610 self->body_sid = GST_READ_UINT32_BE (tag_data);
1611 GST_DEBUG (" body sid = %u", self->body_sid);
1612 break;
1613 default:
1614 ret =
1615 MXF_METADATA_BASE_CLASS
1616 (mxf_metadata_essence_container_data_parent_class)->handle_tag
1617 (metadata, primer, tag, tag_data, tag_size);
1618 break;
1619 }
1620
1621 return ret;
1622
1623 error:
1624
1625 GST_ERROR ("Invalid essence container data local tag 0x%04x of size %u", tag,
1626 tag_size);
1627
1628 return FALSE;
1629 }
1630
1631 static gboolean
mxf_metadata_essence_container_data_resolve(MXFMetadataBase * m,GHashTable * metadata)1632 mxf_metadata_essence_container_data_resolve (MXFMetadataBase * m,
1633 GHashTable * metadata)
1634 {
1635 MXFMetadataEssenceContainerData *self =
1636 MXF_METADATA_ESSENCE_CONTAINER_DATA (m);
1637 MXFMetadataBase *current = NULL;
1638 GHashTableIter iter;
1639 #ifndef GST_DISABLE_GST_DEBUG
1640 gchar str[96];
1641 #endif
1642
1643 g_hash_table_iter_init (&iter, metadata);
1644
1645 while (g_hash_table_iter_next (&iter, NULL, (gpointer) & current)) {
1646 if (MXF_IS_METADATA_SOURCE_PACKAGE (current)) {
1647 MXFMetadataSourcePackage *package = MXF_METADATA_SOURCE_PACKAGE (current);
1648
1649 if (mxf_umid_is_equal (&package->parent.package_uid,
1650 &self->linked_package_uid)) {
1651 if (mxf_metadata_base_resolve (current, metadata)) {
1652 self->linked_package = package;
1653 } else {
1654 GST_ERROR ("Couldn't resolve linked package %s",
1655 mxf_umid_to_string (&self->linked_package_uid, str));
1656 }
1657 break;
1658 }
1659 }
1660 }
1661
1662 if (!self->linked_package) {
1663 GST_ERROR ("Couldn't resolve or find linked package %s",
1664 mxf_umid_to_string (&self->linked_package_uid, str));
1665 return FALSE;
1666 }
1667
1668 return
1669 MXF_METADATA_BASE_CLASS
1670 (mxf_metadata_essence_container_data_parent_class)->resolve (m, metadata);
1671 }
1672
1673 static GstStructure *
mxf_metadata_essence_container_data_to_structure(MXFMetadataBase * m)1674 mxf_metadata_essence_container_data_to_structure (MXFMetadataBase * m)
1675 {
1676 GstStructure *ret =
1677 MXF_METADATA_BASE_CLASS
1678 (mxf_metadata_essence_container_data_parent_class)->to_structure (m);
1679 MXFMetadataEssenceContainerData *self =
1680 MXF_METADATA_ESSENCE_CONTAINER_DATA (m);
1681 gchar str[96];
1682
1683 if (!mxf_umid_is_zero (&self->linked_package_uid)) {
1684 mxf_umid_to_string (&self->linked_package_uid, str);
1685 gst_structure_id_set (ret, MXF_QUARK (LINKED_PACKAGE), G_TYPE_STRING, str,
1686 NULL);
1687 }
1688
1689 gst_structure_id_set (ret, MXF_QUARK (INDEX_SID), G_TYPE_UINT,
1690 self->index_sid, MXF_QUARK (BODY_SID), G_TYPE_UINT, self->body_sid, NULL);
1691
1692
1693 return ret;
1694 }
1695
1696 static GList *
mxf_metadata_essence_container_data_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)1697 mxf_metadata_essence_container_data_write_tags (MXFMetadataBase * m,
1698 MXFPrimerPack * primer)
1699 {
1700 MXFMetadataEssenceContainerData *self =
1701 MXF_METADATA_ESSENCE_CONTAINER_DATA (m);
1702 GList *ret =
1703 MXF_METADATA_BASE_CLASS
1704 (mxf_metadata_essence_container_data_parent_class)->write_tags (m,
1705 primer);
1706 MXFLocalTag *t;
1707
1708 t = g_slice_new0 (MXFLocalTag);
1709 memcpy (&t->ul, MXF_UL (LINKED_PACKAGE_UID), 16);
1710 t->size = 32;
1711 t->data = g_slice_alloc0 (32);
1712 t->g_slice = TRUE;
1713 if (self->linked_package)
1714 memcpy (t->data, &self->linked_package->parent.package_uid, 32);
1715 mxf_primer_pack_add_mapping (primer, 0x2701, &t->ul);
1716 ret = g_list_prepend (ret, t);
1717
1718 t = g_slice_new0 (MXFLocalTag);
1719 memcpy (&t->ul, MXF_UL (BODY_SID), 16);
1720 t->size = 4;
1721 t->data = g_slice_alloc (4);
1722 t->g_slice = TRUE;
1723 GST_WRITE_UINT32_BE (t->data, self->body_sid);
1724 mxf_primer_pack_add_mapping (primer, 0x3f07, &t->ul);
1725 ret = g_list_prepend (ret, t);
1726
1727 if (self->index_sid) {
1728 t = g_slice_new0 (MXFLocalTag);
1729 memcpy (&t->ul, MXF_UL (INDEX_SID), 16);
1730 t->size = 4;
1731 t->data = g_slice_alloc (4);
1732 t->g_slice = TRUE;
1733 GST_WRITE_UINT32_BE (t->data, self->index_sid);
1734 mxf_primer_pack_add_mapping (primer, 0x3f06, &t->ul);
1735 ret = g_list_prepend (ret, t);
1736 }
1737
1738 return ret;
1739 }
1740
1741 static void
mxf_metadata_essence_container_data_init(MXFMetadataEssenceContainerData * self)1742 mxf_metadata_essence_container_data_init (MXFMetadataEssenceContainerData *
1743 self)
1744 {
1745
1746 }
1747
1748 static void
mxf_metadata_essence_container_data_class_init(MXFMetadataEssenceContainerDataClass * klass)1749 mxf_metadata_essence_container_data_class_init
1750 (MXFMetadataEssenceContainerDataClass * klass)
1751 {
1752 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
1753 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
1754
1755 metadata_base_class->handle_tag =
1756 mxf_metadata_essence_container_data_handle_tag;
1757 metadata_base_class->resolve = mxf_metadata_essence_container_data_resolve;
1758 metadata_base_class->name_quark = MXF_QUARK (ESSENCE_CONTAINER_DATA);
1759 metadata_base_class->to_structure =
1760 mxf_metadata_essence_container_data_to_structure;
1761 metadata_base_class->write_tags =
1762 mxf_metadata_essence_container_data_write_tags;
1763 metadata_class->type = 0x0123;
1764 }
1765
1766 G_DEFINE_ABSTRACT_TYPE (MXFMetadataGenericPackage, mxf_metadata_generic_package,
1767 MXF_TYPE_METADATA);
1768
1769 static void
mxf_metadata_generic_package_finalize(GObject * object)1770 mxf_metadata_generic_package_finalize (GObject * object)
1771 {
1772 MXFMetadataGenericPackage *self = MXF_METADATA_GENERIC_PACKAGE (object);
1773
1774 g_free (self->name);
1775 self->name = NULL;
1776 g_free (self->tracks_uids);
1777 self->tracks_uids = NULL;
1778
1779 g_free (self->tracks);
1780 self->tracks = NULL;
1781
1782 G_OBJECT_CLASS (mxf_metadata_generic_package_parent_class)->finalize (object);
1783 }
1784
1785 static gboolean
mxf_metadata_generic_package_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)1786 mxf_metadata_generic_package_handle_tag (MXFMetadataBase * metadata,
1787 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
1788 guint tag_size)
1789 {
1790 MXFMetadataGenericPackage *self = MXF_METADATA_GENERIC_PACKAGE (metadata);
1791 gboolean ret = TRUE;
1792 #ifndef GST_DISABLE_GST_DEBUG
1793 gchar str[96];
1794 #endif
1795
1796 switch (tag) {
1797 case 0x4401:
1798 if (tag_size != 32)
1799 goto error;
1800 memcpy (&self->package_uid, tag_data, 32);
1801 GST_DEBUG (" UMID = %s", mxf_umid_to_string (&self->package_uid, str));
1802 break;
1803 case 0x4402:
1804 self->name = mxf_utf16_to_utf8 (tag_data, tag_size);
1805 GST_DEBUG (" name = %s", GST_STR_NULL (self->name));
1806 break;
1807 case 0x4405:
1808 if (!mxf_timestamp_parse (&self->package_creation_date,
1809 tag_data, tag_size))
1810 goto error;
1811 GST_DEBUG (" creation date = %s",
1812 mxf_timestamp_to_string (&self->package_creation_date, str));
1813 break;
1814 case 0x4404:
1815 if (!mxf_timestamp_parse (&self->package_modified_date,
1816 tag_data, tag_size))
1817 goto error;
1818 GST_DEBUG (" modification date = %s",
1819 mxf_timestamp_to_string (&self->package_modified_date, str));
1820 break;
1821 case 0x4403:
1822 if (!mxf_uuid_array_parse (&self->tracks_uids, &self->n_tracks, tag_data,
1823 tag_size))
1824 goto error;
1825
1826 GST_DEBUG (" number of tracks = %u", self->n_tracks);
1827 #ifndef GST_DISABLE_GST_DEBUG
1828 {
1829 guint i;
1830 for (i = 0; i < self->n_tracks; i++) {
1831 GST_DEBUG (" track %u = %s", i,
1832 mxf_uuid_to_string (&self->tracks_uids[i], str));
1833 }
1834 }
1835 #endif
1836 break;
1837 default:
1838 ret =
1839 MXF_METADATA_BASE_CLASS
1840 (mxf_metadata_generic_package_parent_class)->handle_tag (metadata,
1841 primer, tag, tag_data, tag_size);
1842 break;
1843 }
1844
1845 return ret;
1846
1847 error:
1848
1849 GST_ERROR ("Invalid generic package local tag 0x%04x of size %u", tag,
1850 tag_size);
1851
1852 return FALSE;
1853 }
1854
1855 static gboolean
mxf_metadata_generic_package_resolve(MXFMetadataBase * m,GHashTable * metadata)1856 mxf_metadata_generic_package_resolve (MXFMetadataBase * m,
1857 GHashTable * metadata)
1858 {
1859 MXFMetadataGenericPackage *self = MXF_METADATA_GENERIC_PACKAGE (m);
1860 MXFMetadataBase *current = NULL;
1861 guint i;
1862 gboolean have_track = FALSE;
1863 #ifndef GST_DISABLE_GST_DEBUG
1864 gchar str[48];
1865 #endif
1866
1867 if (self->tracks)
1868 memset (self->tracks, 0, sizeof (gpointer) * self->n_tracks);
1869 else
1870 self->tracks = g_new0 (MXFMetadataTrack *, self->n_tracks);
1871 for (i = 0; i < self->n_tracks; i++) {
1872 current = g_hash_table_lookup (metadata, &self->tracks_uids[i]);
1873 if (current && MXF_IS_METADATA_TRACK (current)) {
1874 if (mxf_metadata_base_resolve (current, metadata)) {
1875 MXFMetadataTrack *track = MXF_METADATA_TRACK (current);
1876
1877 self->tracks[i] = track;
1878 have_track = TRUE;
1879 if ((track->type & 0xf0) == 0x10)
1880 self->n_timecode_tracks++;
1881 else if ((track->type & 0xf0) == 0x20)
1882 self->n_metadata_tracks++;
1883 else if ((track->type & 0xf0) == 0x30)
1884 self->n_essence_tracks++;
1885 else if ((track->type & 0xf0) == 0x40)
1886 self->n_other_tracks++;
1887 } else {
1888 GST_ERROR ("Track %s couldn't be resolved",
1889 mxf_uuid_to_string (&self->tracks_uids[i], str));
1890 }
1891 } else {
1892 GST_ERROR ("Track %s not found",
1893 mxf_uuid_to_string (&self->tracks_uids[i], str));
1894 }
1895 }
1896
1897 if (!have_track) {
1898 GST_ERROR ("Couldn't resolve a track");
1899 return FALSE;
1900 }
1901
1902 return
1903 MXF_METADATA_BASE_CLASS
1904 (mxf_metadata_generic_package_parent_class)->resolve (m, metadata);
1905 }
1906
1907 static GstStructure *
mxf_metadata_generic_package_to_structure(MXFMetadataBase * m)1908 mxf_metadata_generic_package_to_structure (MXFMetadataBase * m)
1909 {
1910 GstStructure *ret =
1911 MXF_METADATA_BASE_CLASS
1912 (mxf_metadata_generic_package_parent_class)->to_structure (m);
1913 MXFMetadataGenericPackage *self = MXF_METADATA_GENERIC_PACKAGE (m);
1914 guint i;
1915 gchar str[96];
1916
1917 mxf_umid_to_string (&self->package_uid, str);
1918 gst_structure_id_set (ret, MXF_QUARK (PACKAGE_UID), G_TYPE_STRING, str, NULL);
1919
1920 if (self->name)
1921 gst_structure_id_set (ret, MXF_QUARK (NAME), G_TYPE_STRING, self->name,
1922 NULL);
1923
1924 if (!mxf_timestamp_is_unknown (&self->package_creation_date)) {
1925 mxf_timestamp_to_string (&self->package_creation_date, str);
1926 gst_structure_id_set (ret, MXF_QUARK (PACKAGE_CREATION_DATE), G_TYPE_STRING,
1927 str, NULL);
1928 }
1929
1930 if (!mxf_timestamp_is_unknown (&self->package_modified_date)) {
1931 mxf_timestamp_to_string (&self->package_modified_date, str);
1932 gst_structure_id_set (ret, MXF_QUARK (PACKAGE_MODIFIED_DATE), G_TYPE_STRING,
1933 str, NULL);
1934 }
1935
1936 if (self->n_tracks > 0) {
1937 GValue arr = { 0, }
1938 , val = {
1939 0,};
1940
1941 g_value_init (&arr, GST_TYPE_ARRAY);
1942
1943 for (i = 0; i < self->n_tracks; i++) {
1944 GstStructure *s;
1945
1946 if (self->tracks[i] == NULL)
1947 continue;
1948
1949 g_value_init (&val, GST_TYPE_STRUCTURE);
1950
1951 s = mxf_metadata_base_to_structure (MXF_METADATA_BASE (self->tracks[i]));
1952 gst_value_set_structure (&val, s);
1953 gst_structure_free (s);
1954 gst_value_array_append_value (&arr, &val);
1955 g_value_unset (&val);
1956 }
1957
1958 if (gst_value_array_get_size (&arr) > 0)
1959 gst_structure_id_set_value (ret, MXF_QUARK (TRACKS), &arr);
1960
1961 g_value_unset (&arr);
1962 }
1963
1964 return ret;
1965 }
1966
1967 static GList *
mxf_metadata_generic_package_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)1968 mxf_metadata_generic_package_write_tags (MXFMetadataBase * m,
1969 MXFPrimerPack * primer)
1970 {
1971 MXFMetadataGenericPackage *self = MXF_METADATA_GENERIC_PACKAGE (m);
1972 GList *ret =
1973 MXF_METADATA_BASE_CLASS
1974 (mxf_metadata_generic_package_parent_class)->write_tags (m, primer);
1975 MXFLocalTag *t;
1976
1977 t = g_slice_new0 (MXFLocalTag);
1978 memcpy (&t->ul, MXF_UL (PACKAGE_UID), 16);
1979 t->size = 32;
1980 t->data = g_slice_alloc (t->size);
1981 t->g_slice = TRUE;
1982 memcpy (t->data, &self->package_uid, 32);
1983 mxf_primer_pack_add_mapping (primer, 0x4401, &t->ul);
1984 ret = g_list_prepend (ret, t);
1985
1986 if (self->name) {
1987 t = g_slice_new0 (MXFLocalTag);
1988 memcpy (&t->ul, MXF_UL (PACKAGE_NAME), 16);
1989 t->data = mxf_utf8_to_utf16 (self->name, &t->size);
1990 mxf_primer_pack_add_mapping (primer, 0x4402, &t->ul);
1991 ret = g_list_prepend (ret, t);
1992 }
1993
1994 t = g_slice_new0 (MXFLocalTag);
1995 memcpy (&t->ul, MXF_UL (PACKAGE_CREATION_DATE), 16);
1996 t->size = 8;
1997 t->data = g_slice_alloc (t->size);
1998 t->g_slice = TRUE;
1999 mxf_timestamp_write (&self->package_creation_date, t->data);
2000 mxf_primer_pack_add_mapping (primer, 0x4405, &t->ul);
2001 ret = g_list_prepend (ret, t);
2002
2003 t = g_slice_new0 (MXFLocalTag);
2004 memcpy (&t->ul, MXF_UL (PACKAGE_MODIFIED_DATE), 16);
2005 t->size = 8;
2006 t->data = g_slice_alloc (t->size);
2007 t->g_slice = TRUE;
2008 mxf_timestamp_write (&self->package_modified_date, t->data);
2009 mxf_primer_pack_add_mapping (primer, 0x4404, &t->ul);
2010 ret = g_list_prepend (ret, t);
2011
2012 if (self->tracks) {
2013 guint i;
2014
2015 t = g_slice_new0 (MXFLocalTag);
2016 memcpy (&t->ul, MXF_UL (TRACKS), 16);
2017 t->size = 8 + 16 * self->n_tracks;
2018 t->data = g_slice_alloc0 (t->size);
2019 t->g_slice = TRUE;
2020 GST_WRITE_UINT32_BE (t->data, self->n_tracks);
2021 GST_WRITE_UINT32_BE (t->data + 4, 16);
2022 for (i = 0; i < self->n_tracks; i++) {
2023 if (!self->tracks[i])
2024 continue;
2025
2026 memcpy (t->data + 8 + 16 * i,
2027 &MXF_METADATA_BASE (self->tracks[i])->instance_uid, 16);
2028 }
2029 mxf_primer_pack_add_mapping (primer, 0x4403, &t->ul);
2030 ret = g_list_prepend (ret, t);
2031 }
2032
2033 return ret;
2034 }
2035
2036 static void
mxf_metadata_generic_package_init(MXFMetadataGenericPackage * self)2037 mxf_metadata_generic_package_init (MXFMetadataGenericPackage * self)
2038 {
2039
2040 }
2041
2042 static void
mxf_metadata_generic_package_class_init(MXFMetadataGenericPackageClass * klass)2043 mxf_metadata_generic_package_class_init (MXFMetadataGenericPackageClass * klass)
2044 {
2045 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
2046 GObjectClass *object_class = (GObjectClass *) klass;
2047
2048 object_class->finalize = mxf_metadata_generic_package_finalize;
2049 metadata_base_class->handle_tag = mxf_metadata_generic_package_handle_tag;
2050 metadata_base_class->resolve = mxf_metadata_generic_package_resolve;
2051 metadata_base_class->to_structure = mxf_metadata_generic_package_to_structure;
2052 metadata_base_class->write_tags = mxf_metadata_generic_package_write_tags;
2053 }
2054
2055 G_DEFINE_TYPE (MXFMetadataMaterialPackage, mxf_metadata_material_package,
2056 MXF_TYPE_METADATA_GENERIC_PACKAGE);
2057
2058 static gboolean
mxf_metadata_material_package_resolve(MXFMetadataBase * m,GHashTable * metadata)2059 mxf_metadata_material_package_resolve (MXFMetadataBase * m,
2060 GHashTable * metadata)
2061 {
2062 gboolean ret =
2063 MXF_METADATA_BASE_CLASS
2064 (mxf_metadata_material_package_parent_class)->resolve (m, metadata);
2065 MXFMetadataGenericPackage *self = MXF_METADATA_GENERIC_PACKAGE (m);
2066 guint i;
2067 guint ntracks = 0;
2068
2069 if (!ret)
2070 return ret;
2071
2072 for (i = 0; i < self->n_tracks; i++) {
2073 MXFMetadataTrack *track = self->tracks[i];
2074 MXFMetadataSequence *sequence;
2075 guint j;
2076
2077 if (!track)
2078 continue;
2079
2080 sequence = track->sequence;
2081
2082 if (!sequence || !sequence->structural_components)
2083 continue;
2084
2085 for (j = 0; j < sequence->n_structural_components; j++) {
2086 MXFMetadataSourceClip *sc;
2087 MXFMetadataTimelineTrack *st = NULL;
2088 guint k;
2089
2090 if (!sequence->structural_components[j]
2091 || !MXF_IS_METADATA_SOURCE_CLIP (sequence->structural_components[j]))
2092 continue;
2093
2094 sc = MXF_METADATA_SOURCE_CLIP (sequence->structural_components[j]);
2095
2096 if (!sc->source_package) {
2097 GST_ERROR ("Material package track %u without resolved source package",
2098 i);
2099 track = NULL;
2100 break;
2101 }
2102
2103 if (!mxf_metadata_base_resolve (MXF_METADATA_BASE (sc->source_package),
2104 metadata)) {
2105 GST_ERROR ("Couldn't resolve source package for track %u", i);
2106 track = NULL;
2107 break;
2108 }
2109
2110 sc->source_package->top_level = TRUE;
2111 for (k = 0; k < sc->source_package->parent.n_tracks; k++) {
2112 MXFMetadataTimelineTrack *tmp;
2113
2114 if (!sc->source_package->parent.tracks[k] ||
2115 !MXF_IS_METADATA_TIMELINE_TRACK (sc->source_package->parent.
2116 tracks[k]))
2117 continue;
2118
2119 tmp =
2120 MXF_METADATA_TIMELINE_TRACK (sc->source_package->parent.tracks[k]);
2121 if (tmp->parent.track_id == sc->source_track_id) {
2122 st = tmp;
2123 break;
2124 }
2125 }
2126
2127 if (!st) {
2128 GST_ERROR ("Material package track %u without resolved source track",
2129 i);
2130 track = NULL;
2131 }
2132 }
2133
2134 if (track)
2135 ntracks++;
2136 else
2137 self->tracks[i] = NULL;
2138 }
2139
2140 if (ntracks == 0) {
2141 GST_ERROR ("No tracks could be resolved");
2142 return FALSE;
2143 } else if (ntracks != self->n_tracks) {
2144 GST_WARNING ("Not all tracks could be resolved");
2145 }
2146
2147 return TRUE;
2148 }
2149
2150 static void
mxf_metadata_material_package_init(MXFMetadataMaterialPackage * self)2151 mxf_metadata_material_package_init (MXFMetadataMaterialPackage * self)
2152 {
2153 }
2154
2155 static void
mxf_metadata_material_package_class_init(MXFMetadataMaterialPackageClass * klass)2156 mxf_metadata_material_package_class_init (MXFMetadataMaterialPackageClass *
2157 klass)
2158 {
2159 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
2160 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
2161
2162 metadata_base_class->resolve = mxf_metadata_material_package_resolve;
2163 metadata_base_class->name_quark = MXF_QUARK (MATERIAL_PACKAGE);
2164 metadata_class->type = 0x0136;
2165 }
2166
2167 G_DEFINE_TYPE (MXFMetadataSourcePackage, mxf_metadata_source_package,
2168 MXF_TYPE_METADATA_GENERIC_PACKAGE);
2169
2170 static gboolean
mxf_metadata_source_package_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)2171 mxf_metadata_source_package_handle_tag (MXFMetadataBase * metadata,
2172 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
2173 guint tag_size)
2174 {
2175 MXFMetadataSourcePackage *self = MXF_METADATA_SOURCE_PACKAGE (metadata);
2176 gboolean ret = TRUE;
2177 #ifndef GST_DISABLE_GST_DEBUG
2178 gchar str[48];
2179 #endif
2180
2181 switch (tag) {
2182 case 0x4701:
2183 if (tag_size != 16)
2184 goto error;
2185
2186 memcpy (&self->descriptor_uid, tag_data, 16);
2187 GST_DEBUG (" descriptor = %s",
2188 mxf_uuid_to_string (&self->descriptor_uid, str));
2189 break;
2190 default:
2191 ret =
2192 MXF_METADATA_BASE_CLASS
2193 (mxf_metadata_source_package_parent_class)->handle_tag (metadata,
2194 primer, tag, tag_data, tag_size);
2195 break;
2196 }
2197
2198 return ret;
2199
2200 error:
2201
2202 GST_ERROR ("Invalid source package local tag 0x%04x of size %u", tag,
2203 tag_size);
2204
2205 return FALSE;
2206 }
2207
2208 static gboolean
mxf_metadata_source_package_resolve(MXFMetadataBase * m,GHashTable * metadata)2209 mxf_metadata_source_package_resolve (MXFMetadataBase * m, GHashTable * metadata)
2210 {
2211 MXFMetadataSourcePackage *self = MXF_METADATA_SOURCE_PACKAGE (m);
2212 MXFMetadataGenericPackage *package = MXF_METADATA_GENERIC_PACKAGE (m);
2213 MXFMetadataBase *current = NULL;
2214 guint i;
2215 gboolean ret;
2216 MXFMetadataFileDescriptor *d;
2217 #ifndef GST_DISABLE_GST_DEBUG
2218 gchar str[48];
2219 #endif
2220
2221 if (mxf_uuid_is_zero (&self->descriptor_uid))
2222 return
2223 MXF_METADATA_BASE_CLASS
2224 (mxf_metadata_source_package_parent_class)->resolve (m, metadata);
2225
2226 current = g_hash_table_lookup (metadata, &self->descriptor_uid);
2227 if (!current) {
2228 GST_ERROR ("Descriptor %s not found",
2229 mxf_uuid_to_string (&self->descriptor_uid, str));
2230 return FALSE;
2231 }
2232
2233 if (!mxf_metadata_base_resolve (MXF_METADATA_BASE (current), metadata)) {
2234 GST_ERROR ("Couldn't resolve descriptor %s",
2235 mxf_uuid_to_string (&self->descriptor_uid, str));
2236 return FALSE;
2237 }
2238
2239 self->descriptor = MXF_METADATA_GENERIC_DESCRIPTOR (current);
2240
2241 ret =
2242 MXF_METADATA_BASE_CLASS
2243 (mxf_metadata_source_package_parent_class)->resolve (m, metadata);
2244
2245 if (!MXF_IS_METADATA_FILE_DESCRIPTOR (self->descriptor))
2246 return ret;
2247
2248 d = MXF_METADATA_FILE_DESCRIPTOR (current);
2249
2250 for (i = 0; i < package->n_tracks; i++) {
2251 if (!package->tracks[i])
2252 continue;
2253
2254 if (!MXF_IS_METADATA_MULTIPLE_DESCRIPTOR (d)) {
2255 if (d->linked_track_id == package->tracks[i]->track_id ||
2256 (d->linked_track_id == 0 && package->n_essence_tracks == 1 &&
2257 (package->tracks[i]->type & 0xf0) == 0x30)) {
2258 g_free (package->tracks[i]->descriptor);
2259 package->tracks[i]->descriptor =
2260 g_new0 (MXFMetadataFileDescriptor *, 1);
2261 package->tracks[i]->descriptor[0] = d;
2262 package->tracks[i]->n_descriptor = 1;
2263 break;
2264 }
2265 } else {
2266 guint n_descriptor = 0, j, k = 0;
2267 MXFMetadataMultipleDescriptor *md = MXF_METADATA_MULTIPLE_DESCRIPTOR (d);
2268
2269 for (j = 0; j < md->n_sub_descriptors; j++) {
2270 MXFMetadataFileDescriptor *fd;
2271
2272 if (!md->sub_descriptors[j] ||
2273 !MXF_METADATA_FILE_DESCRIPTOR (md->sub_descriptors[j]))
2274 continue;
2275
2276 fd = MXF_METADATA_FILE_DESCRIPTOR (md->sub_descriptors[j]);
2277
2278 if (fd->linked_track_id == package->tracks[i]->track_id ||
2279 (fd->linked_track_id == 0 && package->n_essence_tracks == 1 &&
2280 (package->tracks[i]->type & 0xf0) == 0x30))
2281 n_descriptor++;
2282 }
2283
2284 g_free (package->tracks[i]->descriptor);
2285 package->tracks[i]->descriptor =
2286 g_new0 (MXFMetadataFileDescriptor *, n_descriptor);
2287 package->tracks[i]->n_descriptor = n_descriptor;
2288
2289 for (j = 0; j < md->n_sub_descriptors; j++) {
2290 MXFMetadataFileDescriptor *fd;
2291
2292 if (!md->sub_descriptors[j] ||
2293 !MXF_METADATA_FILE_DESCRIPTOR (md->sub_descriptors[j]))
2294 continue;
2295
2296 fd = MXF_METADATA_FILE_DESCRIPTOR (md->sub_descriptors[j]);
2297
2298 if (fd->linked_track_id == package->tracks[i]->track_id ||
2299 (fd->linked_track_id == 0 && package->n_essence_tracks == 1 &&
2300 (package->tracks[i]->type & 0xf0) == 0x30)) {
2301 package->tracks[i]->descriptor[k] = fd;
2302 k++;
2303 }
2304 }
2305 }
2306 }
2307
2308 return ret;
2309 }
2310
2311 static GstStructure *
mxf_metadata_source_package_to_structure(MXFMetadataBase * m)2312 mxf_metadata_source_package_to_structure (MXFMetadataBase * m)
2313 {
2314 GstStructure *ret =
2315 MXF_METADATA_BASE_CLASS
2316 (mxf_metadata_source_package_parent_class)->to_structure (m);
2317 MXFMetadataSourcePackage *self = MXF_METADATA_SOURCE_PACKAGE (m);
2318 GstStructure *s;
2319
2320 if (!self->descriptor)
2321 return ret;
2322
2323 s = mxf_metadata_base_to_structure (MXF_METADATA_BASE (self->descriptor));
2324 gst_structure_id_set (ret, MXF_QUARK (DESCRIPTOR), GST_TYPE_STRUCTURE, s,
2325 NULL);
2326 gst_structure_free (s);
2327
2328 return ret;
2329 }
2330
2331 static GList *
mxf_metadata_source_package_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)2332 mxf_metadata_source_package_write_tags (MXFMetadataBase * m,
2333 MXFPrimerPack * primer)
2334 {
2335 MXFMetadataSourcePackage *self = MXF_METADATA_SOURCE_PACKAGE (m);
2336 GList *ret =
2337 MXF_METADATA_BASE_CLASS
2338 (mxf_metadata_source_package_parent_class)->write_tags (m, primer);
2339 MXFLocalTag *t;
2340
2341 if (self->descriptor) {
2342 t = g_slice_new0 (MXFLocalTag);
2343 memcpy (&t->ul, MXF_UL (DESCRIPTOR), 16);
2344 t->size = 16;
2345 t->data = g_slice_alloc (t->size);
2346 t->g_slice = TRUE;
2347 memcpy (t->data, &MXF_METADATA_BASE (self->descriptor)->instance_uid, 16);
2348 mxf_primer_pack_add_mapping (primer, 0x4701, &t->ul);
2349 ret = g_list_prepend (ret, t);
2350 }
2351
2352 return ret;
2353 }
2354
2355 static void
mxf_metadata_source_package_init(MXFMetadataSourcePackage * self)2356 mxf_metadata_source_package_init (MXFMetadataSourcePackage * self)
2357 {
2358
2359 }
2360
2361 static void
mxf_metadata_source_package_class_init(MXFMetadataSourcePackageClass * klass)2362 mxf_metadata_source_package_class_init (MXFMetadataSourcePackageClass * klass)
2363 {
2364 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
2365 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
2366
2367 metadata_base_class->handle_tag = mxf_metadata_source_package_handle_tag;
2368 metadata_base_class->resolve = mxf_metadata_source_package_resolve;
2369 metadata_base_class->name_quark = MXF_QUARK (SOURCE_PACKAGE);
2370 metadata_base_class->to_structure = mxf_metadata_source_package_to_structure;
2371 metadata_base_class->write_tags = mxf_metadata_source_package_write_tags;
2372 metadata_class->type = 0x0137;
2373 }
2374
2375 G_DEFINE_ABSTRACT_TYPE (MXFMetadataTrack, mxf_metadata_track,
2376 MXF_TYPE_METADATA);
2377
2378 static void
mxf_metadata_track_finalize(GObject * object)2379 mxf_metadata_track_finalize (GObject * object)
2380 {
2381 MXFMetadataTrack *self = MXF_METADATA_TRACK (object);
2382
2383 g_free (self->track_name);
2384 self->track_name = NULL;
2385 g_free (self->descriptor);
2386 self->descriptor = NULL;
2387
2388 G_OBJECT_CLASS (mxf_metadata_track_parent_class)->finalize (object);
2389 }
2390
2391 static gboolean
mxf_metadata_track_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)2392 mxf_metadata_track_handle_tag (MXFMetadataBase * metadata,
2393 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
2394 guint tag_size)
2395 {
2396 MXFMetadataTrack *self = MXF_METADATA_TRACK (metadata);
2397 gboolean ret = TRUE;
2398 #ifndef GST_DISABLE_GST_DEBUG
2399 gchar str[48];
2400 #endif
2401
2402 switch (tag) {
2403 case 0x4801:
2404 if (tag_size != 4)
2405 goto error;
2406 self->track_id = GST_READ_UINT32_BE (tag_data);
2407 GST_DEBUG (" track id = %u", self->track_id);
2408 break;
2409 case 0x4804:
2410 if (tag_size != 4)
2411 goto error;
2412 self->track_number = GST_READ_UINT32_BE (tag_data);
2413 GST_DEBUG (" track number = %u", self->track_number);
2414 break;
2415 case 0x4802:
2416 self->track_name = mxf_utf16_to_utf8 (tag_data, tag_size);
2417 GST_DEBUG (" track name = %s", GST_STR_NULL (self->track_name));
2418 break;
2419 case 0x4803:
2420 if (tag_size != 16)
2421 goto error;
2422 memcpy (&self->sequence_uid, tag_data, 16);
2423 GST_DEBUG (" sequence uid = %s",
2424 mxf_uuid_to_string (&self->sequence_uid, str));
2425 break;
2426 default:
2427 ret =
2428 MXF_METADATA_BASE_CLASS (mxf_metadata_track_parent_class)->handle_tag
2429 (metadata, primer, tag, tag_data, tag_size);
2430 break;
2431 }
2432
2433 return ret;
2434
2435 error:
2436
2437 GST_ERROR ("Invalid track local tag 0x%04x of size %u", tag, tag_size);
2438
2439 return FALSE;
2440 }
2441
2442 static gboolean
mxf_metadata_track_resolve(MXFMetadataBase * m,GHashTable * metadata)2443 mxf_metadata_track_resolve (MXFMetadataBase * m, GHashTable * metadata)
2444 {
2445 MXFMetadataTrack *self = MXF_METADATA_TRACK (m);
2446 MXFMetadataBase *current = NULL;
2447 guint i;
2448 #ifndef GST_DISABLE_GST_DEBUG
2449 gchar str[48];
2450 #endif
2451
2452 current = g_hash_table_lookup (metadata, &self->sequence_uid);
2453 if (current && MXF_IS_METADATA_SEQUENCE (current)) {
2454 if (mxf_metadata_base_resolve (current, metadata)) {
2455 self->sequence = MXF_METADATA_SEQUENCE (current);
2456 } else {
2457 GST_ERROR ("Couldn't resolve sequence %s",
2458 mxf_uuid_to_string (&self->sequence_uid, str));
2459 return FALSE;
2460 }
2461 } else {
2462 GST_ERROR ("Couldn't find sequence %s",
2463 mxf_uuid_to_string (&self->sequence_uid, str));
2464 return FALSE;
2465 }
2466
2467 self->type =
2468 mxf_metadata_track_identifier_parse (&self->sequence->data_definition);
2469 if (self->type == MXF_METADATA_TRACK_UNKNOWN) {
2470 MXFMetadataSequence *sequence = self->sequence;
2471
2472 for (i = 0; i < sequence->n_structural_components; i++) {
2473 MXFMetadataStructuralComponent *component =
2474 sequence->structural_components[i];
2475
2476 if (!component)
2477 continue;
2478
2479 self->type =
2480 mxf_metadata_track_identifier_parse (&component->data_definition);
2481 if (self->type != MXF_METADATA_TRACK_UNKNOWN)
2482 break;
2483 }
2484 }
2485
2486 return MXF_METADATA_BASE_CLASS (mxf_metadata_track_parent_class)->resolve (m,
2487 metadata);
2488 }
2489
2490 static GstStructure *
mxf_metadata_track_to_structure(MXFMetadataBase * m)2491 mxf_metadata_track_to_structure (MXFMetadataBase * m)
2492 {
2493 GstStructure *ret =
2494 MXF_METADATA_BASE_CLASS (mxf_metadata_track_parent_class)->to_structure
2495 (m);
2496 MXFMetadataTrack *self = MXF_METADATA_TRACK (m);
2497
2498 gst_structure_id_set (ret, MXF_QUARK (TRACK_ID), G_TYPE_UINT, self->track_id,
2499 MXF_QUARK (TRACK_NUMBER), G_TYPE_UINT, self->track_number, NULL);
2500
2501 if (self->track_name)
2502 gst_structure_id_set (ret, MXF_QUARK (TRACK_NAME), G_TYPE_STRING,
2503 self->track_name, NULL);
2504
2505 if (self->sequence) {
2506 GstStructure *s =
2507 mxf_metadata_base_to_structure (MXF_METADATA_BASE (self->sequence));
2508
2509 gst_structure_id_set (ret, MXF_QUARK (SEQUENCE), GST_TYPE_STRUCTURE, s,
2510 NULL);
2511 gst_structure_free (s);
2512 }
2513
2514
2515 return ret;
2516 }
2517
2518 static GList *
mxf_metadata_track_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)2519 mxf_metadata_track_write_tags (MXFMetadataBase * m, MXFPrimerPack * primer)
2520 {
2521 MXFMetadataTrack *self = MXF_METADATA_TRACK (m);
2522 GList *ret =
2523 MXF_METADATA_BASE_CLASS (mxf_metadata_track_parent_class)->write_tags (m,
2524 primer);
2525 MXFLocalTag *t;
2526
2527 t = g_slice_new0 (MXFLocalTag);
2528 memcpy (&t->ul, MXF_UL (TRACK_ID), 16);
2529 t->size = 4;
2530 t->data = g_slice_alloc (t->size);
2531 t->g_slice = TRUE;
2532 GST_WRITE_UINT32_BE (t->data, self->track_id);
2533 mxf_primer_pack_add_mapping (primer, 0x4801, &t->ul);
2534 ret = g_list_prepend (ret, t);
2535
2536 t = g_slice_new0 (MXFLocalTag);
2537 memcpy (&t->ul, MXF_UL (TRACK_NUMBER), 16);
2538 t->size = 4;
2539 t->data = g_slice_alloc (t->size);
2540 t->g_slice = TRUE;
2541 GST_WRITE_UINT32_BE (t->data, self->track_number);
2542 mxf_primer_pack_add_mapping (primer, 0x4804, &t->ul);
2543 ret = g_list_prepend (ret, t);
2544
2545 if (self->track_name) {
2546 t = g_slice_new0 (MXFLocalTag);
2547 memcpy (&t->ul, MXF_UL (TRACK_NAME), 16);
2548 t->data = mxf_utf8_to_utf16 (self->track_name, &t->size);
2549 mxf_primer_pack_add_mapping (primer, 0x4802, &t->ul);
2550 ret = g_list_prepend (ret, t);
2551 }
2552
2553 t = g_slice_new0 (MXFLocalTag);
2554 memcpy (&t->ul, MXF_UL (SEQUENCE), 16);
2555 t->size = 16;
2556 t->data = g_slice_alloc (t->size);
2557 t->g_slice = TRUE;
2558 memcpy (t->data, &MXF_METADATA_BASE (self->sequence)->instance_uid, 16);
2559 mxf_primer_pack_add_mapping (primer, 0x4803, &t->ul);
2560 ret = g_list_prepend (ret, t);
2561
2562 return ret;
2563 }
2564
2565 static void
mxf_metadata_track_init(MXFMetadataTrack * self)2566 mxf_metadata_track_init (MXFMetadataTrack * self)
2567 {
2568
2569 }
2570
2571 static void
mxf_metadata_track_class_init(MXFMetadataTrackClass * klass)2572 mxf_metadata_track_class_init (MXFMetadataTrackClass * klass)
2573 {
2574 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
2575 GObjectClass *object_class = (GObjectClass *) klass;
2576
2577 object_class->finalize = mxf_metadata_track_finalize;
2578 metadata_base_class->handle_tag = mxf_metadata_track_handle_tag;
2579 metadata_base_class->resolve = mxf_metadata_track_resolve;
2580 metadata_base_class->to_structure = mxf_metadata_track_to_structure;
2581 metadata_base_class->write_tags = mxf_metadata_track_write_tags;
2582 }
2583
2584 /* SMPTE RP224 */
2585 static const struct
2586 {
2587 const MXFUL *ul;
2588 const MXFMetadataTrackType type;
2589 } mxf_metadata_track_identifier[] = {
2590 {
2591 MXF_UL (TRACK_TIMECODE_12M_INACTIVE),
2592 MXF_METADATA_TRACK_TIMECODE_12M_INACTIVE}, {
2593 MXF_UL (TRACK_TIMECODE_12M_ACTIVE), MXF_METADATA_TRACK_TIMECODE_12M_ACTIVE}, {
2594 MXF_UL (TRACK_TIMECODE_309M), MXF_METADATA_TRACK_TIMECODE_309M}, {
2595 MXF_UL (TRACK_METADATA), MXF_METADATA_TRACK_METADATA}, {
2596 MXF_UL (TRACK_PICTURE_ESSENCE), MXF_METADATA_TRACK_PICTURE_ESSENCE}, {
2597 MXF_UL (TRACK_SOUND_ESSENCE), MXF_METADATA_TRACK_SOUND_ESSENCE}, {
2598 MXF_UL (TRACK_DATA_ESSENCE), MXF_METADATA_TRACK_DATA_ESSENCE}, {
2599 MXF_UL (TRACK_AUXILIARY_DATA), MXF_METADATA_TRACK_AUXILIARY_DATA}, {
2600 MXF_UL (TRACK_PARSED_TEXT), MXF_METADATA_TRACK_PARSED_TEXT},
2601 /* Avid video? */
2602 {
2603 MXF_UL (TRACK_AVID_PICTURE_ESSENCE), MXF_METADATA_TRACK_PICTURE_ESSENCE}
2604 };
2605
2606 MXFMetadataTrackType
mxf_metadata_track_identifier_parse(const MXFUL * track_identifier)2607 mxf_metadata_track_identifier_parse (const MXFUL * track_identifier)
2608 {
2609 guint i;
2610
2611 for (i = 0; i < G_N_ELEMENTS (mxf_metadata_track_identifier); i++)
2612 if (mxf_ul_is_equal (mxf_metadata_track_identifier[i].ul, track_identifier))
2613 return mxf_metadata_track_identifier[i].type;
2614
2615 return MXF_METADATA_TRACK_UNKNOWN;
2616 }
2617
2618 const MXFUL *
mxf_metadata_track_identifier_get(MXFMetadataTrackType type)2619 mxf_metadata_track_identifier_get (MXFMetadataTrackType type)
2620 {
2621 guint i;
2622
2623 for (i = 0; i < G_N_ELEMENTS (mxf_metadata_track_identifier); i++)
2624 if (mxf_metadata_track_identifier[i].type == type)
2625 return mxf_metadata_track_identifier[i].ul;
2626
2627 return NULL;
2628 }
2629
2630 G_DEFINE_TYPE (MXFMetadataTimelineTrack, mxf_metadata_timeline_track,
2631 MXF_TYPE_METADATA_TRACK);
2632
2633 static gboolean
mxf_metadata_timeline_track_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)2634 mxf_metadata_timeline_track_handle_tag (MXFMetadataBase * metadata,
2635 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
2636 guint tag_size)
2637 {
2638 MXFMetadataTimelineTrack *self = MXF_METADATA_TIMELINE_TRACK (metadata);
2639 gboolean ret = TRUE;
2640
2641 switch (tag) {
2642 case 0x4b01:
2643 if (!mxf_fraction_parse (&self->edit_rate, tag_data, tag_size))
2644 goto error;
2645 GST_DEBUG (" edit rate = %d/%d", self->edit_rate.n, self->edit_rate.d);
2646 break;
2647 case 0x4b02:
2648 if (tag_size != 8)
2649 goto error;
2650 self->origin = GST_READ_UINT64_BE (tag_data);
2651 GST_DEBUG (" origin = %" G_GINT64_FORMAT, self->origin);
2652 break;
2653 default:
2654 ret =
2655 MXF_METADATA_BASE_CLASS
2656 (mxf_metadata_timeline_track_parent_class)->handle_tag (metadata,
2657 primer, tag, tag_data, tag_size);
2658 break;
2659 }
2660
2661 return ret;
2662
2663 error:
2664
2665 GST_ERROR ("Invalid timeline track local tag 0x%04x of size %u", tag,
2666 tag_size);
2667
2668 return FALSE;
2669 }
2670
2671 static GstStructure *
mxf_metadata_timeline_track_to_structure(MXFMetadataBase * m)2672 mxf_metadata_timeline_track_to_structure (MXFMetadataBase * m)
2673 {
2674 GstStructure *ret =
2675 MXF_METADATA_BASE_CLASS
2676 (mxf_metadata_timeline_track_parent_class)->to_structure (m);
2677 MXFMetadataTimelineTrack *self = MXF_METADATA_TIMELINE_TRACK (m);
2678
2679 gst_structure_id_set (ret, MXF_QUARK (EDIT_RATE), GST_TYPE_FRACTION,
2680 self->edit_rate.n, self->edit_rate.d, MXF_QUARK (ORIGIN), G_TYPE_INT64,
2681 self->origin, NULL);
2682
2683 return ret;
2684 }
2685
2686 static GList *
mxf_metadata_timeline_track_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)2687 mxf_metadata_timeline_track_write_tags (MXFMetadataBase * m,
2688 MXFPrimerPack * primer)
2689 {
2690 MXFMetadataTimelineTrack *self = MXF_METADATA_TIMELINE_TRACK (m);
2691 GList *ret =
2692 MXF_METADATA_BASE_CLASS
2693 (mxf_metadata_timeline_track_parent_class)->write_tags (m, primer);
2694 MXFLocalTag *t;
2695
2696 t = g_slice_new0 (MXFLocalTag);
2697 memcpy (&t->ul, MXF_UL (EDIT_RATE), 16);
2698 t->size = 8;
2699 t->data = g_slice_alloc (t->size);
2700 t->g_slice = TRUE;
2701 GST_WRITE_UINT32_BE (t->data, self->edit_rate.n);
2702 GST_WRITE_UINT32_BE (t->data + 4, self->edit_rate.d);
2703 mxf_primer_pack_add_mapping (primer, 0x4b01, &t->ul);
2704 ret = g_list_prepend (ret, t);
2705
2706 t = g_slice_new0 (MXFLocalTag);
2707 memcpy (&t->ul, MXF_UL (ORIGIN), 16);
2708 t->size = 8;
2709 t->data = g_slice_alloc (t->size);
2710 t->g_slice = TRUE;
2711 GST_WRITE_UINT64_BE (t->data, self->origin);
2712 mxf_primer_pack_add_mapping (primer, 0x4b02, &t->ul);
2713 ret = g_list_prepend (ret, t);
2714
2715 return ret;
2716 }
2717
2718 static void
mxf_metadata_timeline_track_init(MXFMetadataTimelineTrack * self)2719 mxf_metadata_timeline_track_init (MXFMetadataTimelineTrack * self)
2720 {
2721
2722 }
2723
2724 static void
mxf_metadata_timeline_track_class_init(MXFMetadataTimelineTrackClass * klass)2725 mxf_metadata_timeline_track_class_init (MXFMetadataTimelineTrackClass * klass)
2726 {
2727 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
2728 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
2729
2730 metadata_base_class->handle_tag = mxf_metadata_timeline_track_handle_tag;
2731 metadata_base_class->name_quark = MXF_QUARK (TIMELINE_TRACK);
2732 metadata_base_class->to_structure = mxf_metadata_timeline_track_to_structure;
2733 metadata_base_class->write_tags = mxf_metadata_timeline_track_write_tags;
2734 metadata_class->type = 0x013b;
2735 }
2736
2737 G_DEFINE_TYPE (MXFMetadataEventTrack, mxf_metadata_event_track,
2738 MXF_TYPE_METADATA_TRACK);
2739
2740 static gboolean
mxf_metadata_event_track_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)2741 mxf_metadata_event_track_handle_tag (MXFMetadataBase * metadata,
2742 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
2743 guint tag_size)
2744 {
2745 MXFMetadataEventTrack *self = MXF_METADATA_EVENT_TRACK (metadata);
2746 gboolean ret = TRUE;
2747
2748 switch (tag) {
2749 case 0x4901:
2750 if (!mxf_fraction_parse (&self->event_edit_rate, tag_data, tag_size))
2751 goto error;
2752 GST_DEBUG (" event edit rate = %d/%d", self->event_edit_rate.n,
2753 self->event_edit_rate.d);
2754 break;
2755 case 0x4902:
2756 if (tag_size != 8)
2757 goto error;
2758 self->event_origin = GST_READ_UINT64_BE (tag_data);
2759 GST_DEBUG (" event origin = %" G_GINT64_FORMAT, self->event_origin);
2760 break;
2761 default:
2762 ret =
2763 MXF_METADATA_BASE_CLASS
2764 (mxf_metadata_event_track_parent_class)->handle_tag (metadata, primer,
2765 tag, tag_data, tag_size);
2766 break;
2767 }
2768
2769 return ret;
2770
2771 error:
2772
2773 GST_ERROR ("Invalid event track local tag 0x%04x of size %u", tag, tag_size);
2774
2775 return FALSE;
2776 }
2777
2778 static GstStructure *
mxf_metadata_event_track_to_structure(MXFMetadataBase * m)2779 mxf_metadata_event_track_to_structure (MXFMetadataBase * m)
2780 {
2781 GstStructure *ret =
2782 MXF_METADATA_BASE_CLASS
2783 (mxf_metadata_event_track_parent_class)->to_structure (m);
2784 MXFMetadataEventTrack *self = MXF_METADATA_EVENT_TRACK (m);
2785
2786 gst_structure_id_set (ret, MXF_QUARK (EVENT_EDIT_RATE), GST_TYPE_FRACTION,
2787 self->event_edit_rate.n, self->event_edit_rate.d,
2788 MXF_QUARK (EVENT_ORIGIN), G_TYPE_INT64, self->event_origin, NULL);
2789
2790 return ret;
2791 }
2792
2793 static GList *
mxf_metadata_event_track_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)2794 mxf_metadata_event_track_write_tags (MXFMetadataBase * m,
2795 MXFPrimerPack * primer)
2796 {
2797 MXFMetadataEventTrack *self = MXF_METADATA_EVENT_TRACK (m);
2798 GList *ret =
2799 MXF_METADATA_BASE_CLASS
2800 (mxf_metadata_event_track_parent_class)->write_tags (m, primer);
2801 MXFLocalTag *t;
2802
2803 t = g_slice_new0 (MXFLocalTag);
2804 memcpy (&t->ul, MXF_UL (EVENT_EDIT_RATE), 16);
2805 t->size = 8;
2806 t->data = g_slice_alloc (t->size);
2807 t->g_slice = TRUE;
2808 GST_WRITE_UINT32_BE (t->data, self->event_edit_rate.n);
2809 GST_WRITE_UINT32_BE (t->data + 4, self->event_edit_rate.d);
2810 mxf_primer_pack_add_mapping (primer, 0x4901, &t->ul);
2811 ret = g_list_prepend (ret, t);
2812
2813 t = g_slice_new0 (MXFLocalTag);
2814 memcpy (&t->ul, MXF_UL (EVENT_ORIGIN), 16);
2815 t->size = 8;
2816 t->data = g_slice_alloc (t->size);
2817 t->g_slice = TRUE;
2818 GST_WRITE_UINT64_BE (t->data, self->event_origin);
2819 mxf_primer_pack_add_mapping (primer, 0x4902, &t->ul);
2820 ret = g_list_prepend (ret, t);
2821
2822 return ret;
2823 }
2824
2825 static void
mxf_metadata_event_track_init(MXFMetadataEventTrack * self)2826 mxf_metadata_event_track_init (MXFMetadataEventTrack * self)
2827 {
2828
2829 }
2830
2831 static void
mxf_metadata_event_track_class_init(MXFMetadataEventTrackClass * klass)2832 mxf_metadata_event_track_class_init (MXFMetadataEventTrackClass * klass)
2833 {
2834 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
2835 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
2836
2837 metadata_base_class->handle_tag = mxf_metadata_event_track_handle_tag;
2838 metadata_base_class->name_quark = MXF_QUARK (EVENT_TRACK);
2839 metadata_base_class->to_structure = mxf_metadata_event_track_to_structure;
2840 metadata_base_class->write_tags = mxf_metadata_event_track_write_tags;
2841 metadata_class->type = 0x0139;
2842 }
2843
2844 G_DEFINE_TYPE (MXFMetadataStaticTrack, mxf_metadata_static_track,
2845 MXF_TYPE_METADATA_TRACK);
2846
2847 static void
mxf_metadata_static_track_init(MXFMetadataStaticTrack * self)2848 mxf_metadata_static_track_init (MXFMetadataStaticTrack * self)
2849 {
2850 }
2851
2852 static void
mxf_metadata_static_track_class_init(MXFMetadataStaticTrackClass * klass)2853 mxf_metadata_static_track_class_init (MXFMetadataStaticTrackClass * klass)
2854 {
2855 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
2856 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
2857
2858 metadata_base_class->name_quark = MXF_QUARK (STATIC_TRACK);
2859 metadata_class->type = 0x013a;
2860 }
2861
2862 G_DEFINE_TYPE (MXFMetadataSequence, mxf_metadata_sequence, MXF_TYPE_METADATA);
2863
2864 static void
mxf_metadata_sequence_finalize(GObject * object)2865 mxf_metadata_sequence_finalize (GObject * object)
2866 {
2867 MXFMetadataSequence *self = MXF_METADATA_SEQUENCE (object);
2868
2869 g_free (self->structural_components_uids);
2870 self->structural_components_uids = NULL;
2871 g_free (self->structural_components);
2872 self->structural_components = NULL;
2873
2874 G_OBJECT_CLASS (mxf_metadata_sequence_parent_class)->finalize (object);
2875 }
2876
2877 static gboolean
mxf_metadata_sequence_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)2878 mxf_metadata_sequence_handle_tag (MXFMetadataBase * metadata,
2879 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
2880 guint tag_size)
2881 {
2882 MXFMetadataSequence *self = MXF_METADATA_SEQUENCE (metadata);
2883 gboolean ret = TRUE;
2884 #ifndef GST_DISABLE_GST_DEBUG
2885 gchar str[48];
2886 #endif
2887
2888 switch (tag) {
2889 case 0x0201:
2890 if (tag_size != 16)
2891 goto error;
2892 memcpy (&self->data_definition, tag_data, 16);
2893 GST_DEBUG (" data definition = %s",
2894 mxf_ul_to_string (&self->data_definition, str));
2895 break;
2896 case 0x0202:
2897 if (tag_size != 8)
2898 goto error;
2899 self->duration = GST_READ_UINT64_BE (tag_data);
2900 GST_DEBUG (" duration = %" G_GINT64_FORMAT, self->duration);
2901 break;
2902 case 0x1001:
2903 if (!mxf_uuid_array_parse (&self->structural_components_uids,
2904 &self->n_structural_components, tag_data, tag_size))
2905 goto error;
2906
2907 GST_DEBUG (" number of structural components = %u",
2908 self->n_structural_components);
2909 #ifndef GST_DISABLE_GST_DEBUG
2910 {
2911 guint i;
2912 for (i = 0; i < self->n_structural_components; i++) {
2913 GST_DEBUG (" structural component %u = %s", i,
2914 mxf_uuid_to_string (&self->structural_components_uids[i], str));
2915 }
2916 }
2917 #endif
2918 break;
2919 default:
2920 ret =
2921 MXF_METADATA_BASE_CLASS
2922 (mxf_metadata_sequence_parent_class)->handle_tag (metadata, primer,
2923 tag, tag_data, tag_size);
2924 break;
2925 }
2926
2927 return ret;
2928
2929 error:
2930
2931 GST_ERROR ("Invalid sequence local tag 0x%04x of size %u", tag, tag_size);
2932
2933 return FALSE;
2934 }
2935
2936 static gboolean
mxf_metadata_sequence_resolve(MXFMetadataBase * m,GHashTable * metadata)2937 mxf_metadata_sequence_resolve (MXFMetadataBase * m, GHashTable * metadata)
2938 {
2939 MXFMetadataSequence *self = MXF_METADATA_SEQUENCE (m);
2940 MXFMetadataBase *current = NULL;
2941 guint i;
2942 #ifndef GST_DISABLE_GST_DEBUG
2943 gchar str[48];
2944 #endif
2945
2946 if (self->structural_components)
2947 memset (self->structural_components, 0,
2948 sizeof (gpointer) * self->n_structural_components);
2949 else
2950 self->structural_components =
2951 g_new0 (MXFMetadataStructuralComponent *,
2952 self->n_structural_components);
2953 for (i = 0; i < self->n_structural_components; i++) {
2954 current =
2955 g_hash_table_lookup (metadata, &self->structural_components_uids[i]);
2956 if (current && MXF_IS_METADATA_STRUCTURAL_COMPONENT (current)) {
2957 if (mxf_metadata_base_resolve (current, metadata)) {
2958 self->structural_components[i] =
2959 MXF_METADATA_STRUCTURAL_COMPONENT (current);
2960 } else {
2961 GST_ERROR ("Couldn't resolve structural component %s",
2962 mxf_uuid_to_string (&self->structural_components_uids[i], str));
2963 return FALSE;
2964 }
2965 } else {
2966 GST_ERROR ("Structural component %s not found",
2967 mxf_uuid_to_string (&self->structural_components_uids[i], str));
2968 return FALSE;
2969 }
2970 }
2971
2972 return
2973 MXF_METADATA_BASE_CLASS (mxf_metadata_sequence_parent_class)->resolve (m,
2974 metadata);
2975
2976 }
2977
2978 static GstStructure *
mxf_metadata_sequence_to_structure(MXFMetadataBase * m)2979 mxf_metadata_sequence_to_structure (MXFMetadataBase * m)
2980 {
2981 GstStructure *ret =
2982 MXF_METADATA_BASE_CLASS (mxf_metadata_sequence_parent_class)->to_structure
2983 (m);
2984 MXFMetadataSequence *self = MXF_METADATA_SEQUENCE (m);
2985 guint i;
2986 gchar str[48];
2987
2988 mxf_ul_to_string (&self->data_definition, str);
2989 gst_structure_id_set (ret, MXF_QUARK (DATA_DEFINITION), G_TYPE_STRING, str,
2990 MXF_QUARK (DURATION), G_TYPE_INT64, self->duration, NULL);
2991
2992 if (self->n_structural_components > 0) {
2993 GValue arr = { 0, }
2994 , val = {
2995 0,};
2996
2997 g_value_init (&arr, GST_TYPE_ARRAY);
2998
2999 for (i = 0; i < self->n_structural_components; i++) {
3000 GstStructure *s;
3001
3002 if (self->structural_components[i] == NULL)
3003 continue;
3004
3005 g_value_init (&val, GST_TYPE_STRUCTURE);
3006
3007 s = mxf_metadata_base_to_structure (MXF_METADATA_BASE
3008 (self->structural_components[i]));
3009 gst_value_set_structure (&val, s);
3010 gst_structure_free (s);
3011 gst_value_array_append_value (&arr, &val);
3012 g_value_unset (&val);
3013 }
3014
3015 if (gst_value_array_get_size (&arr) > 0)
3016 gst_structure_id_set_value (ret, MXF_QUARK (STRUCTURAL_COMPONENTS), &arr);
3017
3018 g_value_unset (&arr);
3019 }
3020
3021 return ret;
3022 }
3023
3024 static GList *
mxf_metadata_sequence_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)3025 mxf_metadata_sequence_write_tags (MXFMetadataBase * m, MXFPrimerPack * primer)
3026 {
3027 MXFMetadataSequence *self = MXF_METADATA_SEQUENCE (m);
3028 GList *ret =
3029 MXF_METADATA_BASE_CLASS (mxf_metadata_sequence_parent_class)->write_tags
3030 (m, primer);
3031 MXFLocalTag *t;
3032
3033 t = g_slice_new0 (MXFLocalTag);
3034 memcpy (&t->ul, MXF_UL (DATA_DEFINITION), 16);
3035 t->size = 16;
3036 t->data = g_slice_alloc (t->size);
3037 t->g_slice = TRUE;
3038 memcpy (t->data, &self->data_definition, 16);
3039 mxf_primer_pack_add_mapping (primer, 0x0201, &t->ul);
3040 ret = g_list_prepend (ret, t);
3041
3042 t = g_slice_new0 (MXFLocalTag);
3043 memcpy (&t->ul, MXF_UL (DURATION), 16);
3044 t->size = 8;
3045 t->data = g_slice_alloc (t->size);
3046 t->g_slice = TRUE;
3047 GST_WRITE_UINT64_BE (t->data, self->duration);
3048 mxf_primer_pack_add_mapping (primer, 0x0202, &t->ul);
3049 ret = g_list_prepend (ret, t);
3050
3051 if (self->structural_components) {
3052 guint i;
3053 t = g_slice_new0 (MXFLocalTag);
3054 memcpy (&t->ul, MXF_UL (STRUCTURAL_COMPONENTS), 16);
3055 t->size = 8 + 16 * self->n_structural_components;
3056 t->data = g_slice_alloc0 (t->size);
3057 t->g_slice = TRUE;
3058
3059 GST_WRITE_UINT32_BE (t->data, self->n_structural_components);
3060 GST_WRITE_UINT32_BE (t->data + 4, 16);
3061 for (i = 0; i < self->n_structural_components; i++) {
3062 if (!self->structural_components[i])
3063 continue;
3064
3065 memcpy (t->data + 8 + i * 16,
3066 &MXF_METADATA_BASE (self->structural_components[i])->instance_uid,
3067 16);
3068 }
3069
3070 mxf_primer_pack_add_mapping (primer, 0x1001, &t->ul);
3071 ret = g_list_prepend (ret, t);
3072 }
3073
3074 return ret;
3075 }
3076
3077 static void
mxf_metadata_sequence_init(MXFMetadataSequence * self)3078 mxf_metadata_sequence_init (MXFMetadataSequence * self)
3079 {
3080 self->duration = -1;
3081 }
3082
3083 static void
mxf_metadata_sequence_class_init(MXFMetadataSequenceClass * klass)3084 mxf_metadata_sequence_class_init (MXFMetadataSequenceClass * klass)
3085 {
3086 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
3087 GObjectClass *object_class = (GObjectClass *) klass;
3088 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
3089
3090 object_class->finalize = mxf_metadata_sequence_finalize;
3091 metadata_base_class->handle_tag = mxf_metadata_sequence_handle_tag;
3092 metadata_base_class->resolve = mxf_metadata_sequence_resolve;
3093 metadata_base_class->name_quark = MXF_QUARK (SEQUENCE);
3094 metadata_base_class->to_structure = mxf_metadata_sequence_to_structure;
3095 metadata_base_class->write_tags = mxf_metadata_sequence_write_tags;
3096 metadata_class->type = 0x010f;
3097 }
3098
3099 G_DEFINE_TYPE (MXFMetadataStructuralComponent,
3100 mxf_metadata_structural_component, MXF_TYPE_METADATA);
3101
3102 static gboolean
mxf_metadata_structural_component_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)3103 mxf_metadata_structural_component_handle_tag (MXFMetadataBase * metadata,
3104 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
3105 guint tag_size)
3106 {
3107 MXFMetadataStructuralComponent *self =
3108 MXF_METADATA_STRUCTURAL_COMPONENT (metadata);
3109 gboolean ret = TRUE;
3110 #ifndef GST_DISABLE_GST_DEBUG
3111 gchar str[48];
3112 #endif
3113
3114 switch (tag) {
3115 case 0x0201:
3116 if (tag_size != 16)
3117 goto error;
3118 memcpy (&self->data_definition, tag_data, 16);
3119 GST_DEBUG (" data definition = %s",
3120 mxf_ul_to_string (&self->data_definition, str));
3121 break;
3122 case 0x0202:
3123 if (tag_size != 8)
3124 goto error;
3125 self->duration = GST_READ_UINT64_BE (tag_data);
3126 GST_DEBUG (" duration = %" G_GINT64_FORMAT, self->duration);
3127 break;
3128 default:
3129 ret =
3130 MXF_METADATA_BASE_CLASS
3131 (mxf_metadata_structural_component_parent_class)->handle_tag
3132 (metadata, primer, tag, tag_data, tag_size);
3133 break;
3134 }
3135
3136 return ret;
3137
3138 error:
3139
3140 GST_ERROR ("Invalid structural component local tag 0x%04x of size %u", tag,
3141 tag_size);
3142
3143 return FALSE;
3144 }
3145
3146 static GstStructure *
mxf_metadata_structural_component_to_structure(MXFMetadataBase * m)3147 mxf_metadata_structural_component_to_structure (MXFMetadataBase * m)
3148 {
3149 GstStructure *ret =
3150 MXF_METADATA_BASE_CLASS
3151 (mxf_metadata_structural_component_parent_class)->to_structure (m);
3152 MXFMetadataStructuralComponent *self = MXF_METADATA_STRUCTURAL_COMPONENT (m);
3153 gchar str[48];
3154
3155 mxf_ul_to_string (&self->data_definition, str);
3156 gst_structure_id_set (ret, MXF_QUARK (DATA_DEFINITION), G_TYPE_STRING, str,
3157 MXF_QUARK (DURATION), G_TYPE_INT64, self->duration, NULL);
3158
3159 return ret;
3160 }
3161
3162 static GList *
mxf_metadata_structural_component_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)3163 mxf_metadata_structural_component_write_tags (MXFMetadataBase * m,
3164 MXFPrimerPack * primer)
3165 {
3166 MXFMetadataStructuralComponent *self = MXF_METADATA_STRUCTURAL_COMPONENT (m);
3167 GList *ret =
3168 MXF_METADATA_BASE_CLASS
3169 (mxf_metadata_structural_component_parent_class)->write_tags (m, primer);
3170 MXFLocalTag *t;
3171
3172 t = g_slice_new0 (MXFLocalTag);
3173 memcpy (&t->ul, MXF_UL (DATA_DEFINITION), 16);
3174 t->size = 16;
3175 t->data = g_slice_alloc (t->size);
3176 t->g_slice = TRUE;
3177 memcpy (t->data, &self->data_definition, 16);
3178 mxf_primer_pack_add_mapping (primer, 0x0201, &t->ul);
3179 ret = g_list_prepend (ret, t);
3180
3181 t = g_slice_new0 (MXFLocalTag);
3182 memcpy (&t->ul, MXF_UL (DURATION), 16);
3183 t->size = 8;
3184 t->data = g_slice_alloc (t->size);
3185 t->g_slice = TRUE;
3186 GST_WRITE_UINT64_BE (t->data, self->duration);
3187 mxf_primer_pack_add_mapping (primer, 0x0202, &t->ul);
3188 ret = g_list_prepend (ret, t);
3189
3190 return ret;
3191 }
3192
3193 static void
mxf_metadata_structural_component_init(MXFMetadataStructuralComponent * self)3194 mxf_metadata_structural_component_init (MXFMetadataStructuralComponent * self)
3195 {
3196 self->duration = -1;
3197 }
3198
3199 static void
mxf_metadata_structural_component_class_init(MXFMetadataStructuralComponentClass * klass)3200 mxf_metadata_structural_component_class_init
3201 (MXFMetadataStructuralComponentClass * klass)
3202 {
3203 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
3204
3205 metadata_base_class->handle_tag =
3206 mxf_metadata_structural_component_handle_tag;
3207 metadata_base_class->to_structure =
3208 mxf_metadata_structural_component_to_structure;
3209 metadata_base_class->write_tags =
3210 mxf_metadata_structural_component_write_tags;
3211 }
3212
3213 G_DEFINE_TYPE (MXFMetadataTimecodeComponent, mxf_metadata_timecode_component,
3214 MXF_TYPE_METADATA_STRUCTURAL_COMPONENT);
3215
3216 static gboolean
mxf_metadata_timecode_component_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)3217 mxf_metadata_timecode_component_handle_tag (MXFMetadataBase * metadata,
3218 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
3219 guint tag_size)
3220 {
3221 MXFMetadataTimecodeComponent *self =
3222 MXF_METADATA_TIMECODE_COMPONENT (metadata);
3223 gboolean ret = TRUE;
3224
3225 switch (tag) {
3226 case 0x1502:
3227 if (tag_size != 2)
3228 goto error;
3229 self->rounded_timecode_base = GST_READ_UINT16_BE (tag_data);
3230 GST_DEBUG (" rounded timecode base = %u", self->rounded_timecode_base);
3231 break;
3232 case 0x1501:
3233 if (tag_size != 8)
3234 goto error;
3235 self->start_timecode = GST_READ_UINT64_BE (tag_data);
3236 GST_DEBUG (" start timecode = %" G_GINT64_FORMAT, self->start_timecode);
3237 break;
3238 case 0x1503:
3239 if (tag_size != 1)
3240 goto error;
3241 self->drop_frame = (GST_READ_UINT8 (tag_data) != 0);
3242 GST_DEBUG (" drop frame = %s", (self->drop_frame) ? "yes" : "no");
3243 break;
3244 default:
3245 ret =
3246 MXF_METADATA_BASE_CLASS
3247 (mxf_metadata_timecode_component_parent_class)->handle_tag (metadata,
3248 primer, tag, tag_data, tag_size);
3249 break;
3250 }
3251
3252 return ret;
3253
3254 error:
3255
3256 GST_ERROR ("Invalid timecode component local tag 0x%04x of size %u", tag,
3257 tag_size);
3258
3259 return FALSE;
3260 }
3261
3262 static GstStructure *
mxf_metadata_timecode_component_to_structure(MXFMetadataBase * m)3263 mxf_metadata_timecode_component_to_structure (MXFMetadataBase * m)
3264 {
3265 GstStructure *ret =
3266 MXF_METADATA_BASE_CLASS
3267 (mxf_metadata_timecode_component_parent_class)->to_structure (m);
3268 MXFMetadataTimecodeComponent *self = MXF_METADATA_TIMECODE_COMPONENT (m);
3269
3270 gst_structure_id_set (ret, MXF_QUARK (START_TIMECODE), G_TYPE_INT64,
3271 self->start_timecode, MXF_QUARK (ROUNDED_TIMECODE_BASE), G_TYPE_UINT,
3272 self->rounded_timecode_base, MXF_QUARK (DROP_FRAME), G_TYPE_BOOLEAN,
3273 self->drop_frame, NULL);
3274
3275 return ret;
3276 }
3277
3278 static GList *
mxf_metadata_timecode_component_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)3279 mxf_metadata_timecode_component_write_tags (MXFMetadataBase * m,
3280 MXFPrimerPack * primer)
3281 {
3282 MXFMetadataTimecodeComponent *self = MXF_METADATA_TIMECODE_COMPONENT (m);
3283 GList *ret =
3284 MXF_METADATA_BASE_CLASS
3285 (mxf_metadata_timecode_component_parent_class)->write_tags (m, primer);
3286 MXFLocalTag *t;
3287
3288 t = g_slice_new0 (MXFLocalTag);
3289 memcpy (&t->ul, MXF_UL (ROUNDED_TIMECODE_BASE), 16);
3290 t->size = 2;
3291 t->data = g_slice_alloc (t->size);
3292 t->g_slice = TRUE;
3293 GST_WRITE_UINT16_BE (t->data, self->rounded_timecode_base);
3294 mxf_primer_pack_add_mapping (primer, 0x1502, &t->ul);
3295 ret = g_list_prepend (ret, t);
3296
3297 t = g_slice_new0 (MXFLocalTag);
3298 memcpy (&t->ul, MXF_UL (START_TIMECODE), 16);
3299 t->size = 8;
3300 t->data = g_slice_alloc (t->size);
3301 t->g_slice = TRUE;
3302 GST_WRITE_UINT64_BE (t->data, self->start_timecode);
3303 mxf_primer_pack_add_mapping (primer, 0x1501, &t->ul);
3304 ret = g_list_prepend (ret, t);
3305
3306 t = g_slice_new0 (MXFLocalTag);
3307 memcpy (&t->ul, MXF_UL (DROP_FRAME), 16);
3308 t->size = 1;
3309 t->data = g_slice_alloc (t->size);
3310 t->g_slice = TRUE;
3311 GST_WRITE_UINT8 (t->data, (self->drop_frame) ? 1 : 0);
3312 mxf_primer_pack_add_mapping (primer, 0x1503, &t->ul);
3313 ret = g_list_prepend (ret, t);
3314
3315 return ret;
3316 }
3317
3318 static void
mxf_metadata_timecode_component_init(MXFMetadataTimecodeComponent * self)3319 mxf_metadata_timecode_component_init (MXFMetadataTimecodeComponent * self)
3320 {
3321
3322 }
3323
3324 static void
mxf_metadata_timecode_component_class_init(MXFMetadataTimecodeComponentClass * klass)3325 mxf_metadata_timecode_component_class_init (MXFMetadataTimecodeComponentClass *
3326 klass)
3327 {
3328 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
3329 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
3330
3331 metadata_base_class->handle_tag = mxf_metadata_timecode_component_handle_tag;
3332 metadata_base_class->name_quark = MXF_QUARK (TIMECODE_COMPONENT);
3333 metadata_base_class->to_structure =
3334 mxf_metadata_timecode_component_to_structure;
3335 metadata_base_class->write_tags = mxf_metadata_timecode_component_write_tags;
3336 metadata_class->type = 0x0114;
3337 }
3338
3339 G_DEFINE_TYPE (MXFMetadataSourceClip, mxf_metadata_source_clip,
3340 MXF_TYPE_METADATA_STRUCTURAL_COMPONENT);
3341
3342 static gboolean
mxf_metadata_source_clip_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)3343 mxf_metadata_source_clip_handle_tag (MXFMetadataBase * metadata,
3344 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
3345 guint tag_size)
3346 {
3347 MXFMetadataSourceClip *self = MXF_METADATA_SOURCE_CLIP (metadata);
3348 gboolean ret = TRUE;
3349 #ifndef GST_DISABLE_GST_DEBUG
3350 gchar str[96];
3351 #endif
3352
3353 switch (tag) {
3354 case 0x1201:
3355 if (tag_size != 8)
3356 goto error;
3357
3358 self->start_position = GST_READ_UINT64_BE (tag_data);
3359 GST_DEBUG (" start position = %" G_GINT64_FORMAT, self->start_position);
3360 break;
3361 case 0x1101:
3362 if (tag_size != 32)
3363 goto error;
3364
3365 memcpy (&self->source_package_id, tag_data, 32);
3366 GST_DEBUG (" source package id = %s",
3367 mxf_umid_to_string (&self->source_package_id, str));
3368 break;
3369 case 0x1102:
3370 if (tag_size != 4)
3371 goto error;
3372
3373 self->source_track_id = GST_READ_UINT32_BE (tag_data);
3374 GST_DEBUG (" source track id = %u", self->source_track_id);
3375 break;
3376 default:
3377 ret =
3378 MXF_METADATA_BASE_CLASS
3379 (mxf_metadata_source_clip_parent_class)->handle_tag (metadata, primer,
3380 tag, tag_data, tag_size);
3381 break;
3382 }
3383
3384 return ret;
3385
3386 error:
3387
3388 GST_ERROR ("Invalid source clip local tag 0x%04x of size %u", tag, tag_size);
3389
3390 return FALSE;
3391 }
3392
3393 static gboolean
mxf_metadata_source_clip_resolve(MXFMetadataBase * m,GHashTable * metadata)3394 mxf_metadata_source_clip_resolve (MXFMetadataBase * m, GHashTable * metadata)
3395 {
3396 MXFMetadataSourceClip *self = MXF_METADATA_SOURCE_CLIP (m);
3397 MXFMetadataBase *current = NULL;
3398 GHashTableIter iter;
3399 #ifndef GST_DISABLE_GST_DEBUG
3400 gchar str[96];
3401 #endif
3402
3403 g_hash_table_iter_init (&iter, metadata);
3404
3405 while (g_hash_table_iter_next (&iter, NULL, (gpointer) & current)) {
3406 if (MXF_IS_METADATA_SOURCE_PACKAGE (current)) {
3407 MXFMetadataGenericPackage *p = MXF_METADATA_GENERIC_PACKAGE (current);
3408
3409 if (mxf_umid_is_equal (&p->package_uid, &self->source_package_id)) {
3410 self->source_package = MXF_METADATA_SOURCE_PACKAGE (current);
3411 break;
3412 }
3413 }
3414 }
3415
3416 if (!self->source_package) {
3417 GST_ERROR ("Couldn't find source package %s",
3418 mxf_umid_to_string (&self->source_package_id, str));
3419 }
3420
3421 return
3422 MXF_METADATA_BASE_CLASS (mxf_metadata_source_clip_parent_class)->resolve
3423 (m, metadata);
3424 }
3425
3426 static GstStructure *
mxf_metadata_source_clip_to_structure(MXFMetadataBase * m)3427 mxf_metadata_source_clip_to_structure (MXFMetadataBase * m)
3428 {
3429 GstStructure *ret =
3430 MXF_METADATA_BASE_CLASS
3431 (mxf_metadata_source_clip_parent_class)->to_structure (m);
3432 MXFMetadataSourceClip *self = MXF_METADATA_SOURCE_CLIP (m);
3433 gchar str[96];
3434
3435 mxf_umid_to_string (&self->source_package_id, str);
3436 gst_structure_id_set (ret, MXF_QUARK (START_POSITION), G_TYPE_INT64,
3437 self->start_position, MXF_QUARK (SOURCE_PACKAGE), G_TYPE_STRING, str,
3438 MXF_QUARK (SOURCE_TRACK_ID), G_TYPE_UINT, self->source_track_id, NULL);
3439
3440 return ret;
3441 }
3442
3443 static GList *
mxf_metadata_source_clip_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)3444 mxf_metadata_source_clip_write_tags (MXFMetadataBase * m,
3445 MXFPrimerPack * primer)
3446 {
3447 MXFMetadataSourceClip *self = MXF_METADATA_SOURCE_CLIP (m);
3448 GList *ret =
3449 MXF_METADATA_BASE_CLASS
3450 (mxf_metadata_source_clip_parent_class)->write_tags (m, primer);
3451 MXFLocalTag *t;
3452
3453 t = g_slice_new0 (MXFLocalTag);
3454 memcpy (&t->ul, MXF_UL (START_POSITION), 16);
3455 t->size = 8;
3456 t->data = g_slice_alloc (t->size);
3457 t->g_slice = TRUE;
3458 GST_WRITE_UINT64_BE (t->data, self->start_position);
3459 mxf_primer_pack_add_mapping (primer, 0x1201, &t->ul);
3460 ret = g_list_prepend (ret, t);
3461
3462 t = g_slice_new0 (MXFLocalTag);
3463 memcpy (&t->ul, MXF_UL (SOURCE_PACKAGE_ID), 16);
3464 t->size = 32;
3465 t->data = g_slice_alloc (t->size);
3466 t->g_slice = TRUE;
3467 memcpy (t->data, &self->source_package_id, 32);
3468 mxf_primer_pack_add_mapping (primer, 0x1101, &t->ul);
3469 ret = g_list_prepend (ret, t);
3470
3471 t = g_slice_new0 (MXFLocalTag);
3472 memcpy (&t->ul, MXF_UL (SOURCE_TRACK_ID), 16);
3473 t->size = 4;
3474 t->data = g_slice_alloc (t->size);
3475 t->g_slice = TRUE;
3476 GST_WRITE_UINT32_BE (t->data, self->source_track_id);
3477 mxf_primer_pack_add_mapping (primer, 0x1102, &t->ul);
3478 ret = g_list_prepend (ret, t);
3479
3480 return ret;
3481 }
3482
3483 static void
mxf_metadata_source_clip_init(MXFMetadataSourceClip * self)3484 mxf_metadata_source_clip_init (MXFMetadataSourceClip * self)
3485 {
3486
3487 }
3488
3489 static void
mxf_metadata_source_clip_class_init(MXFMetadataSourceClipClass * klass)3490 mxf_metadata_source_clip_class_init (MXFMetadataSourceClipClass * klass)
3491 {
3492 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
3493 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
3494
3495 metadata_base_class->handle_tag = mxf_metadata_source_clip_handle_tag;
3496 metadata_base_class->resolve = mxf_metadata_source_clip_resolve;
3497 metadata_base_class->name_quark = MXF_QUARK (SOURCE_CLIP);
3498 metadata_base_class->to_structure = mxf_metadata_source_clip_to_structure;
3499 metadata_base_class->write_tags = mxf_metadata_source_clip_write_tags;
3500 metadata_class->type = 0x0111;
3501 }
3502
3503
3504 G_DEFINE_TYPE (MXFMetadataFiller, mxf_metadata_filler,
3505 MXF_TYPE_METADATA_STRUCTURAL_COMPONENT);
3506
3507 static void
mxf_metadata_filler_init(MXFMetadataFiller * self)3508 mxf_metadata_filler_init (MXFMetadataFiller * self)
3509 {
3510
3511 }
3512
3513 static void
mxf_metadata_filler_class_init(MXFMetadataFillerClass * klass)3514 mxf_metadata_filler_class_init (MXFMetadataFillerClass * klass)
3515 {
3516 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
3517 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
3518
3519 metadata_base_class->name_quark = MXF_QUARK (FILLER);
3520 metadata_class->type = 0x0109;
3521 }
3522
3523 G_DEFINE_TYPE (MXFMetadataDMSourceClip, mxf_metadata_dm_source_clip,
3524 MXF_TYPE_METADATA_SOURCE_CLIP);
3525
3526 static void
mxf_metadata_dm_source_clip_finalize(GObject * object)3527 mxf_metadata_dm_source_clip_finalize (GObject * object)
3528 {
3529 MXFMetadataDMSourceClip *self = MXF_METADATA_DM_SOURCE_CLIP (object);
3530
3531 g_free (self->track_ids);
3532 self->track_ids = NULL;
3533
3534 G_OBJECT_CLASS (mxf_metadata_dm_source_clip_parent_class)->finalize (object);
3535 }
3536
3537 static gboolean
mxf_metadata_dm_source_clip_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)3538 mxf_metadata_dm_source_clip_handle_tag (MXFMetadataBase * metadata,
3539 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
3540 guint tag_size)
3541 {
3542 MXFMetadataDMSourceClip *self = MXF_METADATA_DM_SOURCE_CLIP (metadata);
3543 gboolean ret = TRUE;
3544
3545 switch (tag) {
3546 case 0x6103:
3547 {
3548 guint32 len;
3549 guint i;
3550
3551 if (tag_size < 8)
3552 goto error;
3553
3554 len = GST_READ_UINT32_BE (tag_data);
3555 GST_DEBUG (" number of track ids = %u", len);
3556 if (len == 0)
3557 return TRUE;
3558
3559 if (GST_READ_UINT32_BE (tag_data + 4) != 4)
3560 goto error;
3561
3562 tag_data += 8;
3563 tag_size -= 8;
3564
3565 if (tag_size / 4 < len)
3566 goto error;
3567
3568 self->n_track_ids = len;
3569 self->track_ids = g_new0 (guint32, len);
3570
3571 for (i = 0; i < len; i++) {
3572 self->track_ids[i] = GST_READ_UINT32_BE (tag_data);
3573 GST_DEBUG (" track id %u = %u", i, self->track_ids[i]);
3574 tag_data += 4;
3575 tag_size -= 4;
3576 }
3577 break;
3578 }
3579 default:
3580 ret =
3581 MXF_METADATA_BASE_CLASS
3582 (mxf_metadata_dm_source_clip_parent_class)->handle_tag (metadata,
3583 primer, tag, tag_data, tag_size);
3584 break;
3585 }
3586
3587 return ret;
3588
3589 error:
3590
3591 GST_ERROR ("Invalid DM source clip local tag 0x%04x of size %u", tag,
3592 tag_size);
3593
3594 return FALSE;
3595 }
3596
3597 static GstStructure *
mxf_metadata_dm_source_clip_to_structure(MXFMetadataBase * m)3598 mxf_metadata_dm_source_clip_to_structure (MXFMetadataBase * m)
3599 {
3600 GstStructure *ret =
3601 MXF_METADATA_BASE_CLASS
3602 (mxf_metadata_dm_source_clip_parent_class)->to_structure (m);
3603 MXFMetadataDMSourceClip *self = MXF_METADATA_DM_SOURCE_CLIP (m);
3604 guint i;
3605
3606 if (self->n_track_ids > 0) {
3607 GValue arr = { 0, }
3608 , val = {
3609 0,};
3610
3611 g_value_init (&arr, GST_TYPE_ARRAY);
3612
3613 for (i = 0; i < self->n_track_ids; i++) {
3614 g_value_init (&val, G_TYPE_UINT);
3615
3616 g_value_set_uint (&val, self->track_ids[i]);
3617 gst_value_array_append_value (&arr, &val);
3618 g_value_unset (&val);
3619 }
3620
3621 if (gst_value_array_get_size (&arr) > 0)
3622 gst_structure_id_set_value (ret, MXF_QUARK (TRACK_IDS), &arr);
3623
3624 g_value_unset (&arr);
3625 }
3626
3627 return ret;
3628 }
3629
3630 static GList *
mxf_metadata_dm_source_clip_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)3631 mxf_metadata_dm_source_clip_write_tags (MXFMetadataBase * m,
3632 MXFPrimerPack * primer)
3633 {
3634 MXFMetadataDMSourceClip *self = MXF_METADATA_DM_SOURCE_CLIP (m);
3635 GList *ret =
3636 MXF_METADATA_BASE_CLASS
3637 (mxf_metadata_dm_source_clip_parent_class)->write_tags (m, primer);
3638 MXFLocalTag *t;
3639
3640 if (self->track_ids) {
3641 guint i;
3642
3643 t = g_slice_new0 (MXFLocalTag);
3644 memcpy (&t->ul, MXF_UL (DM_SOURCECLIP_TRACK_IDS), 16);
3645 t->size = 8 + 4 * self->n_track_ids;
3646 t->data = g_slice_alloc (t->size);
3647 t->g_slice = TRUE;
3648 GST_WRITE_UINT32_BE (t->data, self->n_track_ids);
3649 GST_WRITE_UINT32_BE (t->data + 4, 4);
3650 for (i = 0; i < self->n_track_ids; i++)
3651 GST_WRITE_UINT32_BE (t->data + 8 + i * 4, self->track_ids[i]);
3652 mxf_primer_pack_add_mapping (primer, 0x6103, &t->ul);
3653 ret = g_list_prepend (ret, t);
3654 }
3655
3656 return ret;
3657 }
3658
3659 static void
mxf_metadata_dm_source_clip_init(MXFMetadataDMSourceClip * self)3660 mxf_metadata_dm_source_clip_init (MXFMetadataDMSourceClip * self)
3661 {
3662
3663 }
3664
3665 static void
mxf_metadata_dm_source_clip_class_init(MXFMetadataDMSourceClipClass * klass)3666 mxf_metadata_dm_source_clip_class_init (MXFMetadataDMSourceClipClass * klass)
3667 {
3668 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
3669 GObjectClass *object_class = (GObjectClass *) klass;
3670 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
3671
3672 object_class->finalize = mxf_metadata_dm_source_clip_finalize;
3673 metadata_base_class->handle_tag = mxf_metadata_dm_source_clip_handle_tag;
3674 metadata_base_class->name_quark = MXF_QUARK (DM_SOURCE_CLIP);
3675 metadata_base_class->to_structure = mxf_metadata_dm_source_clip_to_structure;
3676 metadata_base_class->write_tags = mxf_metadata_dm_source_clip_write_tags;
3677 metadata_class->type = 0x0145;
3678 }
3679
3680 G_DEFINE_TYPE (MXFMetadataDMSegment, mxf_metadata_dm_segment,
3681 MXF_TYPE_METADATA_STRUCTURAL_COMPONENT);
3682
3683 static void
mxf_metadata_dm_segment_finalize(GObject * object)3684 mxf_metadata_dm_segment_finalize (GObject * object)
3685 {
3686 MXFMetadataDMSegment *self = MXF_METADATA_DM_SEGMENT (object);
3687
3688 g_free (self->track_ids);
3689 self->track_ids = NULL;
3690
3691 g_free (self->event_comment);
3692 self->event_comment = NULL;
3693
3694 G_OBJECT_CLASS (mxf_metadata_dm_segment_parent_class)->finalize (object);
3695 }
3696
3697 static gboolean
mxf_metadata_dm_segment_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)3698 mxf_metadata_dm_segment_handle_tag (MXFMetadataBase * metadata,
3699 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
3700 guint tag_size)
3701 {
3702 MXFMetadataDMSegment *self = MXF_METADATA_DM_SEGMENT (metadata);
3703 gboolean ret = TRUE;
3704 #ifndef GST_DISABLE_GST_DEBUG
3705 gchar str[48];
3706 #endif
3707
3708 switch (tag) {
3709 case 0x0601:
3710 if (tag_size != 8)
3711 goto error;
3712 self->event_start_position = GST_READ_UINT64_BE (tag_data);
3713 GST_DEBUG (" event start position = %" G_GINT64_FORMAT,
3714 self->event_start_position);
3715 break;
3716 case 0x0602:
3717 self->event_comment = mxf_utf16_to_utf8 (tag_data, tag_size);
3718 GST_DEBUG (" event comment = %s", GST_STR_NULL (self->event_comment));
3719 break;
3720 case 0x6102:
3721 {
3722 guint32 len;
3723 guint i;
3724
3725 if (tag_size < 8)
3726 goto error;
3727 len = GST_READ_UINT32_BE (tag_data);
3728 GST_DEBUG (" number of track ids = %u", len);
3729 if (len == 0)
3730 return TRUE;
3731
3732 if (GST_READ_UINT32_BE (tag_data + 4) != 4)
3733 goto error;
3734
3735 tag_data += 8;
3736 tag_size -= 8;
3737
3738 if (len < tag_size / 4)
3739 goto error;
3740
3741 self->n_track_ids = len;
3742 self->track_ids = g_new0 (guint32, len);
3743
3744 tag_data += 8;
3745 tag_size -= 8;
3746
3747 for (i = 0; i < len; i++) {
3748 self->track_ids[i] = GST_READ_UINT32_BE (tag_data);
3749 GST_DEBUG (" track id %u = %u", i, self->track_ids[i]);
3750 tag_data += 4;
3751 tag_size -= 4;
3752 }
3753 break;
3754 }
3755 case 0x6101:
3756 if (tag_size != 16)
3757 goto error;
3758
3759 memcpy (&self->dm_framework_uid, tag_data, 16);
3760 GST_DEBUG (" DM framework = %s",
3761 mxf_uuid_to_string (&self->dm_framework_uid, str));
3762 break;
3763 default:
3764 ret =
3765 MXF_METADATA_BASE_CLASS
3766 (mxf_metadata_dm_segment_parent_class)->handle_tag (metadata, primer,
3767 tag, tag_data, tag_size);
3768 break;
3769 }
3770
3771 return ret;
3772
3773 error:
3774
3775 GST_ERROR ("Invalid DM segment local tag 0x%04x of size %u", tag, tag_size);
3776
3777 return FALSE;
3778 }
3779
3780 static gboolean
mxf_metadata_dm_segment_resolve(MXFMetadataBase * m,GHashTable * metadata)3781 mxf_metadata_dm_segment_resolve (MXFMetadataBase * m, GHashTable * metadata)
3782 {
3783 MXFMetadataDMSegment *self = MXF_METADATA_DM_SEGMENT (m);
3784 MXFMetadataBase *current = NULL;
3785 #ifndef GST_DISABLE_GST_DEBUG
3786 gchar str[48];
3787 #endif
3788
3789 current = g_hash_table_lookup (metadata, &self->dm_framework_uid);
3790 if (current && MXF_IS_DESCRIPTIVE_METADATA_FRAMEWORK (current)) {
3791 if (mxf_metadata_base_resolve (current, metadata)) {
3792 self->dm_framework = MXF_DESCRIPTIVE_METADATA_FRAMEWORK (current);
3793 } else {
3794 GST_ERROR ("Couldn't resolve DM framework %s",
3795 mxf_uuid_to_string (&self->dm_framework_uid, str));
3796 return FALSE;
3797 }
3798 } else {
3799 GST_ERROR ("Couldn't find DM framework %s",
3800 mxf_uuid_to_string (&self->dm_framework_uid, str));
3801 return FALSE;
3802 }
3803
3804
3805 return
3806 MXF_METADATA_BASE_CLASS (mxf_metadata_dm_segment_parent_class)->resolve
3807 (m, metadata);
3808 }
3809
3810 static GstStructure *
mxf_metadata_dm_segment_to_structure(MXFMetadataBase * m)3811 mxf_metadata_dm_segment_to_structure (MXFMetadataBase * m)
3812 {
3813 GstStructure *ret =
3814 MXF_METADATA_BASE_CLASS
3815 (mxf_metadata_dm_segment_parent_class)->to_structure (m);
3816 MXFMetadataDMSegment *self = MXF_METADATA_DM_SEGMENT (m);
3817 guint i;
3818
3819 gst_structure_id_set (ret, MXF_QUARK (EVENT_START_POSITION), G_TYPE_INT64,
3820 self->event_start_position, NULL);
3821
3822 if (self->event_comment)
3823 gst_structure_id_set (ret, MXF_QUARK (EVENT_COMMENT), G_TYPE_STRING,
3824 self->event_comment, NULL);
3825 /* FIXME: DMS1 doesn't support serializing to a structure yet */
3826 #if 0
3827 if (self->dm_framework) {
3828 GstStructure *s =
3829 mxf_metadata_base_to_structure (MXF_METADATA_BASE (self->dm_framework));
3830
3831 gst_structure_id_set (ret, MXF_QUARK (DM_FRAMEWORK), GST_TYPE_STRUCTURE,
3832 s, NULL);
3833 gst_structure_free (s);
3834 }
3835 #endif
3836
3837 if (self->n_track_ids > 0) {
3838 GValue arr = { 0, }
3839 , val = {
3840 0,};
3841
3842 g_value_init (&arr, GST_TYPE_ARRAY);
3843
3844 for (i = 0; i < self->n_track_ids; i++) {
3845 g_value_init (&val, G_TYPE_UINT);
3846
3847 g_value_set_uint (&val, self->track_ids[i]);
3848 gst_value_array_append_value (&arr, &val);
3849 g_value_unset (&val);
3850 }
3851
3852 if (gst_value_array_get_size (&arr) > 0)
3853 gst_structure_id_set_value (ret, MXF_QUARK (TRACK_IDS), &arr);
3854
3855 g_value_unset (&arr);
3856 }
3857
3858 return ret;
3859 }
3860
3861 static GList *
mxf_metadata_dm_segment_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)3862 mxf_metadata_dm_segment_write_tags (MXFMetadataBase * m, MXFPrimerPack * primer)
3863 {
3864 MXFMetadataDMSegment *self = MXF_METADATA_DM_SEGMENT (m);
3865 GList *ret =
3866 MXF_METADATA_BASE_CLASS (mxf_metadata_dm_segment_parent_class)->write_tags
3867 (m, primer);
3868 MXFLocalTag *t;
3869
3870 if (self->event_start_position != -1) {
3871 t = g_slice_new0 (MXFLocalTag);
3872 memcpy (&t->ul, MXF_UL (EVENT_START_POSITION), 16);
3873 t->size = 8;
3874 t->data = g_slice_alloc (t->size);
3875 t->g_slice = TRUE;
3876 GST_WRITE_UINT64_BE (t->data, self->event_start_position);
3877 mxf_primer_pack_add_mapping (primer, 0x0601, &t->ul);
3878 ret = g_list_prepend (ret, t);
3879 }
3880
3881 if (self->event_comment) {
3882 t = g_slice_new0 (MXFLocalTag);
3883 memcpy (&t->ul, MXF_UL (EVENT_COMMENT), 16);
3884 t->data = mxf_utf8_to_utf16 (self->event_comment, &t->size);
3885 mxf_primer_pack_add_mapping (primer, 0x0602, &t->ul);
3886 ret = g_list_prepend (ret, t);
3887 }
3888
3889 if (self->track_ids) {
3890 guint i;
3891
3892 t = g_slice_new0 (MXFLocalTag);
3893 memcpy (&t->ul, MXF_UL (DM_SEGMENT_TRACK_IDS), 16);
3894 t->size = 8 + 4 * self->n_track_ids;
3895 t->data = g_slice_alloc (t->size);
3896 t->g_slice = TRUE;
3897 GST_WRITE_UINT32_BE (t->data, self->n_track_ids);
3898 GST_WRITE_UINT32_BE (t->data + 4, 4);
3899 for (i = 0; i < self->n_track_ids; i++)
3900 GST_WRITE_UINT32_BE (t->data + 8 + i * 4, self->track_ids[i]);
3901 mxf_primer_pack_add_mapping (primer, 0x6102, &t->ul);
3902 ret = g_list_prepend (ret, t);
3903 }
3904
3905 if (self->dm_framework) {
3906 t = g_slice_new0 (MXFLocalTag);
3907 memcpy (&t->ul, MXF_UL (DM_FRAMEWORK), 16);
3908 t->size = 16;
3909 t->data = g_slice_alloc (t->size);
3910 t->g_slice = TRUE;
3911 memcpy (t->data, &MXF_METADATA_BASE (self->dm_framework)->instance_uid, 16);
3912 mxf_primer_pack_add_mapping (primer, 0x6101, &t->ul);
3913 ret = g_list_prepend (ret, t);
3914 }
3915
3916 return ret;
3917 }
3918
3919 static void
mxf_metadata_dm_segment_init(MXFMetadataDMSegment * self)3920 mxf_metadata_dm_segment_init (MXFMetadataDMSegment * self)
3921 {
3922 self->event_start_position = -1;
3923 }
3924
3925 static void
mxf_metadata_dm_segment_class_init(MXFMetadataDMSegmentClass * klass)3926 mxf_metadata_dm_segment_class_init (MXFMetadataDMSegmentClass * klass)
3927 {
3928 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
3929 GObjectClass *object_class = (GObjectClass *) klass;
3930 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
3931
3932 object_class->finalize = mxf_metadata_dm_segment_finalize;
3933 metadata_base_class->handle_tag = mxf_metadata_dm_segment_handle_tag;
3934 metadata_base_class->resolve = mxf_metadata_dm_segment_resolve;
3935 metadata_base_class->name_quark = MXF_QUARK (DM_SEGMENT);
3936 metadata_base_class->to_structure = mxf_metadata_dm_segment_to_structure;
3937 metadata_base_class->write_tags = mxf_metadata_dm_segment_write_tags;
3938 metadata_class->type = 0x0141;
3939 }
3940
3941 G_DEFINE_ABSTRACT_TYPE (MXFMetadataGenericDescriptor,
3942 mxf_metadata_generic_descriptor, MXF_TYPE_METADATA);
3943
3944 static void
mxf_metadata_generic_descriptor_finalize(GObject * object)3945 mxf_metadata_generic_descriptor_finalize (GObject * object)
3946 {
3947 MXFMetadataGenericDescriptor *self = MXF_METADATA_GENERIC_DESCRIPTOR (object);
3948
3949 g_free (self->locators_uids);
3950 self->locators_uids = NULL;
3951
3952 g_free (self->locators);
3953 self->locators = NULL;
3954
3955 G_OBJECT_CLASS (mxf_metadata_generic_descriptor_parent_class)->finalize
3956 (object);
3957 }
3958
3959 static gboolean
mxf_metadata_generic_descriptor_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)3960 mxf_metadata_generic_descriptor_handle_tag (MXFMetadataBase * metadata,
3961 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
3962 guint tag_size)
3963 {
3964 MXFMetadataGenericDescriptor *self =
3965 MXF_METADATA_GENERIC_DESCRIPTOR (metadata);
3966 gboolean ret = TRUE;
3967 #ifndef GST_DISABLE_GST_DEBUG
3968 gchar str[48];
3969 #endif
3970
3971 switch (tag) {
3972 case 0x2f01:
3973 if (!mxf_uuid_array_parse (&self->locators_uids, &self->n_locators,
3974 tag_data, tag_size))
3975 goto error;
3976
3977 GST_DEBUG (" number of locators = %u", self->n_locators);
3978 #ifndef GST_DISABLE_GST_DEBUG
3979 {
3980 guint i;
3981 for (i = 0; i < self->n_locators; i++) {
3982 GST_DEBUG (" locator %u = %s", i,
3983 mxf_uuid_to_string (&self->locators_uids[i], str));
3984 }
3985 }
3986 #endif
3987 break;
3988 default:
3989 ret =
3990 MXF_METADATA_BASE_CLASS
3991 (mxf_metadata_generic_descriptor_parent_class)->handle_tag (metadata,
3992 primer, tag, tag_data, tag_size);
3993 break;
3994 }
3995
3996 return ret;
3997
3998 error:
3999
4000 GST_ERROR ("Invalid generic descriptor local tag 0x%04x of size %u", tag,
4001 tag_size);
4002
4003 return FALSE;
4004 }
4005
4006 static gboolean
mxf_metadata_generic_descriptor_resolve(MXFMetadataBase * m,GHashTable * metadata)4007 mxf_metadata_generic_descriptor_resolve (MXFMetadataBase * m,
4008 GHashTable * metadata)
4009 {
4010 MXFMetadataGenericDescriptor *self = MXF_METADATA_GENERIC_DESCRIPTOR (m);
4011 MXFMetadataBase *current = NULL;
4012 guint i;
4013 gboolean have_locator = FALSE;
4014 #ifndef GST_DISABLE_GST_DEBUG
4015 gchar str[48];
4016 #endif
4017
4018 if (self->locators)
4019 memset (self->locators, 0, sizeof (gpointer) * self->n_locators);
4020 else
4021 self->locators = g_new0 (MXFMetadataLocator *, self->n_locators);
4022 for (i = 0; i < self->n_locators; i++) {
4023 current = g_hash_table_lookup (metadata, &self->locators_uids[i]);
4024 if (current && MXF_IS_METADATA_LOCATOR (current)) {
4025 if (mxf_metadata_base_resolve (current, metadata)) {
4026 self->locators[i] = MXF_METADATA_LOCATOR (current);
4027 have_locator = TRUE;
4028 } else {
4029 GST_ERROR ("Couldn't resolve locator %s",
4030 mxf_uuid_to_string (&self->locators_uids[i], str));
4031 }
4032 } else {
4033 GST_ERROR ("Locator %s not found",
4034 mxf_uuid_to_string (&self->locators_uids[i], str));
4035 }
4036 }
4037
4038 if (!have_locator && self->n_locators > 0) {
4039 GST_ERROR ("Couldn't resolve a locator");
4040 return FALSE;
4041 }
4042
4043 return
4044 MXF_METADATA_BASE_CLASS
4045 (mxf_metadata_generic_descriptor_parent_class)->resolve (m, metadata);
4046 }
4047
4048 static GstStructure *
mxf_metadata_generic_descriptor_to_structure(MXFMetadataBase * m)4049 mxf_metadata_generic_descriptor_to_structure (MXFMetadataBase * m)
4050 {
4051 GstStructure *ret =
4052 MXF_METADATA_BASE_CLASS
4053 (mxf_metadata_generic_descriptor_parent_class)->to_structure (m);
4054 MXFMetadataGenericDescriptor *self = MXF_METADATA_GENERIC_DESCRIPTOR (m);
4055 guint i;
4056
4057 if (self->n_locators > 0) {
4058 GValue arr = { 0, }
4059 , val = {
4060 0,};
4061
4062 g_value_init (&arr, GST_TYPE_ARRAY);
4063
4064 for (i = 0; i < self->n_locators; i++) {
4065 GstStructure *s;
4066
4067 if (self->locators[i] == NULL)
4068 continue;
4069
4070 g_value_init (&val, GST_TYPE_STRUCTURE);
4071
4072 s = mxf_metadata_base_to_structure (MXF_METADATA_BASE (self->locators
4073 [i]));
4074 gst_value_set_structure (&val, s);
4075 gst_structure_free (s);
4076 gst_value_array_append_value (&arr, &val);
4077 g_value_unset (&val);
4078 }
4079
4080 if (gst_value_array_get_size (&arr) > 0)
4081 gst_structure_id_set_value (ret, MXF_QUARK (LOCATORS), &arr);
4082
4083 g_value_unset (&arr);
4084 }
4085
4086 return ret;
4087 }
4088
4089 static GList *
mxf_metadata_generic_descriptor_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)4090 mxf_metadata_generic_descriptor_write_tags (MXFMetadataBase * m,
4091 MXFPrimerPack * primer)
4092 {
4093 MXFMetadataGenericDescriptor *self = MXF_METADATA_GENERIC_DESCRIPTOR (m);
4094 GList *ret =
4095 MXF_METADATA_BASE_CLASS
4096 (mxf_metadata_generic_descriptor_parent_class)->write_tags (m, primer);
4097 MXFLocalTag *t;
4098
4099 if (self->locators) {
4100 guint i;
4101
4102 t = g_slice_new0 (MXFLocalTag);
4103 memcpy (&t->ul, MXF_UL (LOCATORS), 16);
4104 t->size = 8 + 16 * self->n_locators;
4105 t->data = g_slice_alloc0 (t->size);
4106 t->g_slice = TRUE;
4107 GST_WRITE_UINT32_BE (t->data, self->n_locators);
4108 GST_WRITE_UINT32_BE (t->data + 4, 16);
4109 for (i = 0; i < self->n_locators; i++) {
4110 if (!self->locators[i])
4111 continue;
4112 memcpy (t->data + 8 + 16 * i,
4113 &MXF_METADATA_BASE (self->locators[i])->instance_uid, 16);
4114 }
4115 mxf_primer_pack_add_mapping (primer, 0x2f01, &t->ul);
4116 ret = g_list_prepend (ret, t);
4117 }
4118
4119 return ret;
4120 }
4121
4122 static void
mxf_metadata_generic_descriptor_init(MXFMetadataGenericDescriptor * self)4123 mxf_metadata_generic_descriptor_init (MXFMetadataGenericDescriptor * self)
4124 {
4125
4126 }
4127
4128 static void
mxf_metadata_generic_descriptor_class_init(MXFMetadataGenericDescriptorClass * klass)4129 mxf_metadata_generic_descriptor_class_init (MXFMetadataGenericDescriptorClass *
4130 klass)
4131 {
4132 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
4133 GObjectClass *object_class = (GObjectClass *) klass;
4134
4135 object_class->finalize = mxf_metadata_generic_descriptor_finalize;
4136 metadata_base_class->handle_tag = mxf_metadata_generic_descriptor_handle_tag;
4137 metadata_base_class->resolve = mxf_metadata_generic_descriptor_resolve;
4138 metadata_base_class->to_structure =
4139 mxf_metadata_generic_descriptor_to_structure;
4140 metadata_base_class->write_tags = mxf_metadata_generic_descriptor_write_tags;
4141 }
4142
4143 G_DEFINE_TYPE (MXFMetadataFileDescriptor, mxf_metadata_file_descriptor,
4144 MXF_TYPE_METADATA_GENERIC_DESCRIPTOR);
4145
4146 static gboolean
mxf_metadata_file_descriptor_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)4147 mxf_metadata_file_descriptor_handle_tag (MXFMetadataBase * metadata,
4148 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
4149 guint tag_size)
4150 {
4151 MXFMetadataFileDescriptor *self = MXF_METADATA_FILE_DESCRIPTOR (metadata);
4152 gboolean ret = TRUE;
4153 #ifndef GST_DISABLE_GST_DEBUG
4154 gchar str[48];
4155 #endif
4156
4157 switch (tag) {
4158 case 0x3006:
4159 if (tag_size != 4)
4160 goto error;
4161 self->linked_track_id = GST_READ_UINT32_BE (tag_data);
4162 GST_DEBUG (" linked track id = %u", self->linked_track_id);
4163 break;
4164 case 0x3001:
4165 if (!mxf_fraction_parse (&self->sample_rate, tag_data, tag_size))
4166 goto error;
4167 GST_DEBUG (" sample rate = %d/%d", self->sample_rate.n,
4168 self->sample_rate.d);
4169 break;
4170 case 0x3002:
4171 if (tag_size != 8)
4172 goto error;
4173 self->container_duration = GST_READ_UINT64_BE (tag_data);
4174 GST_DEBUG (" container duration = %" G_GINT64_FORMAT,
4175 self->container_duration);
4176 break;
4177 case 0x3004:
4178 if (tag_size != 16)
4179 goto error;
4180 memcpy (&self->essence_container, tag_data, 16);
4181 GST_DEBUG (" essence container = %s",
4182 mxf_ul_to_string (&self->essence_container, str));
4183 break;
4184 case 0x3005:
4185 if (tag_size != 16)
4186 goto error;
4187 memcpy (&self->codec, tag_data, 16);
4188 GST_DEBUG (" codec = %s", mxf_ul_to_string (&self->codec, str));
4189 break;
4190 default:
4191 ret =
4192 MXF_METADATA_BASE_CLASS
4193 (mxf_metadata_file_descriptor_parent_class)->handle_tag (metadata,
4194 primer, tag, tag_data, tag_size);
4195 break;
4196 }
4197
4198 return ret;
4199
4200 error:
4201
4202 GST_ERROR ("Invalid file descriptor local tag 0x%04x of size %u", tag,
4203 tag_size);
4204
4205 return FALSE;
4206 }
4207
4208 static GstStructure *
mxf_metadata_file_descriptor_to_structure(MXFMetadataBase * m)4209 mxf_metadata_file_descriptor_to_structure (MXFMetadataBase * m)
4210 {
4211 GstStructure *ret =
4212 MXF_METADATA_BASE_CLASS
4213 (mxf_metadata_file_descriptor_parent_class)->to_structure (m);
4214 MXFMetadataFileDescriptor *self = MXF_METADATA_FILE_DESCRIPTOR (m);
4215 gchar str[48];
4216
4217 if (self->linked_track_id)
4218 gst_structure_id_set (ret, MXF_QUARK (LINKED_TRACK_ID), G_TYPE_UINT,
4219 self->linked_track_id, NULL);
4220
4221 if (self->sample_rate.n && self->sample_rate.d)
4222 gst_structure_id_set (ret, MXF_QUARK (SAMPLE_RATE), GST_TYPE_FRACTION,
4223 self->sample_rate.n, self->sample_rate.d, NULL);
4224
4225 if (self->container_duration)
4226 gst_structure_id_set (ret, MXF_QUARK (CONTAINER_DURATION), G_TYPE_INT64,
4227 self->container_duration, NULL);
4228
4229 mxf_ul_to_string (&self->essence_container, str);
4230 gst_structure_id_set (ret, MXF_QUARK (ESSENCE_CONTAINER), G_TYPE_STRING, str,
4231 NULL);
4232
4233 if (!mxf_ul_is_zero (&self->codec)) {
4234 mxf_ul_to_string (&self->codec, str);
4235 gst_structure_id_set (ret, MXF_QUARK (CODEC), G_TYPE_STRING, str, NULL);
4236 }
4237
4238 return ret;
4239 }
4240
4241 static GList *
mxf_metadata_file_descriptor_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)4242 mxf_metadata_file_descriptor_write_tags (MXFMetadataBase * m,
4243 MXFPrimerPack * primer)
4244 {
4245 MXFMetadataFileDescriptor *self = MXF_METADATA_FILE_DESCRIPTOR (m);
4246 GList *ret =
4247 MXF_METADATA_BASE_CLASS
4248 (mxf_metadata_file_descriptor_parent_class)->write_tags (m, primer);
4249 MXFLocalTag *t;
4250
4251 if (self->linked_track_id) {
4252 t = g_slice_new0 (MXFLocalTag);
4253 memcpy (&t->ul, MXF_UL (LINKED_TRACK_ID), 16);
4254 t->size = 4;
4255 t->data = g_slice_alloc (t->size);
4256 t->g_slice = TRUE;
4257 GST_WRITE_UINT32_BE (t->data, self->linked_track_id);
4258 mxf_primer_pack_add_mapping (primer, 0x3006, &t->ul);
4259 ret = g_list_prepend (ret, t);
4260 }
4261
4262 t = g_slice_new0 (MXFLocalTag);
4263 memcpy (&t->ul, MXF_UL (SAMPLE_RATE), 16);
4264 t->size = 8;
4265 t->data = g_slice_alloc (t->size);
4266 t->g_slice = TRUE;
4267 GST_WRITE_UINT32_BE (t->data, self->sample_rate.n);
4268 GST_WRITE_UINT32_BE (t->data + 4, self->sample_rate.d);
4269 mxf_primer_pack_add_mapping (primer, 0x3001, &t->ul);
4270 ret = g_list_prepend (ret, t);
4271
4272 if (self->container_duration > 0) {
4273 t = g_slice_new0 (MXFLocalTag);
4274 memcpy (&t->ul, MXF_UL (CONTAINER_DURATION), 16);
4275 t->size = 8;
4276 t->data = g_slice_alloc (t->size);
4277 t->g_slice = TRUE;
4278 GST_WRITE_UINT64_BE (t->data, self->container_duration);
4279 mxf_primer_pack_add_mapping (primer, 0x3002, &t->ul);
4280 ret = g_list_prepend (ret, t);
4281 }
4282
4283 t = g_slice_new0 (MXFLocalTag);
4284 memcpy (&t->ul, MXF_UL (ESSENCE_CONTAINER), 16);
4285 t->size = 16;
4286 t->data = g_slice_alloc (t->size);
4287 t->g_slice = TRUE;
4288 memcpy (t->data, &self->essence_container, 16);
4289 mxf_primer_pack_add_mapping (primer, 0x3004, &t->ul);
4290 ret = g_list_prepend (ret, t);
4291
4292 if (!mxf_ul_is_zero (&self->codec)) {
4293 t = g_slice_new0 (MXFLocalTag);
4294 memcpy (&t->ul, MXF_UL (CODEC), 16);
4295 t->size = 16;
4296 t->data = g_slice_alloc (t->size);
4297 t->g_slice = TRUE;
4298 memcpy (t->data, &self->codec, 16);
4299 mxf_primer_pack_add_mapping (primer, 0x3005, &t->ul);
4300 ret = g_list_prepend (ret, t);
4301 }
4302
4303 return ret;
4304 }
4305
4306 static void
mxf_metadata_file_descriptor_init(MXFMetadataFileDescriptor * self)4307 mxf_metadata_file_descriptor_init (MXFMetadataFileDescriptor * self)
4308 {
4309
4310 }
4311
4312 static void
mxf_metadata_file_descriptor_class_init(MXFMetadataFileDescriptorClass * klass)4313 mxf_metadata_file_descriptor_class_init (MXFMetadataFileDescriptorClass * klass)
4314 {
4315 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
4316 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
4317
4318 metadata_base_class->handle_tag = mxf_metadata_file_descriptor_handle_tag;
4319 metadata_base_class->name_quark = MXF_QUARK (FILE_DESCRIPTOR);
4320 metadata_base_class->to_structure = mxf_metadata_file_descriptor_to_structure;
4321 metadata_base_class->write_tags = mxf_metadata_file_descriptor_write_tags;
4322 metadata_class->type = 0x0125;
4323 }
4324
4325 G_DEFINE_TYPE (MXFMetadataGenericPictureEssenceDescriptor,
4326 mxf_metadata_generic_picture_essence_descriptor,
4327 MXF_TYPE_METADATA_FILE_DESCRIPTOR);
4328
4329 static gboolean
mxf_metadata_generic_picture_essence_descriptor_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)4330 mxf_metadata_generic_picture_essence_descriptor_handle_tag (MXFMetadataBase *
4331 metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
4332 guint tag_size)
4333 {
4334 MXFMetadataGenericPictureEssenceDescriptor *self =
4335 MXF_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (metadata);
4336 gboolean ret = TRUE;
4337 #ifndef GST_DISABLE_GST_DEBUG
4338 gchar str[48];
4339 #endif
4340
4341 switch (tag) {
4342 case 0x3215:
4343 if (tag_size != 1)
4344 goto error;
4345 self->signal_standard = GST_READ_UINT8 (tag_data);
4346 GST_DEBUG (" signal standard = %u", self->signal_standard);
4347 break;
4348 case 0x320c:
4349 if (tag_size != 1)
4350 goto error;
4351 self->frame_layout = GST_READ_UINT8 (tag_data);
4352 GST_DEBUG (" frame layout = %u", self->frame_layout);
4353 break;
4354 case 0x3203:
4355 if (tag_size != 4)
4356 goto error;
4357 self->stored_width = GST_READ_UINT32_BE (tag_data);
4358 GST_DEBUG (" stored width = %u", self->stored_width);
4359 break;
4360 case 0x3202:
4361 if (tag_size != 4)
4362 goto error;
4363 self->stored_height = GST_READ_UINT32_BE (tag_data);
4364 GST_DEBUG (" stored height = %u", self->stored_height);
4365 break;
4366 case 0x3216:
4367 if (tag_size != 4)
4368 goto error;
4369 self->stored_f2_offset = GST_READ_UINT32_BE (tag_data);
4370 GST_DEBUG (" stored f2 offset = %d", self->stored_f2_offset);
4371 break;
4372 case 0x3205:
4373 if (tag_size != 4)
4374 goto error;
4375 self->sampled_width = GST_READ_UINT32_BE (tag_data);
4376 GST_DEBUG (" sampled width = %u", self->sampled_width);
4377 break;
4378 case 0x3204:
4379 if (tag_size != 4)
4380 goto error;
4381 self->sampled_height = GST_READ_UINT32_BE (tag_data);
4382 GST_DEBUG (" sampled height = %u", self->sampled_height);
4383 break;
4384 case 0x3206:
4385 if (tag_size != 4)
4386 goto error;
4387 self->sampled_x_offset = GST_READ_UINT32_BE (tag_data);
4388 GST_DEBUG (" sampled x offset = %d", self->sampled_x_offset);
4389 break;
4390 case 0x3207:
4391 if (tag_size != 4)
4392 goto error;
4393 self->sampled_y_offset = GST_READ_UINT32_BE (tag_data);
4394 GST_DEBUG (" sampled y offset = %d", self->sampled_y_offset);
4395 break;
4396 case 0x3208:
4397 if (tag_size != 4)
4398 goto error;
4399 self->display_height = GST_READ_UINT32_BE (tag_data);
4400 GST_DEBUG (" display height = %u", self->display_height);
4401 break;
4402 case 0x3209:
4403 if (tag_size != 4)
4404 goto error;
4405 self->display_width = GST_READ_UINT32_BE (tag_data);
4406 GST_DEBUG (" display width = %u", self->display_width);
4407 break;
4408 case 0x320a:
4409 if (tag_size != 4)
4410 goto error;
4411 self->display_x_offset = GST_READ_UINT32_BE (tag_data);
4412 GST_DEBUG (" display x offset = %d", self->display_x_offset);
4413 break;
4414 case 0x320b:
4415 if (tag_size != 4)
4416 goto error;
4417 self->display_y_offset = GST_READ_UINT32_BE (tag_data);
4418 GST_DEBUG (" display y offset = %d", self->display_y_offset);
4419 break;
4420 case 0x3217:
4421 if (tag_size != 4)
4422 goto error;
4423 self->display_f2_offset = GST_READ_UINT32_BE (tag_data);
4424 GST_DEBUG (" display f2 offset = %d", self->display_f2_offset);
4425 break;
4426 case 0x320e:
4427 if (!mxf_fraction_parse (&self->aspect_ratio, tag_data, tag_size))
4428 goto error;
4429 GST_DEBUG (" aspect ratio = %d/%d", self->aspect_ratio.n,
4430 self->aspect_ratio.d);
4431 break;
4432 case 0x3218:
4433 if (tag_size != 1)
4434 goto error;
4435 self->active_format_descriptor = GST_READ_UINT8 (tag_data);
4436 GST_DEBUG (" active format descriptor = %u",
4437 self->active_format_descriptor);
4438 break;
4439 case 0x320d:
4440 if (tag_size < 8)
4441 goto error;
4442
4443 if (GST_READ_UINT32_BE (tag_data) == 0)
4444 return TRUE;
4445
4446 if (GST_READ_UINT32_BE (tag_data + 4) != 4)
4447 goto error;
4448
4449 if (GST_READ_UINT32_BE (tag_data) != 1 &&
4450 GST_READ_UINT32_BE (tag_data) != 2)
4451 goto error;
4452
4453 if ((GST_READ_UINT32_BE (tag_data) == 1 && tag_size != 12) ||
4454 (GST_READ_UINT32_BE (tag_data) == 2 && tag_size != 16))
4455 goto error;
4456
4457 self->video_line_map[0] = GST_READ_UINT32_BE (tag_data + 8);
4458
4459 /* Workaround for files created by ffmpeg */
4460 if (GST_READ_UINT32_BE (tag_data) == 1)
4461 self->video_line_map[0] = 0;
4462 else
4463 self->video_line_map[1] = GST_READ_UINT32_BE (tag_data + 12);
4464
4465 GST_DEBUG (" video line map = {%i, %i}", self->video_line_map[0],
4466 self->video_line_map[1]);
4467 break;
4468 case 0x320f:
4469 if (tag_size != 1)
4470 goto error;
4471 self->alpha_transparency = GST_READ_UINT8 (tag_data);
4472 GST_DEBUG (" alpha transparency = %u", self->alpha_transparency);
4473 break;
4474 case 0x3210:
4475 if (tag_size != 16)
4476 goto error;
4477 memcpy (&self->capture_gamma, tag_data, 16);
4478 GST_DEBUG (" capture gamma = %s",
4479 mxf_ul_to_string (&self->capture_gamma, str));
4480 break;
4481 case 0x3211:
4482 if (tag_size != 4)
4483 goto error;
4484 self->image_alignment_offset = GST_READ_UINT32_BE (tag_data);
4485 GST_DEBUG (" image alignment offset = %u", self->image_alignment_offset);
4486 break;
4487 case 0x3213:
4488 if (tag_size != 4)
4489 goto error;
4490 self->image_start_offset = GST_READ_UINT32_BE (tag_data);
4491 GST_DEBUG (" image start offset = %u", self->image_start_offset);
4492 break;
4493 case 0x3214:
4494 if (tag_size != 4)
4495 goto error;
4496 self->image_end_offset = GST_READ_UINT32_BE (tag_data);
4497 GST_DEBUG (" image end offset = %u", self->image_end_offset);
4498 break;
4499 case 0x3212:
4500 if (tag_size != 1)
4501 goto error;
4502 self->field_dominance = GST_READ_UINT8 (tag_data);
4503 GST_DEBUG (" field dominance = %u", self->field_dominance);
4504 break;
4505 case 0x3201:
4506 if (tag_size != 16)
4507 goto error;
4508 memcpy (&self->picture_essence_coding, tag_data, 16);
4509 GST_DEBUG (" picture essence coding = %s",
4510 mxf_ul_to_string (&self->picture_essence_coding, str));
4511 break;
4512 default:
4513 ret =
4514 MXF_METADATA_BASE_CLASS
4515 (mxf_metadata_generic_picture_essence_descriptor_parent_class)->handle_tag
4516 (metadata, primer, tag, tag_data, tag_size);
4517 break;
4518 }
4519
4520 return ret;
4521
4522 error:
4523
4524 GST_ERROR
4525 ("Invalid generic picture essence descriptor local tag 0x%04x of size %u",
4526 tag, tag_size);
4527
4528 return FALSE;
4529 }
4530
4531 static GstStructure *
mxf_metadata_generic_picture_essence_descriptor_to_structure(MXFMetadataBase * m)4532 mxf_metadata_generic_picture_essence_descriptor_to_structure (MXFMetadataBase *
4533 m)
4534 {
4535 GstStructure *ret =
4536 MXF_METADATA_BASE_CLASS
4537 (mxf_metadata_generic_picture_essence_descriptor_parent_class)->to_structure
4538 (m);
4539 MXFMetadataGenericPictureEssenceDescriptor *self =
4540 MXF_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (m);
4541 gchar str[48];
4542
4543 gst_structure_id_set (ret, MXF_QUARK (SIGNAL_STANDARD), G_TYPE_UCHAR,
4544 self->signal_standard, NULL);
4545
4546 gst_structure_id_set (ret, MXF_QUARK (FRAME_LAYOUT), G_TYPE_UCHAR,
4547 self->frame_layout, NULL);
4548
4549 gst_structure_id_set (ret, MXF_QUARK (STORED_WIDTH), G_TYPE_UINT,
4550 self->stored_width, MXF_QUARK (STORED_HEIGHT), G_TYPE_UINT,
4551 self->stored_height, NULL);
4552
4553 if (self->stored_f2_offset != 0)
4554 gst_structure_id_set (ret, MXF_QUARK (STORED_F2_OFFSET), G_TYPE_INT,
4555 self->stored_f2_offset, NULL);
4556
4557 if (self->sampled_width != 0 && self->sampled_height != 0)
4558 gst_structure_id_set (ret, MXF_QUARK (SAMPLED_WIDTH), G_TYPE_UINT,
4559 self->sampled_width, MXF_QUARK (SAMPLED_HEIGHT), G_TYPE_UINT,
4560 self->sampled_height, NULL);
4561
4562 if (self->sampled_x_offset != 0)
4563 gst_structure_id_set (ret, MXF_QUARK (SAMPLED_X_OFFSET), G_TYPE_INT,
4564 self->sampled_x_offset, NULL);
4565
4566 if (self->sampled_y_offset != 0)
4567 gst_structure_id_set (ret, MXF_QUARK (SAMPLED_Y_OFFSET), G_TYPE_INT,
4568 self->sampled_y_offset, NULL);
4569
4570 if (self->display_width != 0 && self->display_height != 0)
4571 gst_structure_id_set (ret, MXF_QUARK (DISPLAY_WIDTH), G_TYPE_UINT,
4572 self->display_width, MXF_QUARK (DISPLAY_HEIGHT), G_TYPE_UINT,
4573 self->display_height, NULL);
4574
4575 if (self->display_x_offset != 0)
4576 gst_structure_id_set (ret, MXF_QUARK (DISPLAY_X_OFFSET), G_TYPE_INT,
4577 self->display_x_offset, NULL);
4578
4579 if (self->display_y_offset != 0)
4580 gst_structure_id_set (ret, MXF_QUARK (DISPLAY_Y_OFFSET), G_TYPE_INT,
4581 self->display_y_offset, NULL);
4582
4583 if (self->display_f2_offset != 0)
4584 gst_structure_id_set (ret, MXF_QUARK (DISPLAY_F2_OFFSET), G_TYPE_INT,
4585 self->display_f2_offset, NULL);
4586
4587 if (self->aspect_ratio.n != 0 && self->aspect_ratio.d != 0)
4588 gst_structure_id_set (ret, MXF_QUARK (ASPECT_RATIO), GST_TYPE_FRACTION,
4589 self->aspect_ratio.n, self->aspect_ratio.d, NULL);
4590
4591 if (self->active_format_descriptor)
4592 gst_structure_id_set (ret, MXF_QUARK (ACTIVE_FORMAT_DESCRIPTOR),
4593 G_TYPE_UCHAR, self->active_format_descriptor, NULL);
4594
4595 gst_structure_id_set (ret, MXF_QUARK (VIDEO_LINE_MAP_0), G_TYPE_UINT,
4596 self->video_line_map[0], MXF_QUARK (VIDEO_LINE_MAP_1), G_TYPE_UINT,
4597 self->video_line_map[1], NULL);
4598
4599 if (self->alpha_transparency != 0)
4600 gst_structure_id_set (ret, MXF_QUARK (ALPHA_TRANSPARENCY), G_TYPE_UCHAR,
4601 self->alpha_transparency, NULL);
4602
4603 if (!mxf_ul_is_zero (&self->capture_gamma)) {
4604 mxf_ul_to_string (&self->capture_gamma, str);
4605 gst_structure_id_set (ret, MXF_QUARK (CAPTURE_GAMMA), G_TYPE_STRING, str,
4606 NULL);
4607 }
4608
4609 if (self->image_alignment_offset != 0)
4610 gst_structure_id_set (ret, MXF_QUARK (IMAGE_ALIGNMENT_OFFSET), G_TYPE_UINT,
4611 self->image_alignment_offset, NULL);
4612
4613 if (self->image_start_offset != 0)
4614 gst_structure_id_set (ret, MXF_QUARK (IMAGE_START_OFFSET), G_TYPE_UINT,
4615 self->image_start_offset, NULL);
4616
4617 if (self->image_end_offset != 0)
4618 gst_structure_id_set (ret, MXF_QUARK (IMAGE_END_OFFSET), G_TYPE_UINT,
4619 self->image_end_offset, NULL);
4620
4621 if (self->field_dominance != 0)
4622 gst_structure_id_set (ret, MXF_QUARK (FIELD_DOMINANCE), G_TYPE_UCHAR,
4623 self->field_dominance, NULL);
4624
4625 if (!mxf_ul_is_zero (&self->picture_essence_coding)) {
4626 mxf_ul_to_string (&self->picture_essence_coding, str);
4627 gst_structure_id_set (ret, MXF_QUARK (PICTURE_ESSENCE_CODING),
4628 G_TYPE_STRING, str, NULL);
4629 }
4630
4631 return ret;
4632 }
4633
4634 static GList *
mxf_metadata_generic_picture_essence_descriptor_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)4635 mxf_metadata_generic_picture_essence_descriptor_write_tags (MXFMetadataBase * m,
4636 MXFPrimerPack * primer)
4637 {
4638 MXFMetadataGenericPictureEssenceDescriptor *self =
4639 MXF_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (m);
4640 GList *ret =
4641 MXF_METADATA_BASE_CLASS
4642 (mxf_metadata_generic_picture_essence_descriptor_parent_class)->write_tags
4643 (m, primer);
4644 MXFLocalTag *t;
4645
4646 if (self->signal_standard != 1) {
4647 t = g_slice_new0 (MXFLocalTag);
4648 memcpy (&t->ul, MXF_UL (SIGNAL_STANDARD), 16);
4649 t->size = 1;
4650 t->data = g_slice_alloc (t->size);
4651 t->g_slice = TRUE;
4652 GST_WRITE_UINT8 (t->data, self->signal_standard);
4653 mxf_primer_pack_add_mapping (primer, 0x3215, &t->ul);
4654 ret = g_list_prepend (ret, t);
4655 }
4656
4657 t = g_slice_new0 (MXFLocalTag);
4658 memcpy (&t->ul, MXF_UL (FRAME_LAYOUT), 16);
4659 t->size = 1;
4660 t->data = g_slice_alloc (t->size);
4661 t->g_slice = TRUE;
4662 GST_WRITE_UINT8 (t->data, self->frame_layout);
4663 mxf_primer_pack_add_mapping (primer, 0x320c, &t->ul);
4664 ret = g_list_prepend (ret, t);
4665
4666 t = g_slice_new0 (MXFLocalTag);
4667 memcpy (&t->ul, MXF_UL (STORED_WIDTH), 16);
4668 t->size = 4;
4669 t->data = g_slice_alloc (t->size);
4670 t->g_slice = TRUE;
4671 GST_WRITE_UINT32_BE (t->data, self->stored_width);
4672 mxf_primer_pack_add_mapping (primer, 0x3203, &t->ul);
4673 ret = g_list_prepend (ret, t);
4674
4675 t = g_slice_new0 (MXFLocalTag);
4676 memcpy (&t->ul, MXF_UL (STORED_HEIGHT), 16);
4677 t->size = 4;
4678 t->data = g_slice_alloc (t->size);
4679 t->g_slice = TRUE;
4680 GST_WRITE_UINT32_BE (t->data, self->stored_height);
4681 mxf_primer_pack_add_mapping (primer, 0x3202, &t->ul);
4682 ret = g_list_prepend (ret, t);
4683
4684 if (self->stored_f2_offset != 0) {
4685 t = g_slice_new0 (MXFLocalTag);
4686 memcpy (&t->ul, MXF_UL (STORED_F2_OFFSET), 16);
4687 t->size = 4;
4688 t->data = g_slice_alloc (t->size);
4689 t->g_slice = TRUE;
4690 GST_WRITE_UINT32_BE (t->data, self->stored_f2_offset);
4691 mxf_primer_pack_add_mapping (primer, 0x3216, &t->ul);
4692 ret = g_list_prepend (ret, t);
4693 }
4694
4695 if (self->sampled_width != 0) {
4696 t = g_slice_new0 (MXFLocalTag);
4697 memcpy (&t->ul, MXF_UL (SAMPLED_WIDTH), 16);
4698 t->size = 4;
4699 t->data = g_slice_alloc (t->size);
4700 t->g_slice = TRUE;
4701 GST_WRITE_UINT32_BE (t->data, self->sampled_width);
4702 mxf_primer_pack_add_mapping (primer, 0x3205, &t->ul);
4703 ret = g_list_prepend (ret, t);
4704 }
4705
4706 if (self->sampled_height != 0) {
4707 t = g_slice_new0 (MXFLocalTag);
4708 memcpy (&t->ul, MXF_UL (SAMPLED_HEIGHT), 16);
4709 t->size = 4;
4710 t->data = g_slice_alloc (t->size);
4711 t->g_slice = TRUE;
4712 GST_WRITE_UINT32_BE (t->data, self->sampled_height);
4713 mxf_primer_pack_add_mapping (primer, 0x3204, &t->ul);
4714 ret = g_list_prepend (ret, t);
4715 }
4716
4717 if (self->sampled_x_offset != 0) {
4718 t = g_slice_new0 (MXFLocalTag);
4719 memcpy (&t->ul, MXF_UL (SAMPLED_X_OFFSET), 16);
4720 t->size = 4;
4721 t->data = g_slice_alloc (t->size);
4722 t->g_slice = TRUE;
4723 GST_WRITE_UINT32_BE (t->data, self->sampled_x_offset);
4724 mxf_primer_pack_add_mapping (primer, 0x3206, &t->ul);
4725 ret = g_list_prepend (ret, t);
4726 }
4727
4728 if (self->sampled_y_offset != 0) {
4729 t = g_slice_new0 (MXFLocalTag);
4730 memcpy (&t->ul, MXF_UL (SAMPLED_Y_OFFSET), 16);
4731 t->size = 4;
4732 t->data = g_slice_alloc (t->size);
4733 t->g_slice = TRUE;
4734 GST_WRITE_UINT32_BE (t->data, self->sampled_y_offset);
4735 mxf_primer_pack_add_mapping (primer, 0x3207, &t->ul);
4736 ret = g_list_prepend (ret, t);
4737 }
4738
4739 if (self->display_height != 0) {
4740 t = g_slice_new0 (MXFLocalTag);
4741 memcpy (&t->ul, MXF_UL (DISPLAY_HEIGHT), 16);
4742 t->size = 4;
4743 t->data = g_slice_alloc (t->size);
4744 t->g_slice = TRUE;
4745 GST_WRITE_UINT32_BE (t->data, self->display_height);
4746 mxf_primer_pack_add_mapping (primer, 0x3208, &t->ul);
4747 ret = g_list_prepend (ret, t);
4748 }
4749
4750 if (self->display_width != 0) {
4751 t = g_slice_new0 (MXFLocalTag);
4752 memcpy (&t->ul, MXF_UL (DISPLAY_WIDTH), 16);
4753 t->size = 4;
4754 t->data = g_slice_alloc (t->size);
4755 t->g_slice = TRUE;
4756 GST_WRITE_UINT32_BE (t->data, self->display_width);
4757 mxf_primer_pack_add_mapping (primer, 0x3209, &t->ul);
4758 ret = g_list_prepend (ret, t);
4759 }
4760
4761 if (self->display_x_offset != 0) {
4762 t = g_slice_new0 (MXFLocalTag);
4763 memcpy (&t->ul, MXF_UL (DISPLAY_X_OFFSET), 16);
4764 t->size = 4;
4765 t->data = g_slice_alloc (t->size);
4766 t->g_slice = TRUE;
4767 GST_WRITE_UINT32_BE (t->data, self->display_x_offset);
4768 mxf_primer_pack_add_mapping (primer, 0x320a, &t->ul);
4769 ret = g_list_prepend (ret, t);
4770 }
4771
4772 if (self->display_y_offset != 0) {
4773 t = g_slice_new0 (MXFLocalTag);
4774 memcpy (&t->ul, MXF_UL (DISPLAY_Y_OFFSET), 16);
4775 t->size = 4;
4776 t->data = g_slice_alloc (t->size);
4777 t->g_slice = TRUE;
4778 GST_WRITE_UINT32_BE (t->data, self->display_y_offset);
4779 mxf_primer_pack_add_mapping (primer, 0x320b, &t->ul);
4780 ret = g_list_prepend (ret, t);
4781 }
4782
4783 if (self->display_f2_offset != 0) {
4784 t = g_slice_new0 (MXFLocalTag);
4785 memcpy (&t->ul, MXF_UL (DISPLAY_F2_OFFSET), 16);
4786 t->size = 4;
4787 t->data = g_slice_alloc (t->size);
4788 t->g_slice = TRUE;
4789 GST_WRITE_UINT32_BE (t->data, self->display_f2_offset);
4790 mxf_primer_pack_add_mapping (primer, 0x3217, &t->ul);
4791 ret = g_list_prepend (ret, t);
4792 }
4793
4794 t = g_slice_new0 (MXFLocalTag);
4795 memcpy (&t->ul, MXF_UL (ASPECT_RATIO), 16);
4796 t->size = 8;
4797 t->data = g_slice_alloc (t->size);
4798 t->g_slice = TRUE;
4799 GST_WRITE_UINT32_BE (t->data, self->aspect_ratio.n);
4800 GST_WRITE_UINT32_BE (t->data + 4, self->aspect_ratio.d);
4801 mxf_primer_pack_add_mapping (primer, 0x320e, &t->ul);
4802 ret = g_list_prepend (ret, t);
4803
4804 if (self->active_format_descriptor != 0) {
4805 t = g_slice_new0 (MXFLocalTag);
4806 memcpy (&t->ul, MXF_UL (ACTIVE_FORMAT_DESCRIPTOR), 16);
4807 t->size = 1;
4808 t->data = g_slice_alloc (t->size);
4809 t->g_slice = TRUE;
4810 GST_WRITE_UINT8 (t->data, self->active_format_descriptor);
4811 mxf_primer_pack_add_mapping (primer, 0x3218, &t->ul);
4812 ret = g_list_prepend (ret, t);
4813 }
4814
4815 t = g_slice_new0 (MXFLocalTag);
4816 memcpy (&t->ul, MXF_UL (VIDEO_LINE_MAP), 16);
4817 t->size = 16;
4818 t->data = g_slice_alloc (t->size);
4819 t->g_slice = TRUE;
4820 GST_WRITE_UINT32_BE (t->data, 2);
4821 GST_WRITE_UINT32_BE (t->data + 4, 4);
4822 GST_WRITE_UINT32_BE (t->data + 8, self->video_line_map[0]);
4823 GST_WRITE_UINT32_BE (t->data + 12, self->video_line_map[1]);
4824 mxf_primer_pack_add_mapping (primer, 0x320d, &t->ul);
4825 ret = g_list_prepend (ret, t);
4826
4827 if (self->alpha_transparency != 0) {
4828 t = g_slice_new0 (MXFLocalTag);
4829 memcpy (&t->ul, MXF_UL (ALPHA_TRANSPARENCY), 16);
4830 t->size = 1;
4831 t->data = g_slice_alloc (t->size);
4832 t->g_slice = TRUE;
4833 GST_WRITE_UINT8 (t->data, self->alpha_transparency);
4834 mxf_primer_pack_add_mapping (primer, 0x320f, &t->ul);
4835 ret = g_list_prepend (ret, t);
4836 }
4837
4838 if (!mxf_ul_is_zero (&self->capture_gamma)) {
4839 t = g_slice_new0 (MXFLocalTag);
4840 memcpy (&t->ul, MXF_UL (CAPTURE_GAMMA), 16);
4841 t->size = 16;
4842 t->data = g_slice_alloc (t->size);
4843 t->g_slice = TRUE;
4844 memcpy (t->data, &self->capture_gamma, 16);
4845 mxf_primer_pack_add_mapping (primer, 0x3210, &t->ul);
4846 ret = g_list_prepend (ret, t);
4847 }
4848
4849 if (self->image_alignment_offset != 0) {
4850 t = g_slice_new0 (MXFLocalTag);
4851 memcpy (&t->ul, MXF_UL (IMAGE_ALIGNMENT_OFFSET), 16);
4852 t->size = 4;
4853 t->data = g_slice_alloc (t->size);
4854 t->g_slice = TRUE;
4855 GST_WRITE_UINT32_BE (t->data, self->image_alignment_offset);
4856 mxf_primer_pack_add_mapping (primer, 0x3211, &t->ul);
4857 ret = g_list_prepend (ret, t);
4858 }
4859
4860 if (self->image_start_offset != 0) {
4861 t = g_slice_new0 (MXFLocalTag);
4862 memcpy (&t->ul, MXF_UL (IMAGE_START_OFFSET), 16);
4863 t->size = 4;
4864 t->data = g_slice_alloc (t->size);
4865 t->g_slice = TRUE;
4866 GST_WRITE_UINT32_BE (t->data, self->image_start_offset);
4867 mxf_primer_pack_add_mapping (primer, 0x3213, &t->ul);
4868 ret = g_list_prepend (ret, t);
4869 }
4870
4871 if (self->image_end_offset != 0) {
4872 t = g_slice_new0 (MXFLocalTag);
4873 memcpy (&t->ul, MXF_UL (IMAGE_END_OFFSET), 16);
4874 t->size = 4;
4875 t->data = g_slice_alloc (t->size);
4876 t->g_slice = TRUE;
4877 GST_WRITE_UINT32_BE (t->data, self->image_end_offset);
4878 mxf_primer_pack_add_mapping (primer, 0x3214, &t->ul);
4879 ret = g_list_prepend (ret, t);
4880 }
4881
4882 if (self->field_dominance != 0) {
4883 t = g_slice_new0 (MXFLocalTag);
4884 memcpy (&t->ul, MXF_UL (FIELD_DOMINANCE), 16);
4885 t->size = 1;
4886 t->data = g_slice_alloc (t->size);
4887 t->g_slice = TRUE;
4888 GST_WRITE_UINT8 (t->data, self->field_dominance);
4889 mxf_primer_pack_add_mapping (primer, 0x3212, &t->ul);
4890 ret = g_list_prepend (ret, t);
4891 }
4892
4893 if (!mxf_ul_is_zero (&self->picture_essence_coding)) {
4894 t = g_slice_new0 (MXFLocalTag);
4895 memcpy (&t->ul, MXF_UL (PICTURE_ESSENCE_CODING), 16);
4896 t->size = 16;
4897 t->data = g_slice_alloc (t->size);
4898 t->g_slice = TRUE;
4899 memcpy (t->data, &self->picture_essence_coding, 16);
4900 mxf_primer_pack_add_mapping (primer, 0x3201, &t->ul);
4901 ret = g_list_prepend (ret, t);
4902 }
4903
4904 return ret;
4905 }
4906
4907 static void
mxf_metadata_generic_picture_essence_descriptor_init(MXFMetadataGenericPictureEssenceDescriptor * self)4908 mxf_metadata_generic_picture_essence_descriptor_init
4909 (MXFMetadataGenericPictureEssenceDescriptor * self)
4910 {
4911 self->signal_standard = 1;
4912 self->frame_layout = 255;
4913 }
4914
4915 static void
mxf_metadata_generic_picture_essence_descriptor_class_init(MXFMetadataGenericPictureEssenceDescriptorClass * klass)4916 mxf_metadata_generic_picture_essence_descriptor_class_init
4917 (MXFMetadataGenericPictureEssenceDescriptorClass * klass)
4918 {
4919 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
4920 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
4921
4922 metadata_base_class->handle_tag =
4923 mxf_metadata_generic_picture_essence_descriptor_handle_tag;
4924 metadata_base_class->name_quark =
4925 MXF_QUARK (GENERIC_PICTURE_ESSENCE_DESCRIPTOR);
4926 metadata_base_class->to_structure =
4927 mxf_metadata_generic_picture_essence_descriptor_to_structure;
4928 metadata_base_class->write_tags =
4929 mxf_metadata_generic_picture_essence_descriptor_write_tags;
4930 metadata_class->type = 0x0127;
4931 }
4932
mxf_metadata_generic_picture_essence_descriptor_set_caps(MXFMetadataGenericPictureEssenceDescriptor * self,GstCaps * caps)4933 void mxf_metadata_generic_picture_essence_descriptor_set_caps
4934 (MXFMetadataGenericPictureEssenceDescriptor * self, GstCaps * caps)
4935 {
4936 guint par_n, par_d;
4937 guint width, height;
4938 MXFMetadataFileDescriptor *f = (MXFMetadataFileDescriptor *) self;
4939
4940 g_return_if_fail (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (self));
4941 g_return_if_fail (GST_IS_CAPS (caps));
4942
4943 if (f->sample_rate.d == 0) {
4944 GST_ERROR ("Invalid framerate");
4945 } else {
4946 gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION, f->sample_rate.n,
4947 f->sample_rate.d, NULL);
4948 }
4949
4950 width = self->stored_width;
4951 height = self->stored_height;
4952 if (self->sampled_width && self->sampled_height) {
4953 width = self->sampled_width;
4954 height = self->sampled_height;
4955 }
4956 if (self->display_width && self->display_height) {
4957 width = self->display_width;
4958 height = self->display_height;
4959 }
4960
4961 /* If the video is stored as separate fields the
4962 * height is only the height of one field, i.e.
4963 * half the height of the frame.
4964 *
4965 * See SMPTE 377M E2.2 and E1.2
4966 */
4967 if (self->frame_layout == 1 || self->frame_layout == 2
4968 || self->frame_layout == 4) {
4969 height *= 2;
4970 gst_caps_set_simple (caps, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL);
4971
4972 if (self->field_dominance == 2) {
4973 gst_caps_set_simple (caps, "field-order", G_TYPE_STRING,
4974 "bottom-field-first", NULL);
4975 } else {
4976 gst_caps_set_simple (caps, "field-order", G_TYPE_STRING,
4977 "top-field-first", NULL);
4978 }
4979 }
4980
4981 if (width == 0 || height == 0) {
4982 GST_ERROR ("Invalid width/height");
4983 return;
4984 }
4985
4986 gst_caps_set_simple (caps, "width", G_TYPE_INT, width, "height", G_TYPE_INT,
4987 height, NULL);
4988
4989 if (self->aspect_ratio.n == 0 && self->aspect_ratio.d == 0) {
4990 gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
4991 1, 1, NULL);
4992 } else if (self->aspect_ratio.n == 0 || self->aspect_ratio.d == 0) {
4993 GST_ERROR ("Invalid aspect ratio");
4994 } else {
4995 par_n = height * self->aspect_ratio.n;
4996 par_d = width * self->aspect_ratio.d;
4997
4998 gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
4999 par_n, par_d, NULL);
5000 }
5001 }
5002
5003 static gint
gst_greatest_common_divisor(gint a,gint b)5004 gst_greatest_common_divisor (gint a, gint b)
5005 {
5006 while (b != 0) {
5007 int temp = a;
5008
5009 a = b;
5010 b = temp % b;
5011 }
5012
5013 return ABS (a);
5014 }
5015
5016 gboolean
mxf_metadata_generic_picture_essence_descriptor_from_caps(MXFMetadataGenericPictureEssenceDescriptor * self,GstCaps * caps)5017 mxf_metadata_generic_picture_essence_descriptor_from_caps
5018 (MXFMetadataGenericPictureEssenceDescriptor * self, GstCaps * caps) {
5019 gint par_n, par_d, gcd;
5020 gint width, height;
5021 gint fps_n, fps_d;
5022 MXFMetadataFileDescriptor *f = (MXFMetadataFileDescriptor *) self;
5023 GstStructure *s;
5024 gboolean interlaced = FALSE;
5025 const gchar *field_order = NULL;
5026
5027 g_return_val_if_fail (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR
5028 (self), FALSE);
5029 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
5030
5031 s = gst_caps_get_structure (caps, 0);
5032
5033 if (!gst_structure_get_boolean (s, "interlaced", &interlaced) || !interlaced) {
5034 self->frame_layout = 0;
5035 } else {
5036 self->frame_layout = 3;
5037 field_order = gst_structure_get_string (s, "field-order");
5038 if (!field_order || strcmp (field_order, "top-field-first") == 0)
5039 self->field_dominance = 1;
5040 else
5041 self->field_dominance = 2;
5042 }
5043
5044 if (!gst_structure_get_fraction (s, "framerate", &fps_n, &fps_d)) {
5045 GST_ERROR ("Invalid framerate");
5046 return FALSE;
5047 }
5048 f->sample_rate.n = fps_n;
5049 f->sample_rate.d = fps_d;
5050
5051 if (!gst_structure_get_int (s, "width", &width) ||
5052 !gst_structure_get_int (s, "height", &height)) {
5053 GST_ERROR ("Invalid width/height");
5054 return FALSE;
5055 }
5056
5057 self->stored_width = width;
5058 self->stored_height = height;
5059
5060 if (!gst_structure_get_fraction (s, "pixel-aspect-ratio", &par_n, &par_d)) {
5061 par_n = 1;
5062 par_d = 1;
5063 }
5064
5065 self->aspect_ratio.n = par_n * width;
5066 self->aspect_ratio.d = par_d * height;
5067 gcd =
5068 gst_greatest_common_divisor (self->aspect_ratio.n, self->aspect_ratio.d);
5069 self->aspect_ratio.n /= gcd;
5070 self->aspect_ratio.d /= gcd;
5071
5072 return TRUE;
5073 }
5074
5075
5076 G_DEFINE_TYPE (MXFMetadataGenericSoundEssenceDescriptor,
5077 mxf_metadata_generic_sound_essence_descriptor,
5078 MXF_TYPE_METADATA_FILE_DESCRIPTOR);
5079
5080 static gboolean
mxf_metadata_generic_sound_essence_descriptor_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)5081 mxf_metadata_generic_sound_essence_descriptor_handle_tag (MXFMetadataBase *
5082 metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
5083 guint tag_size)
5084 {
5085 MXFMetadataGenericSoundEssenceDescriptor *self =
5086 MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (metadata);
5087 gboolean ret = TRUE;
5088 #ifndef GST_DISABLE_GST_DEBUG
5089 gchar str[48];
5090 #endif
5091
5092 switch (tag) {
5093 case 0x3d03:
5094 if (!mxf_fraction_parse (&self->audio_sampling_rate, tag_data, tag_size))
5095 goto error;
5096 GST_DEBUG (" audio sampling rate = %d/%d",
5097 self->audio_sampling_rate.n, self->audio_sampling_rate.d);
5098 break;
5099 case 0x3d02:
5100 if (tag_size != 1)
5101 goto error;
5102 self->locked = (GST_READ_UINT8 (tag_data) != 0);
5103 GST_DEBUG (" locked = %s", (self->locked) ? "yes" : "no");
5104 break;
5105 case 0x3d04:
5106 if (tag_size != 1)
5107 goto error;
5108 self->audio_ref_level = GST_READ_UINT8 (tag_data);
5109 GST_DEBUG (" audio ref level = %d", self->audio_ref_level);
5110 break;
5111 case 0x3d05:
5112 if (tag_size != 1)
5113 goto error;
5114 self->electro_spatial_formulation = GST_READ_UINT8 (tag_data);
5115 GST_DEBUG (" electro spatial formulation = %u",
5116 self->electro_spatial_formulation);
5117 break;
5118 case 0x3d07:
5119 if (tag_size != 4)
5120 goto error;
5121 self->channel_count = GST_READ_UINT32_BE (tag_data);
5122 GST_DEBUG (" channel count = %u", self->channel_count);
5123 break;
5124 case 0x3d01:
5125 if (tag_size != 4)
5126 goto error;
5127 self->quantization_bits = GST_READ_UINT32_BE (tag_data);
5128 GST_DEBUG (" quantization bits = %u", self->quantization_bits);
5129 break;
5130 case 0x3d0c:
5131 if (tag_size != 1)
5132 goto error;
5133 self->dial_norm = GST_READ_UINT8 (tag_data);
5134 GST_DEBUG (" dial norm = %d", self->dial_norm);
5135 break;
5136 case 0x3d06:
5137 if (tag_size != 16)
5138 goto error;
5139 memcpy (&self->sound_essence_compression, tag_data, 16);
5140 GST_DEBUG (" sound essence compression = %s",
5141 mxf_ul_to_string (&self->sound_essence_compression, str));
5142 break;
5143 default:
5144 ret =
5145 MXF_METADATA_BASE_CLASS
5146 (mxf_metadata_generic_sound_essence_descriptor_parent_class)->handle_tag
5147 (metadata, primer, tag, tag_data, tag_size);
5148 break;
5149 }
5150
5151 return ret;
5152
5153 error:
5154
5155 GST_ERROR
5156 ("Invalid generic sound essence descriptor local tag 0x%04x of size %u",
5157 tag, tag_size);
5158
5159 return FALSE;
5160 }
5161
5162 static GstStructure *
mxf_metadata_generic_sound_essence_descriptor_to_structure(MXFMetadataBase * m)5163 mxf_metadata_generic_sound_essence_descriptor_to_structure (MXFMetadataBase * m)
5164 {
5165 GstStructure *ret =
5166 MXF_METADATA_BASE_CLASS
5167 (mxf_metadata_generic_sound_essence_descriptor_parent_class)->to_structure
5168 (m);
5169 MXFMetadataGenericSoundEssenceDescriptor *self =
5170 MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (m);
5171
5172 gst_structure_id_set (ret, MXF_QUARK (AUDIO_SAMPLING_RATE), GST_TYPE_FRACTION,
5173 self->audio_sampling_rate.n, self->audio_sampling_rate.d, NULL);
5174
5175 gst_structure_id_set (ret, MXF_QUARK (LOCKED), G_TYPE_BOOLEAN, self->locked,
5176 NULL);
5177
5178 if (self->electro_spatial_formulation != 0)
5179 gst_structure_id_set (ret, MXF_QUARK (ELECTRO_SPATIAL_FORMULATION),
5180 G_TYPE_UCHAR, self->electro_spatial_formulation, NULL);
5181
5182 gst_structure_id_set (ret, MXF_QUARK (CHANNEL_COUNT), G_TYPE_UINT,
5183 self->channel_count, NULL);
5184
5185 gst_structure_id_set (ret, MXF_QUARK (QUANTIZATION_BITS), G_TYPE_UINT,
5186 self->quantization_bits, NULL);
5187
5188 if (self->dial_norm != 0)
5189 gst_structure_id_set (ret, MXF_QUARK (DIAL_NORM), G_TYPE_CHAR,
5190 self->dial_norm, NULL);
5191
5192 if (!mxf_ul_is_zero (&self->sound_essence_compression)) {
5193 gchar str[48];
5194
5195 mxf_ul_to_string (&self->sound_essence_compression, str);
5196 gst_structure_id_set (ret, MXF_QUARK (SOUND_ESSENCE_COMPRESSION),
5197 G_TYPE_STRING, str, NULL);
5198 }
5199
5200 return ret;
5201 }
5202
5203 static GList *
mxf_metadata_generic_sound_essence_descriptor_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)5204 mxf_metadata_generic_sound_essence_descriptor_write_tags (MXFMetadataBase * m,
5205 MXFPrimerPack * primer)
5206 {
5207 MXFMetadataGenericSoundEssenceDescriptor *self =
5208 MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (m);
5209 GList *ret =
5210 MXF_METADATA_BASE_CLASS
5211 (mxf_metadata_generic_sound_essence_descriptor_parent_class)->write_tags
5212 (m, primer);
5213 MXFLocalTag *t;
5214
5215 t = g_slice_new0 (MXFLocalTag);
5216 memcpy (&t->ul, MXF_UL (AUDIO_SAMPLING_RATE), 16);
5217 t->size = 8;
5218 t->data = g_slice_alloc (t->size);
5219 t->g_slice = TRUE;
5220 GST_WRITE_UINT32_BE (t->data, self->audio_sampling_rate.n);
5221 GST_WRITE_UINT32_BE (t->data + 4, self->audio_sampling_rate.d);
5222 mxf_primer_pack_add_mapping (primer, 0x3d03, &t->ul);
5223 ret = g_list_prepend (ret, t);
5224
5225 t = g_slice_new0 (MXFLocalTag);
5226 memcpy (&t->ul, MXF_UL (LOCKED), 16);
5227 t->size = 1;
5228 t->data = g_slice_alloc (t->size);
5229 t->g_slice = TRUE;
5230 GST_WRITE_UINT8 (t->data, (self->locked) ? 1 : 0);
5231 mxf_primer_pack_add_mapping (primer, 0x3d02, &t->ul);
5232 ret = g_list_prepend (ret, t);
5233
5234 if (self->audio_ref_level) {
5235 t = g_slice_new0 (MXFLocalTag);
5236 memcpy (&t->ul, MXF_UL (AUDIO_REF_LEVEL), 16);
5237 t->size = 1;
5238 t->data = g_slice_alloc (t->size);
5239 t->g_slice = TRUE;
5240 GST_WRITE_UINT8 (t->data, self->audio_ref_level);
5241 mxf_primer_pack_add_mapping (primer, 0x3d04, &t->ul);
5242 ret = g_list_prepend (ret, t);
5243 }
5244
5245 if (self->electro_spatial_formulation != 255) {
5246 t = g_slice_new0 (MXFLocalTag);
5247 memcpy (&t->ul, MXF_UL (ELECTRO_SPATIAL_FORMULATION), 16);
5248 t->size = 1;
5249 t->data = g_slice_alloc (t->size);
5250 t->g_slice = TRUE;
5251 GST_WRITE_UINT8 (t->data, self->electro_spatial_formulation);
5252 mxf_primer_pack_add_mapping (primer, 0x3d05, &t->ul);
5253 ret = g_list_prepend (ret, t);
5254 }
5255
5256 t = g_slice_new0 (MXFLocalTag);
5257 memcpy (&t->ul, MXF_UL (CHANNEL_COUNT), 16);
5258 t->size = 4;
5259 t->data = g_slice_alloc (t->size);
5260 t->g_slice = TRUE;
5261 GST_WRITE_UINT32_BE (t->data, self->channel_count);
5262 mxf_primer_pack_add_mapping (primer, 0x3d07, &t->ul);
5263 ret = g_list_prepend (ret, t);
5264
5265 t = g_slice_new0 (MXFLocalTag);
5266 memcpy (&t->ul, MXF_UL (QUANTIZATION_BITS), 16);
5267 t->size = 4;
5268 t->data = g_slice_alloc (t->size);
5269 t->g_slice = TRUE;
5270 GST_WRITE_UINT32_BE (t->data, self->quantization_bits);
5271 mxf_primer_pack_add_mapping (primer, 0x3d01, &t->ul);
5272 ret = g_list_prepend (ret, t);
5273
5274 if (self->dial_norm != 0) {
5275 t = g_slice_new0 (MXFLocalTag);
5276 memcpy (&t->ul, MXF_UL (DIAL_NORM), 16);
5277 t->size = 1;
5278 t->data = g_slice_alloc (t->size);
5279 t->g_slice = TRUE;
5280 GST_WRITE_UINT8 (t->data, self->dial_norm);
5281 mxf_primer_pack_add_mapping (primer, 0x3d0c, &t->ul);
5282 ret = g_list_prepend (ret, t);
5283 }
5284
5285 if (!mxf_ul_is_zero (&self->sound_essence_compression)) {
5286 t = g_slice_new0 (MXFLocalTag);
5287 memcpy (&t->ul, MXF_UL (SOUND_ESSENCE_COMPRESSION), 16);
5288 t->size = 16;
5289 t->data = g_slice_alloc (t->size);
5290 t->g_slice = TRUE;
5291 memcpy (t->data, &self->sound_essence_compression, 16);
5292 mxf_primer_pack_add_mapping (primer, 0x3d06, &t->ul);
5293 ret = g_list_prepend (ret, t);
5294 }
5295
5296 return ret;
5297 }
5298
5299 static void
mxf_metadata_generic_sound_essence_descriptor_init(MXFMetadataGenericSoundEssenceDescriptor * self)5300 mxf_metadata_generic_sound_essence_descriptor_init
5301 (MXFMetadataGenericSoundEssenceDescriptor * self)
5302 {
5303 self->audio_sampling_rate.n = 0;
5304 self->audio_sampling_rate.d = 1;
5305 self->electro_spatial_formulation = 255;
5306 }
5307
5308 static void
mxf_metadata_generic_sound_essence_descriptor_class_init(MXFMetadataGenericSoundEssenceDescriptorClass * klass)5309 mxf_metadata_generic_sound_essence_descriptor_class_init
5310 (MXFMetadataGenericSoundEssenceDescriptorClass * klass)
5311 {
5312 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
5313 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
5314
5315 metadata_base_class->handle_tag =
5316 mxf_metadata_generic_sound_essence_descriptor_handle_tag;
5317 metadata_base_class->name_quark =
5318 MXF_QUARK (GENERIC_SOUND_ESSENCE_DESCRIPTOR);
5319 metadata_base_class->to_structure =
5320 mxf_metadata_generic_sound_essence_descriptor_to_structure;
5321 metadata_base_class->write_tags =
5322 mxf_metadata_generic_sound_essence_descriptor_write_tags;
5323 metadata_class->type = 0x0142;
5324 }
5325
mxf_metadata_generic_sound_essence_descriptor_set_caps(MXFMetadataGenericSoundEssenceDescriptor * self,GstCaps * caps)5326 void mxf_metadata_generic_sound_essence_descriptor_set_caps
5327 (MXFMetadataGenericSoundEssenceDescriptor * self, GstCaps * caps)
5328 {
5329 g_return_if_fail (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (self));
5330 g_return_if_fail (GST_IS_CAPS (caps));
5331
5332 if (self->audio_sampling_rate.n == 0 || self->audio_sampling_rate.d == 0) {
5333 GST_ERROR ("Invalid audio sampling rate");
5334 } else {
5335 gst_caps_set_simple (caps, "rate", G_TYPE_INT,
5336 (gint) (mxf_fraction_to_double (&self->audio_sampling_rate) + 0.5),
5337 NULL);
5338 }
5339
5340 if (self->channel_count == 0) {
5341 GST_ERROR ("Invalid number of channels (0)");
5342 } else {
5343 gst_caps_set_simple (caps, "channels", G_TYPE_INT, self->channel_count,
5344 NULL);
5345 }
5346 }
5347
mxf_metadata_generic_sound_essence_descriptor_create_caps(MXFMetadataGenericSoundEssenceDescriptor * self,GstAudioFormat * format)5348 GstCaps *mxf_metadata_generic_sound_essence_descriptor_create_caps
5349 (MXFMetadataGenericSoundEssenceDescriptor * self, GstAudioFormat * format)
5350 {
5351 GstAudioInfo info;
5352 gint rate = 0;
5353 gint channels = 0;
5354
5355 g_return_val_if_fail (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (self),
5356 NULL);
5357
5358 gst_audio_info_init (&info);
5359
5360 if (self->audio_sampling_rate.n == 0 || self->audio_sampling_rate.d == 0) {
5361 GST_ERROR ("Invalid audio sampling rate");
5362 } else {
5363 rate = (gint) (mxf_fraction_to_double (&self->audio_sampling_rate)
5364 + 0.5);
5365 }
5366
5367 if (self->channel_count == 0) {
5368 GST_ERROR ("Invalid number of channels (0)");
5369 } else {
5370 channels = self->channel_count;
5371 }
5372
5373 gst_audio_info_set_format (&info, *format, rate, channels, NULL);
5374
5375 return gst_audio_info_to_caps (&info);
5376 }
5377
5378 gboolean
mxf_metadata_generic_sound_essence_descriptor_from_caps(MXFMetadataGenericSoundEssenceDescriptor * self,GstCaps * caps)5379 mxf_metadata_generic_sound_essence_descriptor_from_caps
5380 (MXFMetadataGenericSoundEssenceDescriptor * self, GstCaps * caps) {
5381 gint rate;
5382 gint channels;
5383 GstStructure *s;
5384
5385 g_return_val_if_fail (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (self),
5386 FALSE);
5387 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
5388
5389 s = gst_caps_get_structure (caps, 0);
5390
5391 if (!gst_structure_get_int (s, "rate", &rate) || rate == 0) {
5392 GST_WARNING ("No samplerate");
5393 return FALSE;
5394 } else {
5395 self->audio_sampling_rate.n = rate;
5396 self->audio_sampling_rate.d = 1;
5397 }
5398
5399 if (!gst_structure_get_int (s, "channels", &channels) || channels == 0) {
5400 GST_WARNING ("No channels");
5401 return FALSE;
5402 } else {
5403 self->channel_count = channels;
5404 }
5405
5406 return TRUE;
5407 }
5408
5409
5410 G_DEFINE_TYPE (MXFMetadataCDCIPictureEssenceDescriptor,
5411 mxf_metadata_cdci_picture_essence_descriptor,
5412 MXF_TYPE_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR);
5413
5414 static gboolean
mxf_metadata_cdci_picture_essence_descriptor_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)5415 mxf_metadata_cdci_picture_essence_descriptor_handle_tag (MXFMetadataBase *
5416 metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
5417 guint tag_size)
5418 {
5419 MXFMetadataCDCIPictureEssenceDescriptor *self =
5420 MXF_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (metadata);
5421 gboolean ret = TRUE;
5422
5423 switch (tag) {
5424 case 0x3301:
5425 if (tag_size != 4)
5426 goto error;
5427 self->component_depth = GST_READ_UINT32_BE (tag_data);
5428 GST_DEBUG (" component depth = %u", self->component_depth);
5429 break;
5430 case 0x3302:
5431 if (tag_size != 4)
5432 goto error;
5433 self->horizontal_subsampling = GST_READ_UINT32_BE (tag_data);
5434 GST_DEBUG (" horizontal subsampling = %u", self->horizontal_subsampling);
5435 break;
5436 case 0x3308:
5437 if (tag_size != 4)
5438 goto error;
5439 self->vertical_subsampling = GST_READ_UINT32_BE (tag_data);
5440 GST_DEBUG (" vertical subsampling = %u", self->vertical_subsampling);
5441 break;
5442 case 0x3303:
5443 if (tag_size != 1)
5444 goto error;
5445 self->color_siting = GST_READ_UINT8 (tag_data);
5446 GST_DEBUG (" color siting = %u", self->color_siting);
5447 break;
5448 case 0x330b:
5449 if (tag_size != 1)
5450 goto error;
5451 self->reversed_byte_order = GST_READ_UINT8 (tag_data);
5452 GST_DEBUG (" reversed byte order = %s",
5453 (self->reversed_byte_order) ? "yes" : "no");
5454 break;
5455 case 0x3307:
5456 if (tag_size != 2)
5457 goto error;
5458 self->padding_bits = GST_READ_UINT16_BE (tag_data);
5459 GST_DEBUG (" padding bits = %d", self->padding_bits);
5460 break;
5461 case 0x3309:
5462 if (tag_size != 4)
5463 goto error;
5464 self->alpha_sample_depth = GST_READ_UINT32_BE (tag_data);
5465 GST_DEBUG (" alpha sample depth = %u", self->alpha_sample_depth);
5466 break;
5467 case 0x3304:
5468 if (tag_size != 4)
5469 goto error;
5470 self->black_ref_level = GST_READ_UINT32_BE (tag_data);
5471 GST_DEBUG (" black ref level = %u", self->black_ref_level);
5472 break;
5473 case 0x3305:
5474 if (tag_size != 4)
5475 goto error;
5476 self->white_ref_level = GST_READ_UINT32_BE (tag_data);
5477 GST_DEBUG (" white ref level = %u", self->white_ref_level);
5478 break;
5479 case 0x3306:
5480 if (tag_size != 4)
5481 goto error;
5482 self->color_range = GST_READ_UINT32_BE (tag_data);
5483 GST_DEBUG (" color range = %u", self->color_range);
5484 break;
5485 default:
5486 ret =
5487 MXF_METADATA_BASE_CLASS
5488 (mxf_metadata_cdci_picture_essence_descriptor_parent_class)->handle_tag
5489 (metadata, primer, tag, tag_data, tag_size);
5490 break;
5491 }
5492
5493 return ret;
5494
5495 error:
5496
5497 GST_ERROR
5498 ("Invalid CDCI picture essence descriptor local tag 0x%04x of size %u",
5499 tag, tag_size);
5500
5501 return FALSE;
5502 }
5503
5504 static GstStructure *
mxf_metadata_cdci_picture_essence_descriptor_to_structure(MXFMetadataBase * m)5505 mxf_metadata_cdci_picture_essence_descriptor_to_structure (MXFMetadataBase * m)
5506 {
5507 GstStructure *ret =
5508 MXF_METADATA_BASE_CLASS
5509 (mxf_metadata_cdci_picture_essence_descriptor_parent_class)->to_structure
5510 (m);
5511 MXFMetadataCDCIPictureEssenceDescriptor *self =
5512 MXF_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (m);
5513
5514 gst_structure_id_set (ret, MXF_QUARK (COMPONENT_DEPTH), G_TYPE_UINT,
5515 self->component_depth, NULL);
5516
5517 gst_structure_id_set (ret, MXF_QUARK (HORIZONTAL_SUBSAMPLING), G_TYPE_UINT,
5518 self->horizontal_subsampling, NULL);
5519
5520 if (self->vertical_subsampling != 0)
5521 gst_structure_id_set (ret, MXF_QUARK (VERTICAL_SUBSAMPLING), G_TYPE_UINT,
5522 self->vertical_subsampling, NULL);
5523
5524 if (self->color_siting != 255)
5525 gst_structure_id_set (ret, MXF_QUARK (COLOR_SITING), G_TYPE_UCHAR,
5526 self->color_siting, NULL);
5527
5528 gst_structure_id_set (ret, MXF_QUARK (REVERSED_BYTE_ORDER), G_TYPE_BOOLEAN,
5529 self->reversed_byte_order, NULL);
5530
5531 if (self->padding_bits != 0)
5532 gst_structure_id_set (ret, MXF_QUARK (PADDING_BITS), G_TYPE_INT,
5533 self->padding_bits, NULL);
5534
5535 if (self->alpha_sample_depth != 0)
5536 gst_structure_id_set (ret, MXF_QUARK (ALPHA_SAMPLE_DEPTH), G_TYPE_UINT,
5537 self->alpha_sample_depth, NULL);
5538
5539 if (self->black_ref_level != 0)
5540 gst_structure_id_set (ret, MXF_QUARK (BLACK_REF_LEVEL), G_TYPE_UINT,
5541 self->black_ref_level, NULL);
5542
5543 if (self->white_ref_level != 0)
5544 gst_structure_id_set (ret, MXF_QUARK (WHITE_REF_LEVEL), G_TYPE_UINT,
5545 self->white_ref_level, NULL);
5546
5547 if (self->color_range != 0)
5548 gst_structure_id_set (ret, MXF_QUARK (COLOR_RANGE), G_TYPE_UINT,
5549 self->color_range, NULL);
5550
5551 return ret;
5552 }
5553
5554 static GList *
mxf_metadata_cdci_picture_essence_descriptor_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)5555 mxf_metadata_cdci_picture_essence_descriptor_write_tags (MXFMetadataBase * m,
5556 MXFPrimerPack * primer)
5557 {
5558 MXFMetadataCDCIPictureEssenceDescriptor *self =
5559 MXF_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (m);
5560 GList *ret =
5561 MXF_METADATA_BASE_CLASS
5562 (mxf_metadata_cdci_picture_essence_descriptor_parent_class)->write_tags
5563 (m, primer);
5564 MXFLocalTag *t;
5565
5566 t = g_slice_new0 (MXFLocalTag);
5567 memcpy (&t->ul, MXF_UL (COMPONENT_DEPTH), 16);
5568 t->size = 4;
5569 t->data = g_slice_alloc (t->size);
5570 t->g_slice = TRUE;
5571 GST_WRITE_UINT32_BE (t->data, self->component_depth);
5572 mxf_primer_pack_add_mapping (primer, 0x3301, &t->ul);
5573 ret = g_list_prepend (ret, t);
5574
5575 t = g_slice_new0 (MXFLocalTag);
5576 memcpy (&t->ul, MXF_UL (HORIZONTAL_SUBSAMPLING), 16);
5577 t->size = 4;
5578 t->data = g_slice_alloc (t->size);
5579 t->g_slice = TRUE;
5580 GST_WRITE_UINT32_BE (t->data, self->horizontal_subsampling);
5581 mxf_primer_pack_add_mapping (primer, 0x3302, &t->ul);
5582 ret = g_list_prepend (ret, t);
5583
5584 if (self->vertical_subsampling) {
5585 t = g_slice_new0 (MXFLocalTag);
5586 memcpy (&t->ul, MXF_UL (VERTICAL_SUBSAMPLING), 16);
5587 t->size = 4;
5588 t->data = g_slice_alloc (t->size);
5589 t->g_slice = TRUE;
5590 GST_WRITE_UINT32_BE (t->data, self->vertical_subsampling);
5591 mxf_primer_pack_add_mapping (primer, 0x3308, &t->ul);
5592 ret = g_list_prepend (ret, t);
5593 }
5594
5595 if (self->color_siting != 0xff) {
5596 t = g_slice_new0 (MXFLocalTag);
5597 memcpy (&t->ul, MXF_UL (COLOR_SITING), 16);
5598 t->size = 1;
5599 t->data = g_slice_alloc (t->size);
5600 t->g_slice = TRUE;
5601 GST_WRITE_UINT8 (t->data, self->color_siting);
5602 mxf_primer_pack_add_mapping (primer, 0x3303, &t->ul);
5603 ret = g_list_prepend (ret, t);
5604 }
5605
5606 if (self->reversed_byte_order) {
5607 t = g_slice_new0 (MXFLocalTag);
5608 memcpy (&t->ul, MXF_UL (REVERSED_BYTE_ORDER), 16);
5609 t->size = 1;
5610 t->data = g_slice_alloc (t->size);
5611 t->g_slice = TRUE;
5612 GST_WRITE_UINT8 (t->data, (self->reversed_byte_order) ? 1 : 0);
5613 mxf_primer_pack_add_mapping (primer, 0x330b, &t->ul);
5614 ret = g_list_prepend (ret, t);
5615 }
5616
5617 if (self->padding_bits) {
5618 t = g_slice_new0 (MXFLocalTag);
5619 memcpy (&t->ul, MXF_UL (PADDING_BITS), 16);
5620 t->size = 2;
5621 t->data = g_slice_alloc (t->size);
5622 t->g_slice = TRUE;
5623 GST_WRITE_UINT16_BE (t->data, self->padding_bits);
5624 mxf_primer_pack_add_mapping (primer, 0x3307, &t->ul);
5625 ret = g_list_prepend (ret, t);
5626 }
5627
5628 if (self->alpha_sample_depth) {
5629 t = g_slice_new0 (MXFLocalTag);
5630 memcpy (&t->ul, MXF_UL (ALPHA_SAMPLE_DEPTH), 16);
5631 t->size = 4;
5632 t->data = g_slice_alloc (t->size);
5633 t->g_slice = TRUE;
5634 GST_WRITE_UINT32_BE (t->data, self->alpha_sample_depth);
5635 mxf_primer_pack_add_mapping (primer, 0x3309, &t->ul);
5636 ret = g_list_prepend (ret, t);
5637 }
5638
5639 if (self->black_ref_level) {
5640 t = g_slice_new0 (MXFLocalTag);
5641 memcpy (&t->ul, MXF_UL (BLACK_REF_LEVEL), 16);
5642 t->size = 4;
5643 t->data = g_slice_alloc (t->size);
5644 t->g_slice = TRUE;
5645 GST_WRITE_UINT32_BE (t->data, self->black_ref_level);
5646 mxf_primer_pack_add_mapping (primer, 0x3304, &t->ul);
5647 ret = g_list_prepend (ret, t);
5648 }
5649
5650 if (self->white_ref_level) {
5651 t = g_slice_new0 (MXFLocalTag);
5652 memcpy (&t->ul, MXF_UL (WHITE_REF_LEVEL), 16);
5653 t->size = 4;
5654 t->data = g_slice_alloc (t->size);
5655 t->g_slice = TRUE;
5656 GST_WRITE_UINT32_BE (t->data, self->white_ref_level);
5657 mxf_primer_pack_add_mapping (primer, 0x3305, &t->ul);
5658 ret = g_list_prepend (ret, t);
5659 }
5660
5661 if (self->color_range) {
5662 t = g_slice_new0 (MXFLocalTag);
5663 memcpy (&t->ul, MXF_UL (COLOR_RANGE), 16);
5664 t->size = 4;
5665 t->data = g_slice_alloc (t->size);
5666 t->g_slice = TRUE;
5667 GST_WRITE_UINT32_BE (t->data, self->color_range);
5668 mxf_primer_pack_add_mapping (primer, 0x3306, &t->ul);
5669 ret = g_list_prepend (ret, t);
5670 }
5671
5672 return ret;
5673 }
5674
5675 static void
mxf_metadata_cdci_picture_essence_descriptor_init(MXFMetadataCDCIPictureEssenceDescriptor * self)5676 mxf_metadata_cdci_picture_essence_descriptor_init
5677 (MXFMetadataCDCIPictureEssenceDescriptor * self)
5678 {
5679 self->color_siting = 0xff;
5680 }
5681
5682 static void
mxf_metadata_cdci_picture_essence_descriptor_class_init(MXFMetadataCDCIPictureEssenceDescriptorClass * klass)5683 mxf_metadata_cdci_picture_essence_descriptor_class_init
5684 (MXFMetadataCDCIPictureEssenceDescriptorClass * klass)
5685 {
5686 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
5687 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
5688
5689 metadata_base_class->handle_tag =
5690 mxf_metadata_cdci_picture_essence_descriptor_handle_tag;
5691 metadata_base_class->name_quark = MXF_QUARK (CDCI_PICTURE_ESSENCE_DESCRIPTOR);
5692 metadata_base_class->to_structure =
5693 mxf_metadata_cdci_picture_essence_descriptor_to_structure;
5694 metadata_base_class->write_tags =
5695 mxf_metadata_cdci_picture_essence_descriptor_write_tags;
5696 metadata_class->type = 0x0128;
5697 }
5698
5699 G_DEFINE_TYPE (MXFMetadataRGBAPictureEssenceDescriptor,
5700 mxf_metadata_rgba_picture_essence_descriptor,
5701 MXF_TYPE_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR);
5702
5703 static void
mxf_metadata_rgba_picture_essence_descriptor_finalize(GObject * object)5704 mxf_metadata_rgba_picture_essence_descriptor_finalize (GObject * object)
5705 {
5706 MXFMetadataRGBAPictureEssenceDescriptor *self =
5707 MXF_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (object);
5708
5709 g_free (self->pixel_layout);
5710 self->pixel_layout = NULL;
5711
5712 G_OBJECT_CLASS
5713 (mxf_metadata_rgba_picture_essence_descriptor_parent_class)->finalize
5714 (object);
5715 }
5716
5717 static gboolean
mxf_metadata_rgba_picture_essence_descriptor_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)5718 mxf_metadata_rgba_picture_essence_descriptor_handle_tag (MXFMetadataBase *
5719 metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
5720 guint tag_size)
5721 {
5722 MXFMetadataRGBAPictureEssenceDescriptor *self =
5723 MXF_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (metadata);
5724 gboolean ret = TRUE;
5725
5726 switch (tag) {
5727 case 0x3406:
5728 if (tag_size != 4)
5729 goto error;
5730 self->component_max_ref = GST_READ_UINT32_BE (tag_data);
5731 GST_DEBUG (" component max ref = %u", self->component_max_ref);
5732 break;
5733 case 0x3407:
5734 if (tag_size != 4)
5735 goto error;
5736 self->component_min_ref = GST_READ_UINT32_BE (tag_data);
5737 GST_DEBUG (" component min ref = %u", self->component_min_ref);
5738 break;
5739 case 0x3408:
5740 if (tag_size != 4)
5741 goto error;
5742 self->alpha_max_ref = GST_READ_UINT32_BE (tag_data);
5743 GST_DEBUG (" alpha max ref = %u", self->alpha_max_ref);
5744 break;
5745 case 0x3409:
5746 if (tag_size != 4)
5747 goto error;
5748 self->alpha_min_ref = GST_READ_UINT32_BE (tag_data);
5749 GST_DEBUG (" alpha min ref = %u", self->alpha_min_ref);
5750 break;
5751 case 0x3405:
5752 if (tag_size != 1)
5753 goto error;
5754 self->scanning_direction = GST_READ_UINT8 (tag_data);
5755 GST_DEBUG (" scanning direction = %u", self->scanning_direction);
5756 break;
5757 case 0x3401:{
5758 guint i, len;
5759
5760 if (tag_size % 2 != 0 || tag_size > 16)
5761 goto error;
5762
5763 i = 0;
5764 while (tag_data[i] != 0 && tag_data[i + 1] != 0 && i + 2 <= tag_size)
5765 i += 2;
5766 len = i / 2;
5767
5768 self->n_pixel_layout = len;
5769 GST_DEBUG (" number of pixel layouts = %u", len);
5770 if (len == 0)
5771 return TRUE;
5772
5773 self->pixel_layout = g_malloc0 (16);
5774
5775 for (i = 0; i < len; i++) {
5776 self->pixel_layout[2 * i] = tag_data[2 * i];
5777 self->pixel_layout[2 * i + 1] = tag_data[2 * i + 1];
5778 GST_DEBUG (" pixel layout %u = %c : %u", i,
5779 (gchar) self->pixel_layout[2 * i], self->pixel_layout[2 * i + 1]);
5780 }
5781
5782 break;
5783 }
5784 case 0x3403:
5785 case 0x3404:
5786 /* TODO: handle this */
5787 GST_WARNING (" tag 0x%04x not implemented yet", tag);
5788 break;
5789 default:
5790 ret =
5791 MXF_METADATA_BASE_CLASS
5792 (mxf_metadata_rgba_picture_essence_descriptor_parent_class)->handle_tag
5793 (metadata, primer, tag, tag_data, tag_size);
5794 break;
5795 }
5796
5797 return ret;
5798
5799 error:
5800
5801 GST_ERROR
5802 ("Invalid RGBA picture essence descriptor local tag 0x%04x of size %u",
5803 tag, tag_size);
5804
5805 return FALSE;
5806 }
5807
5808 static GstStructure *
mxf_metadata_rgba_picture_essence_descriptor_to_structure(MXFMetadataBase * m)5809 mxf_metadata_rgba_picture_essence_descriptor_to_structure (MXFMetadataBase * m)
5810 {
5811 GstStructure *ret =
5812 MXF_METADATA_BASE_CLASS
5813 (mxf_metadata_rgba_picture_essence_descriptor_parent_class)->to_structure
5814 (m);
5815 MXFMetadataRGBAPictureEssenceDescriptor *self =
5816 MXF_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (m);
5817
5818 if (self->component_max_ref != 255)
5819 gst_structure_id_set (ret, MXF_QUARK (COMPONENT_MAX_REF), G_TYPE_UINT,
5820 self->component_max_ref, NULL);
5821
5822 if (self->component_min_ref != 0)
5823 gst_structure_id_set (ret, MXF_QUARK (COMPONENT_MIN_REF), G_TYPE_UINT,
5824 self->component_min_ref, NULL);
5825
5826 if (self->alpha_max_ref != 255)
5827 gst_structure_id_set (ret, MXF_QUARK (ALPHA_MAX_REF), G_TYPE_UINT,
5828 self->alpha_max_ref, NULL);
5829
5830 if (self->alpha_min_ref != 0)
5831 gst_structure_id_set (ret, MXF_QUARK (ALPHA_MIN_REF), G_TYPE_UINT,
5832 self->alpha_min_ref, NULL);
5833
5834 if (self->scanning_direction != 0)
5835 gst_structure_id_set (ret, MXF_QUARK (SCANNING_DIRECTION), G_TYPE_UCHAR,
5836 self->scanning_direction, NULL);
5837
5838 if (self->n_pixel_layout != 0) {
5839 gchar *pl = g_new0 (gchar, self->n_pixel_layout * 2 + 1);
5840
5841 memcpy (pl, self->pixel_layout, self->n_pixel_layout * 2);
5842
5843 gst_structure_id_set (ret, MXF_QUARK (PIXEL_LAYOUT), G_TYPE_STRING, pl,
5844 NULL);
5845
5846 g_free (pl);
5847 }
5848
5849 return ret;
5850 }
5851
5852 static GList *
mxf_metadata_rgba_picture_essence_descriptor_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)5853 mxf_metadata_rgba_picture_essence_descriptor_write_tags (MXFMetadataBase * m,
5854 MXFPrimerPack * primer)
5855 {
5856 MXFMetadataRGBAPictureEssenceDescriptor *self =
5857 MXF_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (m);
5858 GList *ret =
5859 MXF_METADATA_BASE_CLASS
5860 (mxf_metadata_rgba_picture_essence_descriptor_parent_class)->write_tags
5861 (m, primer);
5862 MXFLocalTag *t;
5863
5864 if (self->component_max_ref != 255) {
5865 t = g_slice_new0 (MXFLocalTag);
5866 memcpy (&t->ul, MXF_UL (COMPONENT_MAX_REF), 16);
5867 t->size = 4;
5868 t->data = g_slice_alloc (t->size);
5869 t->g_slice = TRUE;
5870 GST_WRITE_UINT32_BE (t->data, self->component_max_ref);
5871 mxf_primer_pack_add_mapping (primer, 0x3406, &t->ul);
5872 ret = g_list_prepend (ret, t);
5873 }
5874
5875 if (self->component_min_ref) {
5876 t = g_slice_new0 (MXFLocalTag);
5877 memcpy (&t->ul, MXF_UL (COMPONENT_MIN_REF), 16);
5878 t->size = 4;
5879 t->data = g_slice_alloc (t->size);
5880 t->g_slice = TRUE;
5881 GST_WRITE_UINT32_BE (t->data, self->component_min_ref);
5882 mxf_primer_pack_add_mapping (primer, 0x3407, &t->ul);
5883 ret = g_list_prepend (ret, t);
5884 }
5885
5886 if (self->alpha_max_ref != 255) {
5887 t = g_slice_new0 (MXFLocalTag);
5888 memcpy (&t->ul, MXF_UL (ALPHA_MAX_REF), 16);
5889 t->size = 4;
5890 t->data = g_slice_alloc (t->size);
5891 t->g_slice = TRUE;
5892 GST_WRITE_UINT32_BE (t->data, self->alpha_max_ref);
5893 mxf_primer_pack_add_mapping (primer, 0x3408, &t->ul);
5894 ret = g_list_prepend (ret, t);
5895 }
5896
5897 if (self->alpha_min_ref) {
5898 t = g_slice_new0 (MXFLocalTag);
5899 memcpy (&t->ul, MXF_UL (ALPHA_MIN_REF), 16);
5900 t->size = 4;
5901 t->data = g_slice_alloc (t->size);
5902 t->g_slice = TRUE;
5903 GST_WRITE_UINT32_BE (t->data, self->alpha_min_ref);
5904 mxf_primer_pack_add_mapping (primer, 0x3409, &t->ul);
5905 ret = g_list_prepend (ret, t);
5906 }
5907
5908 if (self->scanning_direction) {
5909 t = g_slice_new0 (MXFLocalTag);
5910 memcpy (&t->ul, MXF_UL (SCANNING_DIRECTION), 16);
5911 t->size = 1;
5912 t->data = g_slice_alloc (t->size);
5913 t->g_slice = TRUE;
5914 GST_WRITE_UINT8 (t->data, self->scanning_direction);
5915 mxf_primer_pack_add_mapping (primer, 0x3405, &t->ul);
5916 ret = g_list_prepend (ret, t);
5917 }
5918
5919 t = g_slice_new0 (MXFLocalTag);
5920 memcpy (&t->ul, MXF_UL (PIXEL_LAYOUT), 16);
5921 t->size = 16;
5922 t->data = g_slice_alloc0 (t->size);
5923 t->g_slice = TRUE;
5924 if (self->pixel_layout)
5925 memcpy (t->data, self->pixel_layout, self->n_pixel_layout * 2);
5926 mxf_primer_pack_add_mapping (primer, 0x3401, &t->ul);
5927 ret = g_list_prepend (ret, t);
5928
5929 return ret;
5930 }
5931
5932 static void
mxf_metadata_rgba_picture_essence_descriptor_init(MXFMetadataRGBAPictureEssenceDescriptor * self)5933 mxf_metadata_rgba_picture_essence_descriptor_init
5934 (MXFMetadataRGBAPictureEssenceDescriptor * self)
5935 {
5936 self->component_max_ref = 255;
5937 self->alpha_max_ref = 255;
5938 }
5939
5940 static void
mxf_metadata_rgba_picture_essence_descriptor_class_init(MXFMetadataRGBAPictureEssenceDescriptorClass * klass)5941 mxf_metadata_rgba_picture_essence_descriptor_class_init
5942 (MXFMetadataRGBAPictureEssenceDescriptorClass * klass)
5943 {
5944 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
5945 GObjectClass *object_class = (GObjectClass *) klass;
5946 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
5947
5948 object_class->finalize =
5949 mxf_metadata_rgba_picture_essence_descriptor_finalize;
5950 metadata_base_class->handle_tag =
5951 mxf_metadata_rgba_picture_essence_descriptor_handle_tag;
5952 metadata_base_class->name_quark = MXF_QUARK (RGBA_PICTURE_ESSENCE_DESCRIPTOR);
5953 metadata_base_class->to_structure =
5954 mxf_metadata_rgba_picture_essence_descriptor_to_structure;
5955 metadata_base_class->write_tags =
5956 mxf_metadata_rgba_picture_essence_descriptor_write_tags;
5957 metadata_class->type = 0x0129;
5958 }
5959
5960 G_DEFINE_TYPE (MXFMetadataGenericDataEssenceDescriptor,
5961 mxf_metadata_generic_data_essence_descriptor,
5962 MXF_TYPE_METADATA_FILE_DESCRIPTOR);
5963
5964 static gboolean
mxf_metadata_generic_data_essence_descriptor_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)5965 mxf_metadata_generic_data_essence_descriptor_handle_tag (MXFMetadataBase *
5966 metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
5967 guint tag_size)
5968 {
5969 MXFMetadataGenericDataEssenceDescriptor *self =
5970 MXF_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR (metadata);
5971 gboolean ret = TRUE;
5972 #ifndef GST_DISABLE_GST_DEBUG
5973 gchar str[48];
5974 #endif
5975
5976 switch (tag) {
5977 case 0x3e01:
5978 if (tag_size != 16)
5979 goto error;
5980 memcpy (&self->data_essence_coding, tag_data, 16);
5981 GST_DEBUG (" data essence coding = %s",
5982 mxf_ul_to_string (&self->data_essence_coding, str));
5983 break;
5984 default:
5985 ret =
5986 MXF_METADATA_BASE_CLASS
5987 (mxf_metadata_generic_data_essence_descriptor_parent_class)->handle_tag
5988 (metadata, primer, tag, tag_data, tag_size);
5989 break;
5990 }
5991
5992 return ret;
5993
5994 error:
5995
5996 GST_ERROR
5997 ("Invalid generic data essence descriptor local tag 0x%04x of size %u",
5998 tag, tag_size);
5999
6000 return FALSE;
6001 }
6002
6003 static GstStructure *
mxf_metadata_generic_data_essence_descriptor_to_structure(MXFMetadataBase * m)6004 mxf_metadata_generic_data_essence_descriptor_to_structure (MXFMetadataBase * m)
6005 {
6006 GstStructure *ret =
6007 MXF_METADATA_BASE_CLASS
6008 (mxf_metadata_generic_data_essence_descriptor_parent_class)->to_structure
6009 (m);
6010 MXFMetadataGenericDataEssenceDescriptor *self =
6011 MXF_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR (m);
6012 gchar str[48];
6013
6014 if (!mxf_ul_is_zero (&self->data_essence_coding)) {
6015 mxf_ul_to_string (&self->data_essence_coding, str);
6016 gst_structure_id_set (ret, MXF_QUARK (DATA_ESSENCE_CODING), G_TYPE_STRING,
6017 str, NULL);
6018 }
6019
6020 return ret;
6021 }
6022
6023 static GList *
mxf_metadata_generic_data_essence_descriptor_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)6024 mxf_metadata_generic_data_essence_descriptor_write_tags (MXFMetadataBase * m,
6025 MXFPrimerPack * primer)
6026 {
6027 MXFMetadataGenericDataEssenceDescriptor *self =
6028 MXF_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR (m);
6029 GList *ret =
6030 MXF_METADATA_BASE_CLASS
6031 (mxf_metadata_generic_data_essence_descriptor_parent_class)->write_tags
6032 (m, primer);
6033 MXFLocalTag *t;
6034
6035 if (!mxf_ul_is_zero (&self->data_essence_coding)) {
6036 t = g_slice_new0 (MXFLocalTag);
6037 memcpy (&t->ul, MXF_UL (DATA_ESSENCE_CODING), 16);
6038 t->size = 16;
6039 t->data = g_slice_alloc (t->size);
6040 t->g_slice = TRUE;
6041 memcpy (t->data, &self->data_essence_coding, 16);
6042 mxf_primer_pack_add_mapping (primer, 0x3e01, &t->ul);
6043 ret = g_list_prepend (ret, t);
6044 }
6045
6046 return ret;
6047 }
6048
6049 static void
mxf_metadata_generic_data_essence_descriptor_init(MXFMetadataGenericDataEssenceDescriptor * self)6050 mxf_metadata_generic_data_essence_descriptor_init
6051 (MXFMetadataGenericDataEssenceDescriptor * self)
6052 {
6053
6054 }
6055
6056 static void
mxf_metadata_generic_data_essence_descriptor_class_init(MXFMetadataGenericDataEssenceDescriptorClass * klass)6057 mxf_metadata_generic_data_essence_descriptor_class_init
6058 (MXFMetadataGenericDataEssenceDescriptorClass * klass)
6059 {
6060 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
6061 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
6062
6063 metadata_base_class->handle_tag =
6064 mxf_metadata_generic_data_essence_descriptor_handle_tag;
6065 metadata_base_class->name_quark = MXF_QUARK (GENERIC_DATA_ESSENCE_DESCRIPTOR);
6066 metadata_base_class->to_structure =
6067 mxf_metadata_generic_data_essence_descriptor_to_structure;
6068 metadata_base_class->write_tags =
6069 mxf_metadata_generic_data_essence_descriptor_write_tags;
6070 metadata_class->type = 0x0143;
6071 }
6072
6073 G_DEFINE_TYPE (MXFMetadataMultipleDescriptor, mxf_metadata_multiple_descriptor,
6074 MXF_TYPE_METADATA_FILE_DESCRIPTOR);
6075
6076 static void
mxf_metadata_multiple_descriptor_finalize(GObject * object)6077 mxf_metadata_multiple_descriptor_finalize (GObject * object)
6078 {
6079 MXFMetadataMultipleDescriptor *self =
6080 MXF_METADATA_MULTIPLE_DESCRIPTOR (object);
6081
6082 g_free (self->sub_descriptors_uids);
6083 self->sub_descriptors_uids = NULL;
6084 g_free (self->sub_descriptors);
6085 self->sub_descriptors = NULL;
6086
6087 G_OBJECT_CLASS
6088 (mxf_metadata_multiple_descriptor_parent_class)->finalize (object);
6089 }
6090
6091 static gboolean
mxf_metadata_multiple_descriptor_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)6092 mxf_metadata_multiple_descriptor_handle_tag (MXFMetadataBase * metadata,
6093 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
6094 guint tag_size)
6095 {
6096 MXFMetadataMultipleDescriptor *self =
6097 MXF_METADATA_MULTIPLE_DESCRIPTOR (metadata);
6098 gboolean ret = TRUE;
6099 #ifndef GST_DISABLE_GST_DEBUG
6100 gchar str[48];
6101 #endif
6102
6103 switch (tag) {
6104 case 0x3f01:
6105 if (!mxf_uuid_array_parse (&self->sub_descriptors_uids,
6106 &self->n_sub_descriptors, tag_data, tag_size))
6107 goto error;
6108
6109 GST_DEBUG (" number of sub descriptors = %u", self->n_sub_descriptors);
6110 #ifndef GST_DISABLE_GST_DEBUG
6111 {
6112 guint i;
6113 for (i = 0; i < self->n_sub_descriptors; i++) {
6114 GST_DEBUG (" sub descriptor %u = %s", i,
6115 mxf_uuid_to_string (&self->sub_descriptors_uids[i], str));
6116 }
6117 }
6118 #endif
6119
6120 break;
6121 default:
6122 ret =
6123 MXF_METADATA_BASE_CLASS
6124 (mxf_metadata_multiple_descriptor_parent_class)->handle_tag (metadata,
6125 primer, tag, tag_data, tag_size);
6126 break;
6127 }
6128
6129 return ret;
6130
6131 error:
6132
6133 GST_ERROR ("Invalid multiple descriptor local tag 0x%04x of size %u", tag,
6134 tag_size);
6135
6136 return FALSE;
6137 }
6138
6139 static gboolean
mxf_metadata_multiple_descriptor_resolve(MXFMetadataBase * m,GHashTable * metadata)6140 mxf_metadata_multiple_descriptor_resolve (MXFMetadataBase * m,
6141 GHashTable * metadata)
6142 {
6143 MXFMetadataMultipleDescriptor *self = MXF_METADATA_MULTIPLE_DESCRIPTOR (m);
6144 MXFMetadataBase *current = NULL;
6145 guint i, have_subdescriptors = 0;
6146 #ifndef GST_DISABLE_GST_DEBUG
6147 gchar str[48];
6148 #endif
6149
6150 if (self->sub_descriptors)
6151 memset (self->sub_descriptors, 0,
6152 sizeof (gpointer) * self->n_sub_descriptors);
6153 else
6154 self->sub_descriptors =
6155 g_new0 (MXFMetadataGenericDescriptor *, self->n_sub_descriptors);
6156 for (i = 0; i < self->n_sub_descriptors; i++) {
6157 current = g_hash_table_lookup (metadata, &self->sub_descriptors_uids[i]);
6158 if (current && MXF_IS_METADATA_GENERIC_DESCRIPTOR (current)) {
6159 if (mxf_metadata_base_resolve (current, metadata)) {
6160 self->sub_descriptors[i] = MXF_METADATA_GENERIC_DESCRIPTOR (current);
6161 have_subdescriptors++;
6162 } else {
6163 GST_ERROR ("Couldn't resolve descriptor %s",
6164 mxf_uuid_to_string (&self->sub_descriptors_uids[i], str));
6165 return FALSE;
6166 }
6167 } else {
6168 GST_ERROR ("Descriptor %s not found",
6169 mxf_uuid_to_string (&self->sub_descriptors_uids[i], str));
6170 }
6171 }
6172
6173 return
6174 MXF_METADATA_BASE_CLASS
6175 (mxf_metadata_multiple_descriptor_parent_class)->resolve (m, metadata);
6176 }
6177
6178 static GstStructure *
mxf_metadata_multiple_descriptor_to_structure(MXFMetadataBase * m)6179 mxf_metadata_multiple_descriptor_to_structure (MXFMetadataBase * m)
6180 {
6181 GstStructure *ret =
6182 MXF_METADATA_BASE_CLASS
6183 (mxf_metadata_multiple_descriptor_parent_class)->to_structure (m);
6184 MXFMetadataMultipleDescriptor *self = MXF_METADATA_MULTIPLE_DESCRIPTOR (m);
6185 guint i;
6186
6187 if (self->n_sub_descriptors > 0) {
6188 GValue arr = { 0, }
6189 , val = {
6190 0,};
6191
6192 g_value_init (&arr, GST_TYPE_ARRAY);
6193
6194 for (i = 0; i < self->n_sub_descriptors; i++) {
6195 GstStructure *s;
6196
6197 if (self->sub_descriptors[i] == NULL)
6198 continue;
6199
6200 g_value_init (&val, GST_TYPE_STRUCTURE);
6201
6202 s = mxf_metadata_base_to_structure (MXF_METADATA_BASE
6203 (self->sub_descriptors[i]));
6204 gst_value_set_structure (&val, s);
6205 gst_structure_free (s);
6206 gst_value_array_append_value (&arr, &val);
6207 g_value_unset (&val);
6208 }
6209
6210 if (gst_value_array_get_size (&arr) > 0)
6211 gst_structure_id_set_value (ret, MXF_QUARK (SUB_DESCRIPTORS), &arr);
6212
6213 g_value_unset (&arr);
6214 }
6215
6216 return ret;
6217 }
6218
6219 static GList *
mxf_metadata_multiple_descriptor_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)6220 mxf_metadata_multiple_descriptor_write_tags (MXFMetadataBase * m,
6221 MXFPrimerPack * primer)
6222 {
6223 MXFMetadataMultipleDescriptor *self = MXF_METADATA_MULTIPLE_DESCRIPTOR (m);
6224 GList *ret =
6225 MXF_METADATA_BASE_CLASS
6226 (mxf_metadata_multiple_descriptor_parent_class)->write_tags (m, primer);
6227 MXFLocalTag *t;
6228
6229 if (self->sub_descriptors) {
6230 guint i;
6231
6232 t = g_slice_new0 (MXFLocalTag);
6233 memcpy (&t->ul, MXF_UL (SUB_DESCRIPTORS), 16);
6234 t->size = 8 + 16 * self->n_sub_descriptors;
6235 t->data = g_slice_alloc0 (t->size);
6236 t->g_slice = TRUE;
6237 GST_WRITE_UINT32_BE (t->data, self->n_sub_descriptors);
6238 GST_WRITE_UINT32_BE (t->data + 4, 16);
6239 for (i = 0; i < self->n_sub_descriptors; i++) {
6240 if (!self->sub_descriptors[i])
6241 continue;
6242
6243 memcpy (t->data + 8 + 16 * i,
6244 &MXF_METADATA_BASE (self->sub_descriptors[i])->instance_uid, 16);
6245 }
6246 mxf_primer_pack_add_mapping (primer, 0x3f01, &t->ul);
6247 ret = g_list_prepend (ret, t);
6248 }
6249
6250 return ret;
6251 }
6252
6253 static void
mxf_metadata_multiple_descriptor_init(MXFMetadataMultipleDescriptor * self)6254 mxf_metadata_multiple_descriptor_init (MXFMetadataMultipleDescriptor * self)
6255 {
6256
6257 }
6258
6259 static void
mxf_metadata_multiple_descriptor_class_init(MXFMetadataMultipleDescriptorClass * klass)6260 mxf_metadata_multiple_descriptor_class_init (MXFMetadataMultipleDescriptorClass
6261 * klass)
6262 {
6263 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
6264 GObjectClass *object_class = (GObjectClass *) klass;
6265 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
6266
6267 object_class->finalize = mxf_metadata_multiple_descriptor_finalize;
6268 metadata_base_class->handle_tag = mxf_metadata_multiple_descriptor_handle_tag;
6269 metadata_base_class->resolve = mxf_metadata_multiple_descriptor_resolve;
6270 metadata_base_class->name_quark = MXF_QUARK (MULTIPLE_DESCRIPTOR);
6271 metadata_base_class->to_structure =
6272 mxf_metadata_multiple_descriptor_to_structure;
6273 metadata_base_class->write_tags = mxf_metadata_multiple_descriptor_write_tags;
6274 metadata_class->type = 0x0144;
6275 }
6276
6277 G_DEFINE_ABSTRACT_TYPE (MXFMetadataLocator, mxf_metadata_locator,
6278 MXF_TYPE_METADATA);
6279
6280 static void
mxf_metadata_locator_init(MXFMetadataLocator * self)6281 mxf_metadata_locator_init (MXFMetadataLocator * self)
6282 {
6283 }
6284
6285 static void
mxf_metadata_locator_class_init(MXFMetadataLocatorClass * klass)6286 mxf_metadata_locator_class_init (MXFMetadataLocatorClass * klass)
6287 {
6288 }
6289
6290 G_DEFINE_TYPE (MXFMetadataTextLocator, mxf_metadata_text_locator,
6291 MXF_TYPE_METADATA_LOCATOR);
6292
6293 static void
mxf_metadata_text_locator_finalize(GObject * object)6294 mxf_metadata_text_locator_finalize (GObject * object)
6295 {
6296 MXFMetadataTextLocator *self = MXF_METADATA_TEXT_LOCATOR (object);
6297
6298 g_free (self->locator_name);
6299 self->locator_name = NULL;
6300
6301 G_OBJECT_CLASS (mxf_metadata_text_locator_parent_class)->finalize (object);
6302 }
6303
6304 static gboolean
mxf_metadata_text_locator_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)6305 mxf_metadata_text_locator_handle_tag (MXFMetadataBase * metadata,
6306 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
6307 guint tag_size)
6308 {
6309 MXFMetadataTextLocator *self = MXF_METADATA_TEXT_LOCATOR (metadata);
6310 gboolean ret = TRUE;
6311
6312 switch (tag) {
6313 case 0x4101:
6314 self->locator_name = mxf_utf16_to_utf8 (tag_data, tag_size);
6315 GST_DEBUG (" text locator = %s", GST_STR_NULL (self->locator_name));
6316 break;
6317 default:
6318 ret =
6319 MXF_METADATA_BASE_CLASS
6320 (mxf_metadata_text_locator_parent_class)->handle_tag (metadata,
6321 primer, tag, tag_data, tag_size);
6322 break;
6323 }
6324
6325 return ret;
6326 }
6327
6328 static GstStructure *
mxf_metadata_text_locator_to_structure(MXFMetadataBase * m)6329 mxf_metadata_text_locator_to_structure (MXFMetadataBase * m)
6330 {
6331 GstStructure *ret =
6332 MXF_METADATA_BASE_CLASS
6333 (mxf_metadata_text_locator_parent_class)->to_structure (m);
6334 MXFMetadataTextLocator *self = MXF_METADATA_TEXT_LOCATOR (m);
6335
6336 gst_structure_id_set (ret, MXF_QUARK (LOCATOR_NAME), G_TYPE_STRING,
6337 self->locator_name, NULL);
6338
6339 return ret;
6340 }
6341
6342 static GList *
mxf_metadata_text_locator_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)6343 mxf_metadata_text_locator_write_tags (MXFMetadataBase * m,
6344 MXFPrimerPack * primer)
6345 {
6346 MXFMetadataTextLocator *self = MXF_METADATA_TEXT_LOCATOR (m);
6347 GList *ret =
6348 MXF_METADATA_BASE_CLASS
6349 (mxf_metadata_text_locator_parent_class)->write_tags (m, primer);
6350 MXFLocalTag *t;
6351
6352 if (self->locator_name) {
6353 t = g_slice_new0 (MXFLocalTag);
6354 memcpy (&t->ul, MXF_UL (LOCATOR_NAME), 16);
6355 t->data = mxf_utf8_to_utf16 (self->locator_name, &t->size);
6356 mxf_primer_pack_add_mapping (primer, 0x4101, &t->ul);
6357 ret = g_list_prepend (ret, t);
6358 }
6359
6360 return ret;
6361 }
6362
6363 static void
mxf_metadata_text_locator_init(MXFMetadataTextLocator * self)6364 mxf_metadata_text_locator_init (MXFMetadataTextLocator * self)
6365 {
6366
6367 }
6368
6369 static void
mxf_metadata_text_locator_class_init(MXFMetadataTextLocatorClass * klass)6370 mxf_metadata_text_locator_class_init (MXFMetadataTextLocatorClass * klass)
6371 {
6372 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
6373 GObjectClass *object_class = (GObjectClass *) klass;
6374 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
6375
6376 object_class->finalize = mxf_metadata_text_locator_finalize;
6377 metadata_base_class->handle_tag = mxf_metadata_text_locator_handle_tag;
6378 metadata_base_class->name_quark = MXF_QUARK (TEXT_LOCATOR);
6379 metadata_base_class->to_structure = mxf_metadata_text_locator_to_structure;
6380 metadata_base_class->write_tags = mxf_metadata_text_locator_write_tags;
6381 metadata_class->type = 0x0133;
6382 }
6383
6384 G_DEFINE_TYPE (MXFMetadataNetworkLocator, mxf_metadata_network_locator,
6385 MXF_TYPE_METADATA_LOCATOR);
6386
6387 static void
mxf_metadata_network_locator_finalize(GObject * object)6388 mxf_metadata_network_locator_finalize (GObject * object)
6389 {
6390 MXFMetadataNetworkLocator *self = MXF_METADATA_NETWORK_LOCATOR (object);
6391
6392 g_free (self->url_string);
6393 self->url_string = NULL;
6394
6395 G_OBJECT_CLASS (mxf_metadata_network_locator_parent_class)->finalize (object);
6396 }
6397
6398 static gboolean
mxf_metadata_network_locator_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)6399 mxf_metadata_network_locator_handle_tag (MXFMetadataBase * metadata,
6400 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
6401 guint tag_size)
6402 {
6403 MXFMetadataNetworkLocator *self = MXF_METADATA_NETWORK_LOCATOR (metadata);
6404 gboolean ret = TRUE;
6405
6406 switch (tag) {
6407 case 0x4101:
6408 self->url_string = mxf_utf16_to_utf8 (tag_data, tag_size);
6409 GST_DEBUG (" url string = %s", GST_STR_NULL (self->url_string));
6410 break;
6411 default:
6412 ret =
6413 MXF_METADATA_BASE_CLASS
6414 (mxf_metadata_network_locator_parent_class)->handle_tag (metadata,
6415 primer, tag, tag_data, tag_size);
6416 break;
6417 }
6418
6419 return ret;
6420 }
6421
6422 static GstStructure *
mxf_metadata_network_locator_to_structure(MXFMetadataBase * m)6423 mxf_metadata_network_locator_to_structure (MXFMetadataBase * m)
6424 {
6425 GstStructure *ret =
6426 MXF_METADATA_BASE_CLASS
6427 (mxf_metadata_network_locator_parent_class)->to_structure (m);
6428 MXFMetadataNetworkLocator *self = MXF_METADATA_NETWORK_LOCATOR (m);
6429
6430 gst_structure_id_set (ret, MXF_QUARK (URL_STRING), G_TYPE_STRING,
6431 self->url_string, NULL);
6432
6433 return ret;
6434 }
6435
6436 static GList *
mxf_metadata_network_locator_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)6437 mxf_metadata_network_locator_write_tags (MXFMetadataBase * m,
6438 MXFPrimerPack * primer)
6439 {
6440 MXFMetadataNetworkLocator *self = MXF_METADATA_NETWORK_LOCATOR (m);
6441 GList *ret =
6442 MXF_METADATA_BASE_CLASS
6443 (mxf_metadata_network_locator_parent_class)->write_tags (m, primer);
6444 MXFLocalTag *t;
6445
6446 if (self->url_string) {
6447 t = g_slice_new0 (MXFLocalTag);
6448 memcpy (&t->ul, MXF_UL (URL_STRING), 16);
6449 t->data = mxf_utf8_to_utf16 (self->url_string, &t->size);
6450 mxf_primer_pack_add_mapping (primer, 0x4001, &t->ul);
6451 ret = g_list_prepend (ret, t);
6452 }
6453
6454 return ret;
6455 }
6456
6457 static void
mxf_metadata_network_locator_init(MXFMetadataNetworkLocator * self)6458 mxf_metadata_network_locator_init (MXFMetadataNetworkLocator * self)
6459 {
6460 }
6461
6462 static void
mxf_metadata_network_locator_class_init(MXFMetadataNetworkLocatorClass * klass)6463 mxf_metadata_network_locator_class_init (MXFMetadataNetworkLocatorClass * klass)
6464 {
6465 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
6466 GObjectClass *object_class = (GObjectClass *) klass;
6467 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
6468
6469 object_class->finalize = mxf_metadata_network_locator_finalize;
6470 metadata_base_class->handle_tag = mxf_metadata_network_locator_handle_tag;
6471 metadata_base_class->name_quark = MXF_QUARK (NETWORK_LOCATOR);
6472 metadata_base_class->to_structure = mxf_metadata_network_locator_to_structure;
6473 metadata_base_class->write_tags = mxf_metadata_network_locator_write_tags;
6474 metadata_class->type = 0x0133;
6475 }
6476
6477 G_DEFINE_ABSTRACT_TYPE (MXFDescriptiveMetadata, mxf_descriptive_metadata,
6478 MXF_TYPE_METADATA_BASE);
6479
6480 static void
mxf_descriptive_metadata_init(MXFDescriptiveMetadata * self)6481 mxf_descriptive_metadata_init (MXFDescriptiveMetadata * self)
6482 {
6483 }
6484
6485 static void
mxf_descriptive_metadata_class_init(MXFDescriptiveMetadataClass * klass)6486 mxf_descriptive_metadata_class_init (MXFDescriptiveMetadataClass * klass)
6487 {
6488 }
6489
6490 typedef struct
6491 {
6492 guint8 scheme;
6493 GType *types;
6494 } _MXFDescriptiveMetadataScheme;
6495
6496 static GArray *_dm_schemes = NULL;
6497
6498 void
mxf_descriptive_metadata_register(guint8 scheme,GType * types)6499 mxf_descriptive_metadata_register (guint8 scheme, GType * types)
6500 {
6501 _MXFDescriptiveMetadataScheme s;
6502
6503 if (!_dm_schemes)
6504 _dm_schemes =
6505 g_array_new (FALSE, TRUE, sizeof (_MXFDescriptiveMetadataScheme));
6506
6507 s.scheme = scheme;
6508 s.types = types;
6509
6510 g_array_append_val (_dm_schemes, s);
6511 }
6512
6513 MXFDescriptiveMetadata *
mxf_descriptive_metadata_new(guint8 scheme,guint32 type,MXFPrimerPack * primer,guint64 offset,const guint8 * data,guint size)6514 mxf_descriptive_metadata_new (guint8 scheme, guint32 type,
6515 MXFPrimerPack * primer, guint64 offset, const guint8 * data, guint size)
6516 {
6517 guint i;
6518 GType t = G_TYPE_INVALID, *p;
6519 _MXFDescriptiveMetadataScheme *s = NULL;
6520 MXFDescriptiveMetadata *ret = NULL;
6521
6522 g_return_val_if_fail (primer != NULL, NULL);
6523
6524 if (G_UNLIKELY (type == 0)) {
6525 GST_WARNING ("Type 0 is invalid");
6526 return NULL;
6527 }
6528
6529 for (i = 0; _dm_schemes && i < _dm_schemes->len; i++) {
6530 _MXFDescriptiveMetadataScheme *data =
6531 &g_array_index (_dm_schemes, _MXFDescriptiveMetadataScheme, i);
6532
6533 if (data->scheme == scheme) {
6534 s = data;
6535 break;
6536 }
6537 }
6538
6539 if (s == NULL) {
6540 GST_WARNING ("Descriptive metadata scheme 0x%02x not supported", scheme);
6541 return NULL;
6542 }
6543
6544 p = s->types;
6545 while (*p) {
6546 GType tmp = *p;
6547 MXFDescriptiveMetadataClass *klass =
6548 MXF_DESCRIPTIVE_METADATA_CLASS (g_type_class_ref (tmp));
6549
6550 if (klass->type == type) {
6551 g_type_class_unref (klass);
6552 t = tmp;
6553 break;
6554 }
6555 g_type_class_unref (klass);
6556 p++;
6557 }
6558
6559 if (t == G_TYPE_INVALID) {
6560 GST_WARNING
6561 ("No handler for type 0x%06x of descriptive metadata scheme 0x%02x found",
6562 type, scheme);
6563 return NULL;
6564 }
6565
6566 GST_DEBUG ("DM scheme 0x%02x type 0x%06x is handled by type %s", scheme, type,
6567 g_type_name (t));
6568
6569 ret = (MXFDescriptiveMetadata *) g_type_create_instance (t);
6570 if (!mxf_metadata_base_parse (MXF_METADATA_BASE (ret), primer, data, size)) {
6571 GST_ERROR ("Parsing metadata failed");
6572 g_object_unref (ret);
6573 return NULL;
6574 }
6575
6576 ret->parent.offset = offset;
6577
6578 return ret;
6579 }
6580
6581 GType
mxf_descriptive_metadata_framework_get_type(void)6582 mxf_descriptive_metadata_framework_get_type (void)
6583 {
6584 static volatile gsize type = 0;
6585 if (g_once_init_enter (&type)) {
6586 GType _type = 0;
6587 static const GTypeInfo info = {
6588 sizeof (MXFDescriptiveMetadataFrameworkInterface),
6589 NULL, /* base_init */
6590 NULL, /* base_finalize */
6591 NULL, /* class_init */
6592 NULL, /* class_finalize */
6593 NULL, /* class_data */
6594 0, /* instance_size */
6595 0, /* n_preallocs */
6596 NULL /* instance_init */
6597 };
6598 _type = g_type_register_static (G_TYPE_INTERFACE,
6599 "MXFDescriptiveMetadataFrameworkInterface", &info, 0);
6600
6601 g_type_interface_add_prerequisite (_type, MXF_TYPE_DESCRIPTIVE_METADATA);
6602
6603 g_once_init_leave (&type, (gsize) _type);
6604 }
6605
6606 return (GType) type;
6607 }
6608
6609 GHashTable *
mxf_metadata_hash_table_new(void)6610 mxf_metadata_hash_table_new (void)
6611 {
6612 return g_hash_table_new_full ((GHashFunc) mxf_uuid_hash,
6613 (GEqualFunc) mxf_uuid_is_equal, (GDestroyNotify) NULL,
6614 (GDestroyNotify) g_object_unref);
6615 }
6616