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_memdup2 (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 self->is_interleaved = MXF_IS_METADATA_MULTIPLE_DESCRIPTOR (self->descriptor);
2251
2252 for (i = 0; i < package->n_tracks; i++) {
2253 if (!package->tracks[i])
2254 continue;
2255
2256 if (!MXF_IS_METADATA_MULTIPLE_DESCRIPTOR (d)) {
2257 if (d->linked_track_id == package->tracks[i]->track_id ||
2258 (d->linked_track_id == 0 && package->n_essence_tracks == 1 &&
2259 (package->tracks[i]->type & 0xf0) == 0x30)) {
2260 g_free (package->tracks[i]->descriptor);
2261 package->tracks[i]->descriptor =
2262 g_new0 (MXFMetadataFileDescriptor *, 1);
2263 package->tracks[i]->descriptor[0] = d;
2264 package->tracks[i]->n_descriptor = 1;
2265 break;
2266 }
2267 } else {
2268 guint n_descriptor = 0, j, k = 0;
2269 MXFMetadataMultipleDescriptor *md = MXF_METADATA_MULTIPLE_DESCRIPTOR (d);
2270
2271 for (j = 0; j < md->n_sub_descriptors; j++) {
2272 MXFMetadataFileDescriptor *fd;
2273
2274 if (!md->sub_descriptors[j] ||
2275 !MXF_METADATA_FILE_DESCRIPTOR (md->sub_descriptors[j]))
2276 continue;
2277
2278 fd = MXF_METADATA_FILE_DESCRIPTOR (md->sub_descriptors[j]);
2279
2280 if (fd->linked_track_id == package->tracks[i]->track_id ||
2281 (fd->linked_track_id == 0 && package->n_essence_tracks == 1 &&
2282 (package->tracks[i]->type & 0xf0) == 0x30))
2283 n_descriptor++;
2284 }
2285
2286 g_free (package->tracks[i]->descriptor);
2287 package->tracks[i]->descriptor =
2288 g_new0 (MXFMetadataFileDescriptor *, n_descriptor);
2289 package->tracks[i]->n_descriptor = n_descriptor;
2290
2291 for (j = 0; j < md->n_sub_descriptors; j++) {
2292 MXFMetadataFileDescriptor *fd;
2293
2294 if (!md->sub_descriptors[j] ||
2295 !MXF_METADATA_FILE_DESCRIPTOR (md->sub_descriptors[j]))
2296 continue;
2297
2298 fd = MXF_METADATA_FILE_DESCRIPTOR (md->sub_descriptors[j]);
2299
2300 if (fd->linked_track_id == package->tracks[i]->track_id ||
2301 (fd->linked_track_id == 0 && package->n_essence_tracks == 1 &&
2302 (package->tracks[i]->type & 0xf0) == 0x30)) {
2303 package->tracks[i]->descriptor[k] = fd;
2304 k++;
2305 }
2306 }
2307 }
2308 }
2309
2310 return ret;
2311 }
2312
2313 static GstStructure *
mxf_metadata_source_package_to_structure(MXFMetadataBase * m)2314 mxf_metadata_source_package_to_structure (MXFMetadataBase * m)
2315 {
2316 GstStructure *ret =
2317 MXF_METADATA_BASE_CLASS
2318 (mxf_metadata_source_package_parent_class)->to_structure (m);
2319 MXFMetadataSourcePackage *self = MXF_METADATA_SOURCE_PACKAGE (m);
2320 GstStructure *s;
2321
2322 if (!self->descriptor)
2323 return ret;
2324
2325 s = mxf_metadata_base_to_structure (MXF_METADATA_BASE (self->descriptor));
2326 gst_structure_id_set (ret, MXF_QUARK (DESCRIPTOR), GST_TYPE_STRUCTURE, s,
2327 NULL);
2328 gst_structure_free (s);
2329
2330 return ret;
2331 }
2332
2333 static GList *
mxf_metadata_source_package_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)2334 mxf_metadata_source_package_write_tags (MXFMetadataBase * m,
2335 MXFPrimerPack * primer)
2336 {
2337 MXFMetadataSourcePackage *self = MXF_METADATA_SOURCE_PACKAGE (m);
2338 GList *ret =
2339 MXF_METADATA_BASE_CLASS
2340 (mxf_metadata_source_package_parent_class)->write_tags (m, primer);
2341 MXFLocalTag *t;
2342
2343 if (self->descriptor) {
2344 t = g_slice_new0 (MXFLocalTag);
2345 memcpy (&t->ul, MXF_UL (DESCRIPTOR), 16);
2346 t->size = 16;
2347 t->data = g_slice_alloc (t->size);
2348 t->g_slice = TRUE;
2349 memcpy (t->data, &MXF_METADATA_BASE (self->descriptor)->instance_uid, 16);
2350 mxf_primer_pack_add_mapping (primer, 0x4701, &t->ul);
2351 ret = g_list_prepend (ret, t);
2352 }
2353
2354 return ret;
2355 }
2356
2357 static void
mxf_metadata_source_package_init(MXFMetadataSourcePackage * self)2358 mxf_metadata_source_package_init (MXFMetadataSourcePackage * self)
2359 {
2360
2361 }
2362
2363 static void
mxf_metadata_source_package_class_init(MXFMetadataSourcePackageClass * klass)2364 mxf_metadata_source_package_class_init (MXFMetadataSourcePackageClass * klass)
2365 {
2366 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
2367 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
2368
2369 metadata_base_class->handle_tag = mxf_metadata_source_package_handle_tag;
2370 metadata_base_class->resolve = mxf_metadata_source_package_resolve;
2371 metadata_base_class->name_quark = MXF_QUARK (SOURCE_PACKAGE);
2372 metadata_base_class->to_structure = mxf_metadata_source_package_to_structure;
2373 metadata_base_class->write_tags = mxf_metadata_source_package_write_tags;
2374 metadata_class->type = 0x0137;
2375 }
2376
2377 G_DEFINE_ABSTRACT_TYPE (MXFMetadataTrack, mxf_metadata_track,
2378 MXF_TYPE_METADATA);
2379
2380 static void
mxf_metadata_track_finalize(GObject * object)2381 mxf_metadata_track_finalize (GObject * object)
2382 {
2383 MXFMetadataTrack *self = MXF_METADATA_TRACK (object);
2384
2385 g_free (self->track_name);
2386 self->track_name = NULL;
2387 g_free (self->descriptor);
2388 self->descriptor = NULL;
2389
2390 G_OBJECT_CLASS (mxf_metadata_track_parent_class)->finalize (object);
2391 }
2392
2393 static gboolean
mxf_metadata_track_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)2394 mxf_metadata_track_handle_tag (MXFMetadataBase * metadata,
2395 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
2396 guint tag_size)
2397 {
2398 MXFMetadataTrack *self = MXF_METADATA_TRACK (metadata);
2399 gboolean ret = TRUE;
2400 #ifndef GST_DISABLE_GST_DEBUG
2401 gchar str[48];
2402 #endif
2403
2404 switch (tag) {
2405 case 0x4801:
2406 if (tag_size != 4)
2407 goto error;
2408 self->track_id = GST_READ_UINT32_BE (tag_data);
2409 GST_DEBUG (" track id = %u", self->track_id);
2410 break;
2411 case 0x4804:
2412 if (tag_size != 4)
2413 goto error;
2414 self->track_number = GST_READ_UINT32_BE (tag_data);
2415 GST_DEBUG (" track number = %u", self->track_number);
2416 break;
2417 case 0x4802:
2418 self->track_name = mxf_utf16_to_utf8 (tag_data, tag_size);
2419 GST_DEBUG (" track name = %s", GST_STR_NULL (self->track_name));
2420 break;
2421 case 0x4803:
2422 if (tag_size != 16)
2423 goto error;
2424 memcpy (&self->sequence_uid, tag_data, 16);
2425 GST_DEBUG (" sequence uid = %s",
2426 mxf_uuid_to_string (&self->sequence_uid, str));
2427 break;
2428 default:
2429 ret =
2430 MXF_METADATA_BASE_CLASS (mxf_metadata_track_parent_class)->handle_tag
2431 (metadata, primer, tag, tag_data, tag_size);
2432 break;
2433 }
2434
2435 return ret;
2436
2437 error:
2438
2439 GST_ERROR ("Invalid track local tag 0x%04x of size %u", tag, tag_size);
2440
2441 return FALSE;
2442 }
2443
2444 static gboolean
mxf_metadata_track_resolve(MXFMetadataBase * m,GHashTable * metadata)2445 mxf_metadata_track_resolve (MXFMetadataBase * m, GHashTable * metadata)
2446 {
2447 MXFMetadataTrack *self = MXF_METADATA_TRACK (m);
2448 MXFMetadataBase *current = NULL;
2449 guint i;
2450 #ifndef GST_DISABLE_GST_DEBUG
2451 gchar str[48];
2452 #endif
2453
2454 current = g_hash_table_lookup (metadata, &self->sequence_uid);
2455 if (current && MXF_IS_METADATA_SEQUENCE (current)) {
2456 if (mxf_metadata_base_resolve (current, metadata)) {
2457 self->sequence = MXF_METADATA_SEQUENCE (current);
2458 } else {
2459 GST_ERROR ("Couldn't resolve sequence %s",
2460 mxf_uuid_to_string (&self->sequence_uid, str));
2461 return FALSE;
2462 }
2463 } else {
2464 GST_ERROR ("Couldn't find sequence %s",
2465 mxf_uuid_to_string (&self->sequence_uid, str));
2466 return FALSE;
2467 }
2468
2469 self->type =
2470 mxf_metadata_track_identifier_parse (&self->sequence->data_definition);
2471 if (self->type == MXF_METADATA_TRACK_UNKNOWN) {
2472 MXFMetadataSequence *sequence = self->sequence;
2473
2474 for (i = 0; i < sequence->n_structural_components; i++) {
2475 MXFMetadataStructuralComponent *component =
2476 sequence->structural_components[i];
2477
2478 if (!component)
2479 continue;
2480
2481 self->type =
2482 mxf_metadata_track_identifier_parse (&component->data_definition);
2483 if (self->type != MXF_METADATA_TRACK_UNKNOWN)
2484 break;
2485 }
2486 }
2487
2488 return MXF_METADATA_BASE_CLASS (mxf_metadata_track_parent_class)->resolve (m,
2489 metadata);
2490 }
2491
2492 static GstStructure *
mxf_metadata_track_to_structure(MXFMetadataBase * m)2493 mxf_metadata_track_to_structure (MXFMetadataBase * m)
2494 {
2495 GstStructure *ret =
2496 MXF_METADATA_BASE_CLASS (mxf_metadata_track_parent_class)->to_structure
2497 (m);
2498 MXFMetadataTrack *self = MXF_METADATA_TRACK (m);
2499
2500 gst_structure_id_set (ret, MXF_QUARK (TRACK_ID), G_TYPE_UINT, self->track_id,
2501 MXF_QUARK (TRACK_NUMBER), G_TYPE_UINT, self->track_number, NULL);
2502
2503 if (self->track_name)
2504 gst_structure_id_set (ret, MXF_QUARK (TRACK_NAME), G_TYPE_STRING,
2505 self->track_name, NULL);
2506
2507 if (self->sequence) {
2508 GstStructure *s =
2509 mxf_metadata_base_to_structure (MXF_METADATA_BASE (self->sequence));
2510
2511 gst_structure_id_set (ret, MXF_QUARK (SEQUENCE), GST_TYPE_STRUCTURE, s,
2512 NULL);
2513 gst_structure_free (s);
2514 }
2515
2516
2517 return ret;
2518 }
2519
2520 static GList *
mxf_metadata_track_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)2521 mxf_metadata_track_write_tags (MXFMetadataBase * m, MXFPrimerPack * primer)
2522 {
2523 MXFMetadataTrack *self = MXF_METADATA_TRACK (m);
2524 GList *ret =
2525 MXF_METADATA_BASE_CLASS (mxf_metadata_track_parent_class)->write_tags (m,
2526 primer);
2527 MXFLocalTag *t;
2528
2529 t = g_slice_new0 (MXFLocalTag);
2530 memcpy (&t->ul, MXF_UL (TRACK_ID), 16);
2531 t->size = 4;
2532 t->data = g_slice_alloc (t->size);
2533 t->g_slice = TRUE;
2534 GST_WRITE_UINT32_BE (t->data, self->track_id);
2535 mxf_primer_pack_add_mapping (primer, 0x4801, &t->ul);
2536 ret = g_list_prepend (ret, t);
2537
2538 t = g_slice_new0 (MXFLocalTag);
2539 memcpy (&t->ul, MXF_UL (TRACK_NUMBER), 16);
2540 t->size = 4;
2541 t->data = g_slice_alloc (t->size);
2542 t->g_slice = TRUE;
2543 GST_WRITE_UINT32_BE (t->data, self->track_number);
2544 mxf_primer_pack_add_mapping (primer, 0x4804, &t->ul);
2545 ret = g_list_prepend (ret, t);
2546
2547 if (self->track_name) {
2548 t = g_slice_new0 (MXFLocalTag);
2549 memcpy (&t->ul, MXF_UL (TRACK_NAME), 16);
2550 t->data = mxf_utf8_to_utf16 (self->track_name, &t->size);
2551 mxf_primer_pack_add_mapping (primer, 0x4802, &t->ul);
2552 ret = g_list_prepend (ret, t);
2553 }
2554
2555 t = g_slice_new0 (MXFLocalTag);
2556 memcpy (&t->ul, MXF_UL (SEQUENCE), 16);
2557 t->size = 16;
2558 t->data = g_slice_alloc (t->size);
2559 t->g_slice = TRUE;
2560 memcpy (t->data, &MXF_METADATA_BASE (self->sequence)->instance_uid, 16);
2561 mxf_primer_pack_add_mapping (primer, 0x4803, &t->ul);
2562 ret = g_list_prepend (ret, t);
2563
2564 return ret;
2565 }
2566
2567 static void
mxf_metadata_track_init(MXFMetadataTrack * self)2568 mxf_metadata_track_init (MXFMetadataTrack * self)
2569 {
2570
2571 }
2572
2573 static void
mxf_metadata_track_class_init(MXFMetadataTrackClass * klass)2574 mxf_metadata_track_class_init (MXFMetadataTrackClass * klass)
2575 {
2576 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
2577 GObjectClass *object_class = (GObjectClass *) klass;
2578
2579 object_class->finalize = mxf_metadata_track_finalize;
2580 metadata_base_class->handle_tag = mxf_metadata_track_handle_tag;
2581 metadata_base_class->resolve = mxf_metadata_track_resolve;
2582 metadata_base_class->to_structure = mxf_metadata_track_to_structure;
2583 metadata_base_class->write_tags = mxf_metadata_track_write_tags;
2584 }
2585
2586 /* SMPTE RP224 */
2587 static const struct
2588 {
2589 const MXFUL *ul;
2590 const MXFMetadataTrackType type;
2591 } mxf_metadata_track_identifier[] = {
2592 {
2593 MXF_UL (TRACK_TIMECODE_12M_INACTIVE),
2594 MXF_METADATA_TRACK_TIMECODE_12M_INACTIVE}, {
2595 MXF_UL (TRACK_TIMECODE_12M_ACTIVE), MXF_METADATA_TRACK_TIMECODE_12M_ACTIVE}, {
2596 MXF_UL (TRACK_TIMECODE_309M), MXF_METADATA_TRACK_TIMECODE_309M}, {
2597 MXF_UL (TRACK_METADATA), MXF_METADATA_TRACK_METADATA}, {
2598 MXF_UL (TRACK_PICTURE_ESSENCE), MXF_METADATA_TRACK_PICTURE_ESSENCE}, {
2599 MXF_UL (TRACK_SOUND_ESSENCE), MXF_METADATA_TRACK_SOUND_ESSENCE}, {
2600 MXF_UL (TRACK_DATA_ESSENCE), MXF_METADATA_TRACK_DATA_ESSENCE}, {
2601 MXF_UL (TRACK_AUXILIARY_DATA), MXF_METADATA_TRACK_AUXILIARY_DATA}, {
2602 MXF_UL (TRACK_PARSED_TEXT), MXF_METADATA_TRACK_PARSED_TEXT},
2603 /* Avid video? */
2604 {
2605 MXF_UL (TRACK_AVID_PICTURE_ESSENCE), MXF_METADATA_TRACK_PICTURE_ESSENCE}
2606 };
2607
2608 MXFMetadataTrackType
mxf_metadata_track_identifier_parse(const MXFUL * track_identifier)2609 mxf_metadata_track_identifier_parse (const MXFUL * track_identifier)
2610 {
2611 guint i;
2612
2613 for (i = 0; i < G_N_ELEMENTS (mxf_metadata_track_identifier); i++)
2614 if (mxf_ul_is_equal (mxf_metadata_track_identifier[i].ul, track_identifier))
2615 return mxf_metadata_track_identifier[i].type;
2616
2617 return MXF_METADATA_TRACK_UNKNOWN;
2618 }
2619
2620 const MXFUL *
mxf_metadata_track_identifier_get(MXFMetadataTrackType type)2621 mxf_metadata_track_identifier_get (MXFMetadataTrackType type)
2622 {
2623 guint i;
2624
2625 for (i = 0; i < G_N_ELEMENTS (mxf_metadata_track_identifier); i++)
2626 if (mxf_metadata_track_identifier[i].type == type)
2627 return mxf_metadata_track_identifier[i].ul;
2628
2629 return NULL;
2630 }
2631
2632 G_DEFINE_TYPE (MXFMetadataTimelineTrack, mxf_metadata_timeline_track,
2633 MXF_TYPE_METADATA_TRACK);
2634
2635 static gboolean
mxf_metadata_timeline_track_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)2636 mxf_metadata_timeline_track_handle_tag (MXFMetadataBase * metadata,
2637 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
2638 guint tag_size)
2639 {
2640 MXFMetadataTimelineTrack *self = MXF_METADATA_TIMELINE_TRACK (metadata);
2641 gboolean ret = TRUE;
2642
2643 switch (tag) {
2644 case 0x4b01:
2645 if (!mxf_fraction_parse (&self->edit_rate, tag_data, tag_size))
2646 goto error;
2647 GST_DEBUG (" edit rate = %d/%d", self->edit_rate.n, self->edit_rate.d);
2648 break;
2649 case 0x4b02:
2650 if (tag_size != 8)
2651 goto error;
2652 self->origin = GST_READ_UINT64_BE (tag_data);
2653 GST_DEBUG (" origin = %" G_GINT64_FORMAT, self->origin);
2654 break;
2655 default:
2656 ret =
2657 MXF_METADATA_BASE_CLASS
2658 (mxf_metadata_timeline_track_parent_class)->handle_tag (metadata,
2659 primer, tag, tag_data, tag_size);
2660 break;
2661 }
2662
2663 return ret;
2664
2665 error:
2666
2667 GST_ERROR ("Invalid timeline track local tag 0x%04x of size %u", tag,
2668 tag_size);
2669
2670 return FALSE;
2671 }
2672
2673 static GstStructure *
mxf_metadata_timeline_track_to_structure(MXFMetadataBase * m)2674 mxf_metadata_timeline_track_to_structure (MXFMetadataBase * m)
2675 {
2676 GstStructure *ret =
2677 MXF_METADATA_BASE_CLASS
2678 (mxf_metadata_timeline_track_parent_class)->to_structure (m);
2679 MXFMetadataTimelineTrack *self = MXF_METADATA_TIMELINE_TRACK (m);
2680
2681 gst_structure_id_set (ret, MXF_QUARK (EDIT_RATE), GST_TYPE_FRACTION,
2682 self->edit_rate.n, self->edit_rate.d, MXF_QUARK (ORIGIN), G_TYPE_INT64,
2683 self->origin, NULL);
2684
2685 return ret;
2686 }
2687
2688 static GList *
mxf_metadata_timeline_track_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)2689 mxf_metadata_timeline_track_write_tags (MXFMetadataBase * m,
2690 MXFPrimerPack * primer)
2691 {
2692 MXFMetadataTimelineTrack *self = MXF_METADATA_TIMELINE_TRACK (m);
2693 GList *ret =
2694 MXF_METADATA_BASE_CLASS
2695 (mxf_metadata_timeline_track_parent_class)->write_tags (m, primer);
2696 MXFLocalTag *t;
2697
2698 t = g_slice_new0 (MXFLocalTag);
2699 memcpy (&t->ul, MXF_UL (EDIT_RATE), 16);
2700 t->size = 8;
2701 t->data = g_slice_alloc (t->size);
2702 t->g_slice = TRUE;
2703 GST_WRITE_UINT32_BE (t->data, self->edit_rate.n);
2704 GST_WRITE_UINT32_BE (t->data + 4, self->edit_rate.d);
2705 mxf_primer_pack_add_mapping (primer, 0x4b01, &t->ul);
2706 ret = g_list_prepend (ret, t);
2707
2708 t = g_slice_new0 (MXFLocalTag);
2709 memcpy (&t->ul, MXF_UL (ORIGIN), 16);
2710 t->size = 8;
2711 t->data = g_slice_alloc (t->size);
2712 t->g_slice = TRUE;
2713 GST_WRITE_UINT64_BE (t->data, self->origin);
2714 mxf_primer_pack_add_mapping (primer, 0x4b02, &t->ul);
2715 ret = g_list_prepend (ret, t);
2716
2717 return ret;
2718 }
2719
2720 static void
mxf_metadata_timeline_track_init(MXFMetadataTimelineTrack * self)2721 mxf_metadata_timeline_track_init (MXFMetadataTimelineTrack * self)
2722 {
2723
2724 }
2725
2726 static void
mxf_metadata_timeline_track_class_init(MXFMetadataTimelineTrackClass * klass)2727 mxf_metadata_timeline_track_class_init (MXFMetadataTimelineTrackClass * klass)
2728 {
2729 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
2730 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
2731
2732 metadata_base_class->handle_tag = mxf_metadata_timeline_track_handle_tag;
2733 metadata_base_class->name_quark = MXF_QUARK (TIMELINE_TRACK);
2734 metadata_base_class->to_structure = mxf_metadata_timeline_track_to_structure;
2735 metadata_base_class->write_tags = mxf_metadata_timeline_track_write_tags;
2736 metadata_class->type = 0x013b;
2737 }
2738
2739 G_DEFINE_TYPE (MXFMetadataEventTrack, mxf_metadata_event_track,
2740 MXF_TYPE_METADATA_TRACK);
2741
2742 static gboolean
mxf_metadata_event_track_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)2743 mxf_metadata_event_track_handle_tag (MXFMetadataBase * metadata,
2744 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
2745 guint tag_size)
2746 {
2747 MXFMetadataEventTrack *self = MXF_METADATA_EVENT_TRACK (metadata);
2748 gboolean ret = TRUE;
2749
2750 switch (tag) {
2751 case 0x4901:
2752 if (!mxf_fraction_parse (&self->event_edit_rate, tag_data, tag_size))
2753 goto error;
2754 GST_DEBUG (" event edit rate = %d/%d", self->event_edit_rate.n,
2755 self->event_edit_rate.d);
2756 break;
2757 case 0x4902:
2758 if (tag_size != 8)
2759 goto error;
2760 self->event_origin = GST_READ_UINT64_BE (tag_data);
2761 GST_DEBUG (" event origin = %" G_GINT64_FORMAT, self->event_origin);
2762 break;
2763 default:
2764 ret =
2765 MXF_METADATA_BASE_CLASS
2766 (mxf_metadata_event_track_parent_class)->handle_tag (metadata, primer,
2767 tag, tag_data, tag_size);
2768 break;
2769 }
2770
2771 return ret;
2772
2773 error:
2774
2775 GST_ERROR ("Invalid event track local tag 0x%04x of size %u", tag, tag_size);
2776
2777 return FALSE;
2778 }
2779
2780 static GstStructure *
mxf_metadata_event_track_to_structure(MXFMetadataBase * m)2781 mxf_metadata_event_track_to_structure (MXFMetadataBase * m)
2782 {
2783 GstStructure *ret =
2784 MXF_METADATA_BASE_CLASS
2785 (mxf_metadata_event_track_parent_class)->to_structure (m);
2786 MXFMetadataEventTrack *self = MXF_METADATA_EVENT_TRACK (m);
2787
2788 gst_structure_id_set (ret, MXF_QUARK (EVENT_EDIT_RATE), GST_TYPE_FRACTION,
2789 self->event_edit_rate.n, self->event_edit_rate.d,
2790 MXF_QUARK (EVENT_ORIGIN), G_TYPE_INT64, self->event_origin, NULL);
2791
2792 return ret;
2793 }
2794
2795 static GList *
mxf_metadata_event_track_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)2796 mxf_metadata_event_track_write_tags (MXFMetadataBase * m,
2797 MXFPrimerPack * primer)
2798 {
2799 MXFMetadataEventTrack *self = MXF_METADATA_EVENT_TRACK (m);
2800 GList *ret =
2801 MXF_METADATA_BASE_CLASS
2802 (mxf_metadata_event_track_parent_class)->write_tags (m, primer);
2803 MXFLocalTag *t;
2804
2805 t = g_slice_new0 (MXFLocalTag);
2806 memcpy (&t->ul, MXF_UL (EVENT_EDIT_RATE), 16);
2807 t->size = 8;
2808 t->data = g_slice_alloc (t->size);
2809 t->g_slice = TRUE;
2810 GST_WRITE_UINT32_BE (t->data, self->event_edit_rate.n);
2811 GST_WRITE_UINT32_BE (t->data + 4, self->event_edit_rate.d);
2812 mxf_primer_pack_add_mapping (primer, 0x4901, &t->ul);
2813 ret = g_list_prepend (ret, t);
2814
2815 t = g_slice_new0 (MXFLocalTag);
2816 memcpy (&t->ul, MXF_UL (EVENT_ORIGIN), 16);
2817 t->size = 8;
2818 t->data = g_slice_alloc (t->size);
2819 t->g_slice = TRUE;
2820 GST_WRITE_UINT64_BE (t->data, self->event_origin);
2821 mxf_primer_pack_add_mapping (primer, 0x4902, &t->ul);
2822 ret = g_list_prepend (ret, t);
2823
2824 return ret;
2825 }
2826
2827 static void
mxf_metadata_event_track_init(MXFMetadataEventTrack * self)2828 mxf_metadata_event_track_init (MXFMetadataEventTrack * self)
2829 {
2830
2831 }
2832
2833 static void
mxf_metadata_event_track_class_init(MXFMetadataEventTrackClass * klass)2834 mxf_metadata_event_track_class_init (MXFMetadataEventTrackClass * klass)
2835 {
2836 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
2837 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
2838
2839 metadata_base_class->handle_tag = mxf_metadata_event_track_handle_tag;
2840 metadata_base_class->name_quark = MXF_QUARK (EVENT_TRACK);
2841 metadata_base_class->to_structure = mxf_metadata_event_track_to_structure;
2842 metadata_base_class->write_tags = mxf_metadata_event_track_write_tags;
2843 metadata_class->type = 0x0139;
2844 }
2845
2846 G_DEFINE_TYPE (MXFMetadataStaticTrack, mxf_metadata_static_track,
2847 MXF_TYPE_METADATA_TRACK);
2848
2849 static void
mxf_metadata_static_track_init(MXFMetadataStaticTrack * self)2850 mxf_metadata_static_track_init (MXFMetadataStaticTrack * self)
2851 {
2852 }
2853
2854 static void
mxf_metadata_static_track_class_init(MXFMetadataStaticTrackClass * klass)2855 mxf_metadata_static_track_class_init (MXFMetadataStaticTrackClass * klass)
2856 {
2857 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
2858 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
2859
2860 metadata_base_class->name_quark = MXF_QUARK (STATIC_TRACK);
2861 metadata_class->type = 0x013a;
2862 }
2863
2864 G_DEFINE_TYPE (MXFMetadataSequence, mxf_metadata_sequence, MXF_TYPE_METADATA);
2865
2866 static void
mxf_metadata_sequence_finalize(GObject * object)2867 mxf_metadata_sequence_finalize (GObject * object)
2868 {
2869 MXFMetadataSequence *self = MXF_METADATA_SEQUENCE (object);
2870
2871 g_free (self->structural_components_uids);
2872 self->structural_components_uids = NULL;
2873 g_free (self->structural_components);
2874 self->structural_components = NULL;
2875
2876 G_OBJECT_CLASS (mxf_metadata_sequence_parent_class)->finalize (object);
2877 }
2878
2879 static gboolean
mxf_metadata_sequence_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)2880 mxf_metadata_sequence_handle_tag (MXFMetadataBase * metadata,
2881 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
2882 guint tag_size)
2883 {
2884 MXFMetadataSequence *self = MXF_METADATA_SEQUENCE (metadata);
2885 gboolean ret = TRUE;
2886 #ifndef GST_DISABLE_GST_DEBUG
2887 gchar str[48];
2888 #endif
2889
2890 switch (tag) {
2891 case 0x0201:
2892 if (tag_size != 16)
2893 goto error;
2894 memcpy (&self->data_definition, tag_data, 16);
2895 GST_DEBUG (" data definition = %s",
2896 mxf_ul_to_string (&self->data_definition, str));
2897 break;
2898 case 0x0202:
2899 if (tag_size != 8)
2900 goto error;
2901 self->duration = GST_READ_UINT64_BE (tag_data);
2902 GST_DEBUG (" duration = %" G_GINT64_FORMAT, self->duration);
2903 break;
2904 case 0x1001:
2905 if (!mxf_uuid_array_parse (&self->structural_components_uids,
2906 &self->n_structural_components, tag_data, tag_size))
2907 goto error;
2908
2909 GST_DEBUG (" number of structural components = %u",
2910 self->n_structural_components);
2911 #ifndef GST_DISABLE_GST_DEBUG
2912 {
2913 guint i;
2914 for (i = 0; i < self->n_structural_components; i++) {
2915 GST_DEBUG (" structural component %u = %s", i,
2916 mxf_uuid_to_string (&self->structural_components_uids[i], str));
2917 }
2918 }
2919 #endif
2920 break;
2921 default:
2922 ret =
2923 MXF_METADATA_BASE_CLASS
2924 (mxf_metadata_sequence_parent_class)->handle_tag (metadata, primer,
2925 tag, tag_data, tag_size);
2926 break;
2927 }
2928
2929 return ret;
2930
2931 error:
2932
2933 GST_ERROR ("Invalid sequence local tag 0x%04x of size %u", tag, tag_size);
2934
2935 return FALSE;
2936 }
2937
2938 static gboolean
mxf_metadata_sequence_resolve(MXFMetadataBase * m,GHashTable * metadata)2939 mxf_metadata_sequence_resolve (MXFMetadataBase * m, GHashTable * metadata)
2940 {
2941 MXFMetadataSequence *self = MXF_METADATA_SEQUENCE (m);
2942 MXFMetadataBase *current = NULL;
2943 guint i;
2944 #ifndef GST_DISABLE_GST_DEBUG
2945 gchar str[48];
2946 #endif
2947
2948 if (self->structural_components)
2949 memset (self->structural_components, 0,
2950 sizeof (gpointer) * self->n_structural_components);
2951 else
2952 self->structural_components =
2953 g_new0 (MXFMetadataStructuralComponent *,
2954 self->n_structural_components);
2955 for (i = 0; i < self->n_structural_components; i++) {
2956 current =
2957 g_hash_table_lookup (metadata, &self->structural_components_uids[i]);
2958 if (current && MXF_IS_METADATA_STRUCTURAL_COMPONENT (current)) {
2959 if (mxf_metadata_base_resolve (current, metadata)) {
2960 self->structural_components[i] =
2961 MXF_METADATA_STRUCTURAL_COMPONENT (current);
2962 } else {
2963 GST_ERROR ("Couldn't resolve structural component %s",
2964 mxf_uuid_to_string (&self->structural_components_uids[i], str));
2965 return FALSE;
2966 }
2967 } else {
2968 GST_ERROR ("Structural component %s not found",
2969 mxf_uuid_to_string (&self->structural_components_uids[i], str));
2970 return FALSE;
2971 }
2972 }
2973
2974 return
2975 MXF_METADATA_BASE_CLASS (mxf_metadata_sequence_parent_class)->resolve (m,
2976 metadata);
2977
2978 }
2979
2980 static GstStructure *
mxf_metadata_sequence_to_structure(MXFMetadataBase * m)2981 mxf_metadata_sequence_to_structure (MXFMetadataBase * m)
2982 {
2983 GstStructure *ret =
2984 MXF_METADATA_BASE_CLASS (mxf_metadata_sequence_parent_class)->to_structure
2985 (m);
2986 MXFMetadataSequence *self = MXF_METADATA_SEQUENCE (m);
2987 guint i;
2988 gchar str[48];
2989
2990 mxf_ul_to_string (&self->data_definition, str);
2991 gst_structure_id_set (ret, MXF_QUARK (DATA_DEFINITION), G_TYPE_STRING, str,
2992 MXF_QUARK (DURATION), G_TYPE_INT64, self->duration, NULL);
2993
2994 if (self->n_structural_components > 0) {
2995 GValue arr = { 0, }
2996 , val = {
2997 0,};
2998
2999 g_value_init (&arr, GST_TYPE_ARRAY);
3000
3001 for (i = 0; i < self->n_structural_components; i++) {
3002 GstStructure *s;
3003
3004 if (self->structural_components[i] == NULL)
3005 continue;
3006
3007 g_value_init (&val, GST_TYPE_STRUCTURE);
3008
3009 s = mxf_metadata_base_to_structure (MXF_METADATA_BASE
3010 (self->structural_components[i]));
3011 gst_value_set_structure (&val, s);
3012 gst_structure_free (s);
3013 gst_value_array_append_value (&arr, &val);
3014 g_value_unset (&val);
3015 }
3016
3017 if (gst_value_array_get_size (&arr) > 0)
3018 gst_structure_id_set_value (ret, MXF_QUARK (STRUCTURAL_COMPONENTS), &arr);
3019
3020 g_value_unset (&arr);
3021 }
3022
3023 return ret;
3024 }
3025
3026 static GList *
mxf_metadata_sequence_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)3027 mxf_metadata_sequence_write_tags (MXFMetadataBase * m, MXFPrimerPack * primer)
3028 {
3029 MXFMetadataSequence *self = MXF_METADATA_SEQUENCE (m);
3030 GList *ret =
3031 MXF_METADATA_BASE_CLASS (mxf_metadata_sequence_parent_class)->write_tags
3032 (m, primer);
3033 MXFLocalTag *t;
3034
3035 t = g_slice_new0 (MXFLocalTag);
3036 memcpy (&t->ul, MXF_UL (DATA_DEFINITION), 16);
3037 t->size = 16;
3038 t->data = g_slice_alloc (t->size);
3039 t->g_slice = TRUE;
3040 memcpy (t->data, &self->data_definition, 16);
3041 mxf_primer_pack_add_mapping (primer, 0x0201, &t->ul);
3042 ret = g_list_prepend (ret, t);
3043
3044 t = g_slice_new0 (MXFLocalTag);
3045 memcpy (&t->ul, MXF_UL (DURATION), 16);
3046 t->size = 8;
3047 t->data = g_slice_alloc (t->size);
3048 t->g_slice = TRUE;
3049 GST_WRITE_UINT64_BE (t->data, self->duration);
3050 mxf_primer_pack_add_mapping (primer, 0x0202, &t->ul);
3051 ret = g_list_prepend (ret, t);
3052
3053 if (self->structural_components) {
3054 guint i;
3055 t = g_slice_new0 (MXFLocalTag);
3056 memcpy (&t->ul, MXF_UL (STRUCTURAL_COMPONENTS), 16);
3057 t->size = 8 + 16 * self->n_structural_components;
3058 t->data = g_slice_alloc0 (t->size);
3059 t->g_slice = TRUE;
3060
3061 GST_WRITE_UINT32_BE (t->data, self->n_structural_components);
3062 GST_WRITE_UINT32_BE (t->data + 4, 16);
3063 for (i = 0; i < self->n_structural_components; i++) {
3064 if (!self->structural_components[i])
3065 continue;
3066
3067 memcpy (t->data + 8 + i * 16,
3068 &MXF_METADATA_BASE (self->structural_components[i])->instance_uid,
3069 16);
3070 }
3071
3072 mxf_primer_pack_add_mapping (primer, 0x1001, &t->ul);
3073 ret = g_list_prepend (ret, t);
3074 }
3075
3076 return ret;
3077 }
3078
3079 static void
mxf_metadata_sequence_init(MXFMetadataSequence * self)3080 mxf_metadata_sequence_init (MXFMetadataSequence * self)
3081 {
3082 self->duration = -1;
3083 }
3084
3085 static void
mxf_metadata_sequence_class_init(MXFMetadataSequenceClass * klass)3086 mxf_metadata_sequence_class_init (MXFMetadataSequenceClass * klass)
3087 {
3088 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
3089 GObjectClass *object_class = (GObjectClass *) klass;
3090 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
3091
3092 object_class->finalize = mxf_metadata_sequence_finalize;
3093 metadata_base_class->handle_tag = mxf_metadata_sequence_handle_tag;
3094 metadata_base_class->resolve = mxf_metadata_sequence_resolve;
3095 metadata_base_class->name_quark = MXF_QUARK (SEQUENCE);
3096 metadata_base_class->to_structure = mxf_metadata_sequence_to_structure;
3097 metadata_base_class->write_tags = mxf_metadata_sequence_write_tags;
3098 metadata_class->type = 0x010f;
3099 }
3100
3101 G_DEFINE_TYPE (MXFMetadataStructuralComponent,
3102 mxf_metadata_structural_component, MXF_TYPE_METADATA);
3103
3104 static gboolean
mxf_metadata_structural_component_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)3105 mxf_metadata_structural_component_handle_tag (MXFMetadataBase * metadata,
3106 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
3107 guint tag_size)
3108 {
3109 MXFMetadataStructuralComponent *self =
3110 MXF_METADATA_STRUCTURAL_COMPONENT (metadata);
3111 gboolean ret = TRUE;
3112 #ifndef GST_DISABLE_GST_DEBUG
3113 gchar str[48];
3114 #endif
3115
3116 switch (tag) {
3117 case 0x0201:
3118 if (tag_size != 16)
3119 goto error;
3120 memcpy (&self->data_definition, tag_data, 16);
3121 GST_DEBUG (" data definition = %s",
3122 mxf_ul_to_string (&self->data_definition, str));
3123 break;
3124 case 0x0202:
3125 if (tag_size != 8)
3126 goto error;
3127 self->duration = GST_READ_UINT64_BE (tag_data);
3128 GST_DEBUG (" duration = %" G_GINT64_FORMAT, self->duration);
3129 break;
3130 default:
3131 ret =
3132 MXF_METADATA_BASE_CLASS
3133 (mxf_metadata_structural_component_parent_class)->handle_tag
3134 (metadata, primer, tag, tag_data, tag_size);
3135 break;
3136 }
3137
3138 return ret;
3139
3140 error:
3141
3142 GST_ERROR ("Invalid structural component local tag 0x%04x of size %u", tag,
3143 tag_size);
3144
3145 return FALSE;
3146 }
3147
3148 static GstStructure *
mxf_metadata_structural_component_to_structure(MXFMetadataBase * m)3149 mxf_metadata_structural_component_to_structure (MXFMetadataBase * m)
3150 {
3151 GstStructure *ret =
3152 MXF_METADATA_BASE_CLASS
3153 (mxf_metadata_structural_component_parent_class)->to_structure (m);
3154 MXFMetadataStructuralComponent *self = MXF_METADATA_STRUCTURAL_COMPONENT (m);
3155 gchar str[48];
3156
3157 mxf_ul_to_string (&self->data_definition, str);
3158 gst_structure_id_set (ret, MXF_QUARK (DATA_DEFINITION), G_TYPE_STRING, str,
3159 MXF_QUARK (DURATION), G_TYPE_INT64, self->duration, NULL);
3160
3161 return ret;
3162 }
3163
3164 static GList *
mxf_metadata_structural_component_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)3165 mxf_metadata_structural_component_write_tags (MXFMetadataBase * m,
3166 MXFPrimerPack * primer)
3167 {
3168 MXFMetadataStructuralComponent *self = MXF_METADATA_STRUCTURAL_COMPONENT (m);
3169 GList *ret =
3170 MXF_METADATA_BASE_CLASS
3171 (mxf_metadata_structural_component_parent_class)->write_tags (m, primer);
3172 MXFLocalTag *t;
3173
3174 t = g_slice_new0 (MXFLocalTag);
3175 memcpy (&t->ul, MXF_UL (DATA_DEFINITION), 16);
3176 t->size = 16;
3177 t->data = g_slice_alloc (t->size);
3178 t->g_slice = TRUE;
3179 memcpy (t->data, &self->data_definition, 16);
3180 mxf_primer_pack_add_mapping (primer, 0x0201, &t->ul);
3181 ret = g_list_prepend (ret, t);
3182
3183 t = g_slice_new0 (MXFLocalTag);
3184 memcpy (&t->ul, MXF_UL (DURATION), 16);
3185 t->size = 8;
3186 t->data = g_slice_alloc (t->size);
3187 t->g_slice = TRUE;
3188 GST_WRITE_UINT64_BE (t->data, self->duration);
3189 mxf_primer_pack_add_mapping (primer, 0x0202, &t->ul);
3190 ret = g_list_prepend (ret, t);
3191
3192 return ret;
3193 }
3194
3195 static void
mxf_metadata_structural_component_init(MXFMetadataStructuralComponent * self)3196 mxf_metadata_structural_component_init (MXFMetadataStructuralComponent * self)
3197 {
3198 self->duration = -1;
3199 }
3200
3201 static void
mxf_metadata_structural_component_class_init(MXFMetadataStructuralComponentClass * klass)3202 mxf_metadata_structural_component_class_init
3203 (MXFMetadataStructuralComponentClass * klass)
3204 {
3205 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
3206
3207 metadata_base_class->handle_tag =
3208 mxf_metadata_structural_component_handle_tag;
3209 metadata_base_class->to_structure =
3210 mxf_metadata_structural_component_to_structure;
3211 metadata_base_class->write_tags =
3212 mxf_metadata_structural_component_write_tags;
3213 }
3214
3215 G_DEFINE_TYPE (MXFMetadataTimecodeComponent, mxf_metadata_timecode_component,
3216 MXF_TYPE_METADATA_STRUCTURAL_COMPONENT);
3217
3218 static gboolean
mxf_metadata_timecode_component_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)3219 mxf_metadata_timecode_component_handle_tag (MXFMetadataBase * metadata,
3220 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
3221 guint tag_size)
3222 {
3223 MXFMetadataTimecodeComponent *self =
3224 MXF_METADATA_TIMECODE_COMPONENT (metadata);
3225 gboolean ret = TRUE;
3226
3227 switch (tag) {
3228 case 0x1502:
3229 if (tag_size != 2)
3230 goto error;
3231 self->rounded_timecode_base = GST_READ_UINT16_BE (tag_data);
3232 GST_DEBUG (" rounded timecode base = %u", self->rounded_timecode_base);
3233 break;
3234 case 0x1501:
3235 if (tag_size != 8)
3236 goto error;
3237 self->start_timecode = GST_READ_UINT64_BE (tag_data);
3238 GST_DEBUG (" start timecode = %" G_GINT64_FORMAT, self->start_timecode);
3239 break;
3240 case 0x1503:
3241 if (tag_size != 1)
3242 goto error;
3243 self->drop_frame = (GST_READ_UINT8 (tag_data) != 0);
3244 GST_DEBUG (" drop frame = %s", (self->drop_frame) ? "yes" : "no");
3245 break;
3246 default:
3247 ret =
3248 MXF_METADATA_BASE_CLASS
3249 (mxf_metadata_timecode_component_parent_class)->handle_tag (metadata,
3250 primer, tag, tag_data, tag_size);
3251 break;
3252 }
3253
3254 return ret;
3255
3256 error:
3257
3258 GST_ERROR ("Invalid timecode component local tag 0x%04x of size %u", tag,
3259 tag_size);
3260
3261 return FALSE;
3262 }
3263
3264 static GstStructure *
mxf_metadata_timecode_component_to_structure(MXFMetadataBase * m)3265 mxf_metadata_timecode_component_to_structure (MXFMetadataBase * m)
3266 {
3267 GstStructure *ret =
3268 MXF_METADATA_BASE_CLASS
3269 (mxf_metadata_timecode_component_parent_class)->to_structure (m);
3270 MXFMetadataTimecodeComponent *self = MXF_METADATA_TIMECODE_COMPONENT (m);
3271
3272 gst_structure_id_set (ret, MXF_QUARK (START_TIMECODE), G_TYPE_INT64,
3273 self->start_timecode, MXF_QUARK (ROUNDED_TIMECODE_BASE), G_TYPE_UINT,
3274 self->rounded_timecode_base, MXF_QUARK (DROP_FRAME), G_TYPE_BOOLEAN,
3275 self->drop_frame, NULL);
3276
3277 return ret;
3278 }
3279
3280 static GList *
mxf_metadata_timecode_component_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)3281 mxf_metadata_timecode_component_write_tags (MXFMetadataBase * m,
3282 MXFPrimerPack * primer)
3283 {
3284 MXFMetadataTimecodeComponent *self = MXF_METADATA_TIMECODE_COMPONENT (m);
3285 GList *ret =
3286 MXF_METADATA_BASE_CLASS
3287 (mxf_metadata_timecode_component_parent_class)->write_tags (m, primer);
3288 MXFLocalTag *t;
3289
3290 t = g_slice_new0 (MXFLocalTag);
3291 memcpy (&t->ul, MXF_UL (ROUNDED_TIMECODE_BASE), 16);
3292 t->size = 2;
3293 t->data = g_slice_alloc (t->size);
3294 t->g_slice = TRUE;
3295 GST_WRITE_UINT16_BE (t->data, self->rounded_timecode_base);
3296 mxf_primer_pack_add_mapping (primer, 0x1502, &t->ul);
3297 ret = g_list_prepend (ret, t);
3298
3299 t = g_slice_new0 (MXFLocalTag);
3300 memcpy (&t->ul, MXF_UL (START_TIMECODE), 16);
3301 t->size = 8;
3302 t->data = g_slice_alloc (t->size);
3303 t->g_slice = TRUE;
3304 GST_WRITE_UINT64_BE (t->data, self->start_timecode);
3305 mxf_primer_pack_add_mapping (primer, 0x1501, &t->ul);
3306 ret = g_list_prepend (ret, t);
3307
3308 t = g_slice_new0 (MXFLocalTag);
3309 memcpy (&t->ul, MXF_UL (DROP_FRAME), 16);
3310 t->size = 1;
3311 t->data = g_slice_alloc (t->size);
3312 t->g_slice = TRUE;
3313 GST_WRITE_UINT8 (t->data, (self->drop_frame) ? 1 : 0);
3314 mxf_primer_pack_add_mapping (primer, 0x1503, &t->ul);
3315 ret = g_list_prepend (ret, t);
3316
3317 return ret;
3318 }
3319
3320 static void
mxf_metadata_timecode_component_init(MXFMetadataTimecodeComponent * self)3321 mxf_metadata_timecode_component_init (MXFMetadataTimecodeComponent * self)
3322 {
3323
3324 }
3325
3326 static void
mxf_metadata_timecode_component_class_init(MXFMetadataTimecodeComponentClass * klass)3327 mxf_metadata_timecode_component_class_init (MXFMetadataTimecodeComponentClass *
3328 klass)
3329 {
3330 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
3331 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
3332
3333 metadata_base_class->handle_tag = mxf_metadata_timecode_component_handle_tag;
3334 metadata_base_class->name_quark = MXF_QUARK (TIMECODE_COMPONENT);
3335 metadata_base_class->to_structure =
3336 mxf_metadata_timecode_component_to_structure;
3337 metadata_base_class->write_tags = mxf_metadata_timecode_component_write_tags;
3338 metadata_class->type = 0x0114;
3339 }
3340
3341 G_DEFINE_TYPE (MXFMetadataSourceClip, mxf_metadata_source_clip,
3342 MXF_TYPE_METADATA_STRUCTURAL_COMPONENT);
3343
3344 static gboolean
mxf_metadata_source_clip_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)3345 mxf_metadata_source_clip_handle_tag (MXFMetadataBase * metadata,
3346 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
3347 guint tag_size)
3348 {
3349 MXFMetadataSourceClip *self = MXF_METADATA_SOURCE_CLIP (metadata);
3350 gboolean ret = TRUE;
3351 #ifndef GST_DISABLE_GST_DEBUG
3352 gchar str[96];
3353 #endif
3354
3355 switch (tag) {
3356 case 0x1201:
3357 if (tag_size != 8)
3358 goto error;
3359
3360 self->start_position = GST_READ_UINT64_BE (tag_data);
3361 GST_DEBUG (" start position = %" G_GINT64_FORMAT, self->start_position);
3362 break;
3363 case 0x1101:
3364 if (tag_size != 32)
3365 goto error;
3366
3367 memcpy (&self->source_package_id, tag_data, 32);
3368 GST_DEBUG (" source package id = %s",
3369 mxf_umid_to_string (&self->source_package_id, str));
3370 break;
3371 case 0x1102:
3372 if (tag_size != 4)
3373 goto error;
3374
3375 self->source_track_id = GST_READ_UINT32_BE (tag_data);
3376 GST_DEBUG (" source track id = %u", self->source_track_id);
3377 break;
3378 default:
3379 ret =
3380 MXF_METADATA_BASE_CLASS
3381 (mxf_metadata_source_clip_parent_class)->handle_tag (metadata, primer,
3382 tag, tag_data, tag_size);
3383 break;
3384 }
3385
3386 return ret;
3387
3388 error:
3389
3390 GST_ERROR ("Invalid source clip local tag 0x%04x of size %u", tag, tag_size);
3391
3392 return FALSE;
3393 }
3394
3395 static gboolean
mxf_metadata_source_clip_resolve(MXFMetadataBase * m,GHashTable * metadata)3396 mxf_metadata_source_clip_resolve (MXFMetadataBase * m, GHashTable * metadata)
3397 {
3398 MXFMetadataSourceClip *self = MXF_METADATA_SOURCE_CLIP (m);
3399 MXFMetadataBase *current = NULL;
3400 GHashTableIter iter;
3401 #ifndef GST_DISABLE_GST_DEBUG
3402 gchar str[96];
3403 #endif
3404
3405 if (mxf_umid_is_zero (&self->source_package_id)) {
3406 /* S377-1:2019 B.10 Source Clip.
3407 *
3408 * SourcePackageID: The value shall be 32 zero valued bytes to terminate the
3409 * source reference chain. */
3410 GST_LOG ("Skipping termination source package for source clip %s",
3411 mxf_uuid_to_string (&MXF_METADATA_BASE (self)->instance_uid, str));
3412 goto chain_up;
3413 }
3414
3415 g_hash_table_iter_init (&iter, metadata);
3416
3417 while (g_hash_table_iter_next (&iter, NULL, (gpointer) & current)) {
3418 if (MXF_IS_METADATA_SOURCE_PACKAGE (current)) {
3419 MXFMetadataGenericPackage *p = MXF_METADATA_GENERIC_PACKAGE (current);
3420
3421 if (mxf_umid_is_equal (&p->package_uid, &self->source_package_id)) {
3422 self->source_package = MXF_METADATA_SOURCE_PACKAGE (current);
3423 break;
3424 }
3425 }
3426 }
3427
3428 if (!self->source_package) {
3429 GST_ERROR ("Couldn't find source package %s",
3430 mxf_umid_to_string (&self->source_package_id, str));
3431 }
3432
3433 chain_up:
3434 return
3435 MXF_METADATA_BASE_CLASS (mxf_metadata_source_clip_parent_class)->resolve
3436 (m, metadata);
3437 }
3438
3439 static GstStructure *
mxf_metadata_source_clip_to_structure(MXFMetadataBase * m)3440 mxf_metadata_source_clip_to_structure (MXFMetadataBase * m)
3441 {
3442 GstStructure *ret =
3443 MXF_METADATA_BASE_CLASS
3444 (mxf_metadata_source_clip_parent_class)->to_structure (m);
3445 MXFMetadataSourceClip *self = MXF_METADATA_SOURCE_CLIP (m);
3446 gchar str[96];
3447
3448 mxf_umid_to_string (&self->source_package_id, str);
3449 gst_structure_id_set (ret, MXF_QUARK (START_POSITION), G_TYPE_INT64,
3450 self->start_position, MXF_QUARK (SOURCE_PACKAGE), G_TYPE_STRING, str,
3451 MXF_QUARK (SOURCE_TRACK_ID), G_TYPE_UINT, self->source_track_id, NULL);
3452
3453 return ret;
3454 }
3455
3456 static GList *
mxf_metadata_source_clip_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)3457 mxf_metadata_source_clip_write_tags (MXFMetadataBase * m,
3458 MXFPrimerPack * primer)
3459 {
3460 MXFMetadataSourceClip *self = MXF_METADATA_SOURCE_CLIP (m);
3461 GList *ret =
3462 MXF_METADATA_BASE_CLASS
3463 (mxf_metadata_source_clip_parent_class)->write_tags (m, primer);
3464 MXFLocalTag *t;
3465
3466 t = g_slice_new0 (MXFLocalTag);
3467 memcpy (&t->ul, MXF_UL (START_POSITION), 16);
3468 t->size = 8;
3469 t->data = g_slice_alloc (t->size);
3470 t->g_slice = TRUE;
3471 GST_WRITE_UINT64_BE (t->data, self->start_position);
3472 mxf_primer_pack_add_mapping (primer, 0x1201, &t->ul);
3473 ret = g_list_prepend (ret, t);
3474
3475 t = g_slice_new0 (MXFLocalTag);
3476 memcpy (&t->ul, MXF_UL (SOURCE_PACKAGE_ID), 16);
3477 t->size = 32;
3478 t->data = g_slice_alloc (t->size);
3479 t->g_slice = TRUE;
3480 memcpy (t->data, &self->source_package_id, 32);
3481 mxf_primer_pack_add_mapping (primer, 0x1101, &t->ul);
3482 ret = g_list_prepend (ret, t);
3483
3484 t = g_slice_new0 (MXFLocalTag);
3485 memcpy (&t->ul, MXF_UL (SOURCE_TRACK_ID), 16);
3486 t->size = 4;
3487 t->data = g_slice_alloc (t->size);
3488 t->g_slice = TRUE;
3489 GST_WRITE_UINT32_BE (t->data, self->source_track_id);
3490 mxf_primer_pack_add_mapping (primer, 0x1102, &t->ul);
3491 ret = g_list_prepend (ret, t);
3492
3493 return ret;
3494 }
3495
3496 static void
mxf_metadata_source_clip_init(MXFMetadataSourceClip * self)3497 mxf_metadata_source_clip_init (MXFMetadataSourceClip * self)
3498 {
3499
3500 }
3501
3502 static void
mxf_metadata_source_clip_class_init(MXFMetadataSourceClipClass * klass)3503 mxf_metadata_source_clip_class_init (MXFMetadataSourceClipClass * klass)
3504 {
3505 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
3506 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
3507
3508 metadata_base_class->handle_tag = mxf_metadata_source_clip_handle_tag;
3509 metadata_base_class->resolve = mxf_metadata_source_clip_resolve;
3510 metadata_base_class->name_quark = MXF_QUARK (SOURCE_CLIP);
3511 metadata_base_class->to_structure = mxf_metadata_source_clip_to_structure;
3512 metadata_base_class->write_tags = mxf_metadata_source_clip_write_tags;
3513 metadata_class->type = 0x0111;
3514 }
3515
3516
3517 G_DEFINE_TYPE (MXFMetadataFiller, mxf_metadata_filler,
3518 MXF_TYPE_METADATA_STRUCTURAL_COMPONENT);
3519
3520 static void
mxf_metadata_filler_init(MXFMetadataFiller * self)3521 mxf_metadata_filler_init (MXFMetadataFiller * self)
3522 {
3523
3524 }
3525
3526 static void
mxf_metadata_filler_class_init(MXFMetadataFillerClass * klass)3527 mxf_metadata_filler_class_init (MXFMetadataFillerClass * klass)
3528 {
3529 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
3530 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
3531
3532 metadata_base_class->name_quark = MXF_QUARK (FILLER);
3533 metadata_class->type = 0x0109;
3534 }
3535
3536 G_DEFINE_TYPE (MXFMetadataDMSourceClip, mxf_metadata_dm_source_clip,
3537 MXF_TYPE_METADATA_SOURCE_CLIP);
3538
3539 static void
mxf_metadata_dm_source_clip_finalize(GObject * object)3540 mxf_metadata_dm_source_clip_finalize (GObject * object)
3541 {
3542 MXFMetadataDMSourceClip *self = MXF_METADATA_DM_SOURCE_CLIP (object);
3543
3544 g_free (self->track_ids);
3545 self->track_ids = NULL;
3546
3547 G_OBJECT_CLASS (mxf_metadata_dm_source_clip_parent_class)->finalize (object);
3548 }
3549
3550 static gboolean
mxf_metadata_dm_source_clip_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)3551 mxf_metadata_dm_source_clip_handle_tag (MXFMetadataBase * metadata,
3552 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
3553 guint tag_size)
3554 {
3555 MXFMetadataDMSourceClip *self = MXF_METADATA_DM_SOURCE_CLIP (metadata);
3556 gboolean ret = TRUE;
3557
3558 switch (tag) {
3559 case 0x6103:
3560 {
3561 guint32 len;
3562 guint i;
3563
3564 if (tag_size < 8)
3565 goto error;
3566
3567 len = GST_READ_UINT32_BE (tag_data);
3568 GST_DEBUG (" number of track ids = %u", len);
3569 if (len == 0)
3570 return TRUE;
3571
3572 if (GST_READ_UINT32_BE (tag_data + 4) != 4)
3573 goto error;
3574
3575 tag_data += 8;
3576 tag_size -= 8;
3577
3578 if (tag_size / 4 < len)
3579 goto error;
3580
3581 self->n_track_ids = len;
3582 self->track_ids = g_new0 (guint32, len);
3583
3584 for (i = 0; i < len; i++) {
3585 self->track_ids[i] = GST_READ_UINT32_BE (tag_data);
3586 GST_DEBUG (" track id %u = %u", i, self->track_ids[i]);
3587 tag_data += 4;
3588 tag_size -= 4;
3589 }
3590 break;
3591 }
3592 default:
3593 ret =
3594 MXF_METADATA_BASE_CLASS
3595 (mxf_metadata_dm_source_clip_parent_class)->handle_tag (metadata,
3596 primer, tag, tag_data, tag_size);
3597 break;
3598 }
3599
3600 return ret;
3601
3602 error:
3603
3604 GST_ERROR ("Invalid DM source clip local tag 0x%04x of size %u", tag,
3605 tag_size);
3606
3607 return FALSE;
3608 }
3609
3610 static GstStructure *
mxf_metadata_dm_source_clip_to_structure(MXFMetadataBase * m)3611 mxf_metadata_dm_source_clip_to_structure (MXFMetadataBase * m)
3612 {
3613 GstStructure *ret =
3614 MXF_METADATA_BASE_CLASS
3615 (mxf_metadata_dm_source_clip_parent_class)->to_structure (m);
3616 MXFMetadataDMSourceClip *self = MXF_METADATA_DM_SOURCE_CLIP (m);
3617 guint i;
3618
3619 if (self->n_track_ids > 0) {
3620 GValue arr = { 0, }
3621 , val = {
3622 0,};
3623
3624 g_value_init (&arr, GST_TYPE_ARRAY);
3625
3626 for (i = 0; i < self->n_track_ids; i++) {
3627 g_value_init (&val, G_TYPE_UINT);
3628
3629 g_value_set_uint (&val, self->track_ids[i]);
3630 gst_value_array_append_value (&arr, &val);
3631 g_value_unset (&val);
3632 }
3633
3634 if (gst_value_array_get_size (&arr) > 0)
3635 gst_structure_id_set_value (ret, MXF_QUARK (TRACK_IDS), &arr);
3636
3637 g_value_unset (&arr);
3638 }
3639
3640 return ret;
3641 }
3642
3643 static GList *
mxf_metadata_dm_source_clip_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)3644 mxf_metadata_dm_source_clip_write_tags (MXFMetadataBase * m,
3645 MXFPrimerPack * primer)
3646 {
3647 MXFMetadataDMSourceClip *self = MXF_METADATA_DM_SOURCE_CLIP (m);
3648 GList *ret =
3649 MXF_METADATA_BASE_CLASS
3650 (mxf_metadata_dm_source_clip_parent_class)->write_tags (m, primer);
3651 MXFLocalTag *t;
3652
3653 if (self->track_ids) {
3654 guint i;
3655
3656 t = g_slice_new0 (MXFLocalTag);
3657 memcpy (&t->ul, MXF_UL (DM_SOURCECLIP_TRACK_IDS), 16);
3658 t->size = 8 + 4 * self->n_track_ids;
3659 t->data = g_slice_alloc (t->size);
3660 t->g_slice = TRUE;
3661 GST_WRITE_UINT32_BE (t->data, self->n_track_ids);
3662 GST_WRITE_UINT32_BE (t->data + 4, 4);
3663 for (i = 0; i < self->n_track_ids; i++)
3664 GST_WRITE_UINT32_BE (t->data + 8 + i * 4, self->track_ids[i]);
3665 mxf_primer_pack_add_mapping (primer, 0x6103, &t->ul);
3666 ret = g_list_prepend (ret, t);
3667 }
3668
3669 return ret;
3670 }
3671
3672 static void
mxf_metadata_dm_source_clip_init(MXFMetadataDMSourceClip * self)3673 mxf_metadata_dm_source_clip_init (MXFMetadataDMSourceClip * self)
3674 {
3675
3676 }
3677
3678 static void
mxf_metadata_dm_source_clip_class_init(MXFMetadataDMSourceClipClass * klass)3679 mxf_metadata_dm_source_clip_class_init (MXFMetadataDMSourceClipClass * klass)
3680 {
3681 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
3682 GObjectClass *object_class = (GObjectClass *) klass;
3683 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
3684
3685 object_class->finalize = mxf_metadata_dm_source_clip_finalize;
3686 metadata_base_class->handle_tag = mxf_metadata_dm_source_clip_handle_tag;
3687 metadata_base_class->name_quark = MXF_QUARK (DM_SOURCE_CLIP);
3688 metadata_base_class->to_structure = mxf_metadata_dm_source_clip_to_structure;
3689 metadata_base_class->write_tags = mxf_metadata_dm_source_clip_write_tags;
3690 metadata_class->type = 0x0145;
3691 }
3692
3693 G_DEFINE_TYPE (MXFMetadataDMSegment, mxf_metadata_dm_segment,
3694 MXF_TYPE_METADATA_STRUCTURAL_COMPONENT);
3695
3696 static void
mxf_metadata_dm_segment_finalize(GObject * object)3697 mxf_metadata_dm_segment_finalize (GObject * object)
3698 {
3699 MXFMetadataDMSegment *self = MXF_METADATA_DM_SEGMENT (object);
3700
3701 g_free (self->track_ids);
3702 self->track_ids = NULL;
3703
3704 g_free (self->event_comment);
3705 self->event_comment = NULL;
3706
3707 G_OBJECT_CLASS (mxf_metadata_dm_segment_parent_class)->finalize (object);
3708 }
3709
3710 static gboolean
mxf_metadata_dm_segment_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)3711 mxf_metadata_dm_segment_handle_tag (MXFMetadataBase * metadata,
3712 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
3713 guint tag_size)
3714 {
3715 MXFMetadataDMSegment *self = MXF_METADATA_DM_SEGMENT (metadata);
3716 gboolean ret = TRUE;
3717 #ifndef GST_DISABLE_GST_DEBUG
3718 gchar str[48];
3719 #endif
3720
3721 switch (tag) {
3722 case 0x0601:
3723 if (tag_size != 8)
3724 goto error;
3725 self->event_start_position = GST_READ_UINT64_BE (tag_data);
3726 GST_DEBUG (" event start position = %" G_GINT64_FORMAT,
3727 self->event_start_position);
3728 break;
3729 case 0x0602:
3730 self->event_comment = mxf_utf16_to_utf8 (tag_data, tag_size);
3731 GST_DEBUG (" event comment = %s", GST_STR_NULL (self->event_comment));
3732 break;
3733 case 0x6102:
3734 {
3735 guint32 len;
3736 guint i;
3737
3738 if (tag_size < 8)
3739 goto error;
3740 len = GST_READ_UINT32_BE (tag_data);
3741 GST_DEBUG (" number of track ids = %u", len);
3742 if (len == 0)
3743 return TRUE;
3744
3745 if (GST_READ_UINT32_BE (tag_data + 4) != 4)
3746 goto error;
3747
3748 tag_data += 8;
3749 tag_size -= 8;
3750
3751 if (len < tag_size / 4)
3752 goto error;
3753
3754 self->n_track_ids = len;
3755 self->track_ids = g_new0 (guint32, len);
3756
3757 tag_data += 8;
3758 tag_size -= 8;
3759
3760 for (i = 0; i < len; i++) {
3761 self->track_ids[i] = GST_READ_UINT32_BE (tag_data);
3762 GST_DEBUG (" track id %u = %u", i, self->track_ids[i]);
3763 tag_data += 4;
3764 tag_size -= 4;
3765 }
3766 break;
3767 }
3768 case 0x6101:
3769 if (tag_size != 16)
3770 goto error;
3771
3772 memcpy (&self->dm_framework_uid, tag_data, 16);
3773 GST_DEBUG (" DM framework = %s",
3774 mxf_uuid_to_string (&self->dm_framework_uid, str));
3775 break;
3776 default:
3777 ret =
3778 MXF_METADATA_BASE_CLASS
3779 (mxf_metadata_dm_segment_parent_class)->handle_tag (metadata, primer,
3780 tag, tag_data, tag_size);
3781 break;
3782 }
3783
3784 return ret;
3785
3786 error:
3787
3788 GST_ERROR ("Invalid DM segment local tag 0x%04x of size %u", tag, tag_size);
3789
3790 return FALSE;
3791 }
3792
3793 static gboolean
mxf_metadata_dm_segment_resolve(MXFMetadataBase * m,GHashTable * metadata)3794 mxf_metadata_dm_segment_resolve (MXFMetadataBase * m, GHashTable * metadata)
3795 {
3796 MXFMetadataDMSegment *self = MXF_METADATA_DM_SEGMENT (m);
3797 MXFMetadataBase *current = NULL;
3798 #ifndef GST_DISABLE_GST_DEBUG
3799 gchar str[48];
3800 #endif
3801
3802 current = g_hash_table_lookup (metadata, &self->dm_framework_uid);
3803 if (current && MXF_IS_DESCRIPTIVE_METADATA_FRAMEWORK (current)) {
3804 if (mxf_metadata_base_resolve (current, metadata)) {
3805 self->dm_framework = MXF_DESCRIPTIVE_METADATA_FRAMEWORK (current);
3806 } else {
3807 GST_ERROR ("Couldn't resolve DM framework %s",
3808 mxf_uuid_to_string (&self->dm_framework_uid, str));
3809 return FALSE;
3810 }
3811 } else {
3812 GST_ERROR ("Couldn't find DM framework %s",
3813 mxf_uuid_to_string (&self->dm_framework_uid, str));
3814 return FALSE;
3815 }
3816
3817
3818 return
3819 MXF_METADATA_BASE_CLASS (mxf_metadata_dm_segment_parent_class)->resolve
3820 (m, metadata);
3821 }
3822
3823 static GstStructure *
mxf_metadata_dm_segment_to_structure(MXFMetadataBase * m)3824 mxf_metadata_dm_segment_to_structure (MXFMetadataBase * m)
3825 {
3826 GstStructure *ret =
3827 MXF_METADATA_BASE_CLASS
3828 (mxf_metadata_dm_segment_parent_class)->to_structure (m);
3829 MXFMetadataDMSegment *self = MXF_METADATA_DM_SEGMENT (m);
3830 guint i;
3831
3832 gst_structure_id_set (ret, MXF_QUARK (EVENT_START_POSITION), G_TYPE_INT64,
3833 self->event_start_position, NULL);
3834
3835 if (self->event_comment)
3836 gst_structure_id_set (ret, MXF_QUARK (EVENT_COMMENT), G_TYPE_STRING,
3837 self->event_comment, NULL);
3838 /* FIXME: DMS1 doesn't support serializing to a structure yet */
3839 #if 0
3840 if (self->dm_framework) {
3841 GstStructure *s =
3842 mxf_metadata_base_to_structure (MXF_METADATA_BASE (self->dm_framework));
3843
3844 gst_structure_id_set (ret, MXF_QUARK (DM_FRAMEWORK), GST_TYPE_STRUCTURE,
3845 s, NULL);
3846 gst_structure_free (s);
3847 }
3848 #endif
3849
3850 if (self->n_track_ids > 0) {
3851 GValue arr = { 0, }
3852 , val = {
3853 0,};
3854
3855 g_value_init (&arr, GST_TYPE_ARRAY);
3856
3857 for (i = 0; i < self->n_track_ids; i++) {
3858 g_value_init (&val, G_TYPE_UINT);
3859
3860 g_value_set_uint (&val, self->track_ids[i]);
3861 gst_value_array_append_value (&arr, &val);
3862 g_value_unset (&val);
3863 }
3864
3865 if (gst_value_array_get_size (&arr) > 0)
3866 gst_structure_id_set_value (ret, MXF_QUARK (TRACK_IDS), &arr);
3867
3868 g_value_unset (&arr);
3869 }
3870
3871 return ret;
3872 }
3873
3874 static GList *
mxf_metadata_dm_segment_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)3875 mxf_metadata_dm_segment_write_tags (MXFMetadataBase * m, MXFPrimerPack * primer)
3876 {
3877 MXFMetadataDMSegment *self = MXF_METADATA_DM_SEGMENT (m);
3878 GList *ret =
3879 MXF_METADATA_BASE_CLASS (mxf_metadata_dm_segment_parent_class)->write_tags
3880 (m, primer);
3881 MXFLocalTag *t;
3882
3883 if (self->event_start_position != -1) {
3884 t = g_slice_new0 (MXFLocalTag);
3885 memcpy (&t->ul, MXF_UL (EVENT_START_POSITION), 16);
3886 t->size = 8;
3887 t->data = g_slice_alloc (t->size);
3888 t->g_slice = TRUE;
3889 GST_WRITE_UINT64_BE (t->data, self->event_start_position);
3890 mxf_primer_pack_add_mapping (primer, 0x0601, &t->ul);
3891 ret = g_list_prepend (ret, t);
3892 }
3893
3894 if (self->event_comment) {
3895 t = g_slice_new0 (MXFLocalTag);
3896 memcpy (&t->ul, MXF_UL (EVENT_COMMENT), 16);
3897 t->data = mxf_utf8_to_utf16 (self->event_comment, &t->size);
3898 mxf_primer_pack_add_mapping (primer, 0x0602, &t->ul);
3899 ret = g_list_prepend (ret, t);
3900 }
3901
3902 if (self->track_ids) {
3903 guint i;
3904
3905 t = g_slice_new0 (MXFLocalTag);
3906 memcpy (&t->ul, MXF_UL (DM_SEGMENT_TRACK_IDS), 16);
3907 t->size = 8 + 4 * self->n_track_ids;
3908 t->data = g_slice_alloc (t->size);
3909 t->g_slice = TRUE;
3910 GST_WRITE_UINT32_BE (t->data, self->n_track_ids);
3911 GST_WRITE_UINT32_BE (t->data + 4, 4);
3912 for (i = 0; i < self->n_track_ids; i++)
3913 GST_WRITE_UINT32_BE (t->data + 8 + i * 4, self->track_ids[i]);
3914 mxf_primer_pack_add_mapping (primer, 0x6102, &t->ul);
3915 ret = g_list_prepend (ret, t);
3916 }
3917
3918 if (self->dm_framework) {
3919 t = g_slice_new0 (MXFLocalTag);
3920 memcpy (&t->ul, MXF_UL (DM_FRAMEWORK), 16);
3921 t->size = 16;
3922 t->data = g_slice_alloc (t->size);
3923 t->g_slice = TRUE;
3924 memcpy (t->data, &MXF_METADATA_BASE (self->dm_framework)->instance_uid, 16);
3925 mxf_primer_pack_add_mapping (primer, 0x6101, &t->ul);
3926 ret = g_list_prepend (ret, t);
3927 }
3928
3929 return ret;
3930 }
3931
3932 static void
mxf_metadata_dm_segment_init(MXFMetadataDMSegment * self)3933 mxf_metadata_dm_segment_init (MXFMetadataDMSegment * self)
3934 {
3935 self->event_start_position = -1;
3936 }
3937
3938 static void
mxf_metadata_dm_segment_class_init(MXFMetadataDMSegmentClass * klass)3939 mxf_metadata_dm_segment_class_init (MXFMetadataDMSegmentClass * klass)
3940 {
3941 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
3942 GObjectClass *object_class = (GObjectClass *) klass;
3943 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
3944
3945 object_class->finalize = mxf_metadata_dm_segment_finalize;
3946 metadata_base_class->handle_tag = mxf_metadata_dm_segment_handle_tag;
3947 metadata_base_class->resolve = mxf_metadata_dm_segment_resolve;
3948 metadata_base_class->name_quark = MXF_QUARK (DM_SEGMENT);
3949 metadata_base_class->to_structure = mxf_metadata_dm_segment_to_structure;
3950 metadata_base_class->write_tags = mxf_metadata_dm_segment_write_tags;
3951 metadata_class->type = 0x0141;
3952 }
3953
3954 G_DEFINE_ABSTRACT_TYPE (MXFMetadataGenericDescriptor,
3955 mxf_metadata_generic_descriptor, MXF_TYPE_METADATA);
3956
3957 static void
mxf_metadata_generic_descriptor_finalize(GObject * object)3958 mxf_metadata_generic_descriptor_finalize (GObject * object)
3959 {
3960 MXFMetadataGenericDescriptor *self = MXF_METADATA_GENERIC_DESCRIPTOR (object);
3961
3962 g_free (self->locators_uids);
3963 self->locators_uids = NULL;
3964
3965 g_free (self->locators);
3966 self->locators = NULL;
3967
3968 G_OBJECT_CLASS (mxf_metadata_generic_descriptor_parent_class)->finalize
3969 (object);
3970 }
3971
3972 static gboolean
mxf_metadata_generic_descriptor_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)3973 mxf_metadata_generic_descriptor_handle_tag (MXFMetadataBase * metadata,
3974 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
3975 guint tag_size)
3976 {
3977 MXFMetadataGenericDescriptor *self =
3978 MXF_METADATA_GENERIC_DESCRIPTOR (metadata);
3979 gboolean ret = TRUE;
3980 #ifndef GST_DISABLE_GST_DEBUG
3981 gchar str[48];
3982 #endif
3983
3984 switch (tag) {
3985 case 0x2f01:
3986 if (!mxf_uuid_array_parse (&self->locators_uids, &self->n_locators,
3987 tag_data, tag_size))
3988 goto error;
3989
3990 GST_DEBUG (" number of locators = %u", self->n_locators);
3991 #ifndef GST_DISABLE_GST_DEBUG
3992 {
3993 guint i;
3994 for (i = 0; i < self->n_locators; i++) {
3995 GST_DEBUG (" locator %u = %s", i,
3996 mxf_uuid_to_string (&self->locators_uids[i], str));
3997 }
3998 }
3999 #endif
4000 break;
4001 default:
4002 ret =
4003 MXF_METADATA_BASE_CLASS
4004 (mxf_metadata_generic_descriptor_parent_class)->handle_tag (metadata,
4005 primer, tag, tag_data, tag_size);
4006 break;
4007 }
4008
4009 return ret;
4010
4011 error:
4012
4013 GST_ERROR ("Invalid generic descriptor local tag 0x%04x of size %u", tag,
4014 tag_size);
4015
4016 return FALSE;
4017 }
4018
4019 static gboolean
mxf_metadata_generic_descriptor_resolve(MXFMetadataBase * m,GHashTable * metadata)4020 mxf_metadata_generic_descriptor_resolve (MXFMetadataBase * m,
4021 GHashTable * metadata)
4022 {
4023 MXFMetadataGenericDescriptor *self = MXF_METADATA_GENERIC_DESCRIPTOR (m);
4024 MXFMetadataBase *current = NULL;
4025 guint i;
4026 gboolean have_locator = FALSE;
4027 #ifndef GST_DISABLE_GST_DEBUG
4028 gchar str[48];
4029 #endif
4030
4031 if (self->locators)
4032 memset (self->locators, 0, sizeof (gpointer) * self->n_locators);
4033 else
4034 self->locators = g_new0 (MXFMetadataLocator *, self->n_locators);
4035 for (i = 0; i < self->n_locators; i++) {
4036 current = g_hash_table_lookup (metadata, &self->locators_uids[i]);
4037 if (current && MXF_IS_METADATA_LOCATOR (current)) {
4038 if (mxf_metadata_base_resolve (current, metadata)) {
4039 self->locators[i] = MXF_METADATA_LOCATOR (current);
4040 have_locator = TRUE;
4041 } else {
4042 GST_ERROR ("Couldn't resolve locator %s",
4043 mxf_uuid_to_string (&self->locators_uids[i], str));
4044 }
4045 } else {
4046 GST_ERROR ("Locator %s not found",
4047 mxf_uuid_to_string (&self->locators_uids[i], str));
4048 }
4049 }
4050
4051 if (!have_locator && self->n_locators > 0) {
4052 GST_ERROR ("Couldn't resolve a locator");
4053 return FALSE;
4054 }
4055
4056 return
4057 MXF_METADATA_BASE_CLASS
4058 (mxf_metadata_generic_descriptor_parent_class)->resolve (m, metadata);
4059 }
4060
4061 static GstStructure *
mxf_metadata_generic_descriptor_to_structure(MXFMetadataBase * m)4062 mxf_metadata_generic_descriptor_to_structure (MXFMetadataBase * m)
4063 {
4064 GstStructure *ret =
4065 MXF_METADATA_BASE_CLASS
4066 (mxf_metadata_generic_descriptor_parent_class)->to_structure (m);
4067 MXFMetadataGenericDescriptor *self = MXF_METADATA_GENERIC_DESCRIPTOR (m);
4068 guint i;
4069
4070 if (self->n_locators > 0) {
4071 GValue arr = { 0, }
4072 , val = {
4073 0,};
4074
4075 g_value_init (&arr, GST_TYPE_ARRAY);
4076
4077 for (i = 0; i < self->n_locators; i++) {
4078 GstStructure *s;
4079
4080 if (self->locators[i] == NULL)
4081 continue;
4082
4083 g_value_init (&val, GST_TYPE_STRUCTURE);
4084
4085 s = mxf_metadata_base_to_structure (MXF_METADATA_BASE (self->locators
4086 [i]));
4087 gst_value_set_structure (&val, s);
4088 gst_structure_free (s);
4089 gst_value_array_append_value (&arr, &val);
4090 g_value_unset (&val);
4091 }
4092
4093 if (gst_value_array_get_size (&arr) > 0)
4094 gst_structure_id_set_value (ret, MXF_QUARK (LOCATORS), &arr);
4095
4096 g_value_unset (&arr);
4097 }
4098
4099 return ret;
4100 }
4101
4102 static GList *
mxf_metadata_generic_descriptor_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)4103 mxf_metadata_generic_descriptor_write_tags (MXFMetadataBase * m,
4104 MXFPrimerPack * primer)
4105 {
4106 MXFMetadataGenericDescriptor *self = MXF_METADATA_GENERIC_DESCRIPTOR (m);
4107 GList *ret =
4108 MXF_METADATA_BASE_CLASS
4109 (mxf_metadata_generic_descriptor_parent_class)->write_tags (m, primer);
4110 MXFLocalTag *t;
4111
4112 if (self->locators) {
4113 guint i;
4114
4115 t = g_slice_new0 (MXFLocalTag);
4116 memcpy (&t->ul, MXF_UL (LOCATORS), 16);
4117 t->size = 8 + 16 * self->n_locators;
4118 t->data = g_slice_alloc0 (t->size);
4119 t->g_slice = TRUE;
4120 GST_WRITE_UINT32_BE (t->data, self->n_locators);
4121 GST_WRITE_UINT32_BE (t->data + 4, 16);
4122 for (i = 0; i < self->n_locators; i++) {
4123 if (!self->locators[i])
4124 continue;
4125 memcpy (t->data + 8 + 16 * i,
4126 &MXF_METADATA_BASE (self->locators[i])->instance_uid, 16);
4127 }
4128 mxf_primer_pack_add_mapping (primer, 0x2f01, &t->ul);
4129 ret = g_list_prepend (ret, t);
4130 }
4131
4132 return ret;
4133 }
4134
4135 static void
mxf_metadata_generic_descriptor_init(MXFMetadataGenericDescriptor * self)4136 mxf_metadata_generic_descriptor_init (MXFMetadataGenericDescriptor * self)
4137 {
4138
4139 }
4140
4141 static void
mxf_metadata_generic_descriptor_class_init(MXFMetadataGenericDescriptorClass * klass)4142 mxf_metadata_generic_descriptor_class_init (MXFMetadataGenericDescriptorClass *
4143 klass)
4144 {
4145 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
4146 GObjectClass *object_class = (GObjectClass *) klass;
4147
4148 object_class->finalize = mxf_metadata_generic_descriptor_finalize;
4149 metadata_base_class->handle_tag = mxf_metadata_generic_descriptor_handle_tag;
4150 metadata_base_class->resolve = mxf_metadata_generic_descriptor_resolve;
4151 metadata_base_class->to_structure =
4152 mxf_metadata_generic_descriptor_to_structure;
4153 metadata_base_class->write_tags = mxf_metadata_generic_descriptor_write_tags;
4154 }
4155
4156 G_DEFINE_TYPE (MXFMetadataFileDescriptor, mxf_metadata_file_descriptor,
4157 MXF_TYPE_METADATA_GENERIC_DESCRIPTOR);
4158
4159 static gboolean
mxf_metadata_file_descriptor_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)4160 mxf_metadata_file_descriptor_handle_tag (MXFMetadataBase * metadata,
4161 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
4162 guint tag_size)
4163 {
4164 MXFMetadataFileDescriptor *self = MXF_METADATA_FILE_DESCRIPTOR (metadata);
4165 gboolean ret = TRUE;
4166 #ifndef GST_DISABLE_GST_DEBUG
4167 gchar str[48];
4168 #endif
4169
4170 switch (tag) {
4171 case 0x3006:
4172 if (tag_size != 4)
4173 goto error;
4174 self->linked_track_id = GST_READ_UINT32_BE (tag_data);
4175 GST_DEBUG (" linked track id = %u", self->linked_track_id);
4176 break;
4177 case 0x3001:
4178 if (!mxf_fraction_parse (&self->sample_rate, tag_data, tag_size))
4179 goto error;
4180 GST_DEBUG (" sample rate = %d/%d", self->sample_rate.n,
4181 self->sample_rate.d);
4182 break;
4183 case 0x3002:
4184 if (tag_size != 8)
4185 goto error;
4186 self->container_duration = GST_READ_UINT64_BE (tag_data);
4187 GST_DEBUG (" container duration = %" G_GINT64_FORMAT,
4188 self->container_duration);
4189 break;
4190 case 0x3004:
4191 if (tag_size != 16)
4192 goto error;
4193 memcpy (&self->essence_container, tag_data, 16);
4194 GST_DEBUG (" essence container = %s",
4195 mxf_ul_to_string (&self->essence_container, str));
4196 break;
4197 case 0x3005:
4198 if (tag_size != 16)
4199 goto error;
4200 memcpy (&self->codec, tag_data, 16);
4201 GST_DEBUG (" codec = %s", mxf_ul_to_string (&self->codec, str));
4202 break;
4203 default:
4204 ret =
4205 MXF_METADATA_BASE_CLASS
4206 (mxf_metadata_file_descriptor_parent_class)->handle_tag (metadata,
4207 primer, tag, tag_data, tag_size);
4208 break;
4209 }
4210
4211 return ret;
4212
4213 error:
4214
4215 GST_ERROR ("Invalid file descriptor local tag 0x%04x of size %u", tag,
4216 tag_size);
4217
4218 return FALSE;
4219 }
4220
4221 static GstStructure *
mxf_metadata_file_descriptor_to_structure(MXFMetadataBase * m)4222 mxf_metadata_file_descriptor_to_structure (MXFMetadataBase * m)
4223 {
4224 GstStructure *ret =
4225 MXF_METADATA_BASE_CLASS
4226 (mxf_metadata_file_descriptor_parent_class)->to_structure (m);
4227 MXFMetadataFileDescriptor *self = MXF_METADATA_FILE_DESCRIPTOR (m);
4228 gchar str[48];
4229
4230 if (self->linked_track_id)
4231 gst_structure_id_set (ret, MXF_QUARK (LINKED_TRACK_ID), G_TYPE_UINT,
4232 self->linked_track_id, NULL);
4233
4234 if (self->sample_rate.n && self->sample_rate.d)
4235 gst_structure_id_set (ret, MXF_QUARK (SAMPLE_RATE), GST_TYPE_FRACTION,
4236 self->sample_rate.n, self->sample_rate.d, NULL);
4237
4238 if (self->container_duration)
4239 gst_structure_id_set (ret, MXF_QUARK (CONTAINER_DURATION), G_TYPE_INT64,
4240 self->container_duration, NULL);
4241
4242 mxf_ul_to_string (&self->essence_container, str);
4243 gst_structure_id_set (ret, MXF_QUARK (ESSENCE_CONTAINER), G_TYPE_STRING, str,
4244 NULL);
4245
4246 if (!mxf_ul_is_zero (&self->codec)) {
4247 mxf_ul_to_string (&self->codec, str);
4248 gst_structure_id_set (ret, MXF_QUARK (CODEC), G_TYPE_STRING, str, NULL);
4249 }
4250
4251 return ret;
4252 }
4253
4254 static GList *
mxf_metadata_file_descriptor_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)4255 mxf_metadata_file_descriptor_write_tags (MXFMetadataBase * m,
4256 MXFPrimerPack * primer)
4257 {
4258 MXFMetadataFileDescriptor *self = MXF_METADATA_FILE_DESCRIPTOR (m);
4259 GList *ret =
4260 MXF_METADATA_BASE_CLASS
4261 (mxf_metadata_file_descriptor_parent_class)->write_tags (m, primer);
4262 MXFLocalTag *t;
4263
4264 if (self->linked_track_id) {
4265 t = g_slice_new0 (MXFLocalTag);
4266 memcpy (&t->ul, MXF_UL (LINKED_TRACK_ID), 16);
4267 t->size = 4;
4268 t->data = g_slice_alloc (t->size);
4269 t->g_slice = TRUE;
4270 GST_WRITE_UINT32_BE (t->data, self->linked_track_id);
4271 mxf_primer_pack_add_mapping (primer, 0x3006, &t->ul);
4272 ret = g_list_prepend (ret, t);
4273 }
4274
4275 t = g_slice_new0 (MXFLocalTag);
4276 memcpy (&t->ul, MXF_UL (SAMPLE_RATE), 16);
4277 t->size = 8;
4278 t->data = g_slice_alloc (t->size);
4279 t->g_slice = TRUE;
4280 GST_WRITE_UINT32_BE (t->data, self->sample_rate.n);
4281 GST_WRITE_UINT32_BE (t->data + 4, self->sample_rate.d);
4282 mxf_primer_pack_add_mapping (primer, 0x3001, &t->ul);
4283 ret = g_list_prepend (ret, t);
4284
4285 if (self->container_duration > 0) {
4286 t = g_slice_new0 (MXFLocalTag);
4287 memcpy (&t->ul, MXF_UL (CONTAINER_DURATION), 16);
4288 t->size = 8;
4289 t->data = g_slice_alloc (t->size);
4290 t->g_slice = TRUE;
4291 GST_WRITE_UINT64_BE (t->data, self->container_duration);
4292 mxf_primer_pack_add_mapping (primer, 0x3002, &t->ul);
4293 ret = g_list_prepend (ret, t);
4294 }
4295
4296 t = g_slice_new0 (MXFLocalTag);
4297 memcpy (&t->ul, MXF_UL (ESSENCE_CONTAINER), 16);
4298 t->size = 16;
4299 t->data = g_slice_alloc (t->size);
4300 t->g_slice = TRUE;
4301 memcpy (t->data, &self->essence_container, 16);
4302 mxf_primer_pack_add_mapping (primer, 0x3004, &t->ul);
4303 ret = g_list_prepend (ret, t);
4304
4305 if (!mxf_ul_is_zero (&self->codec)) {
4306 t = g_slice_new0 (MXFLocalTag);
4307 memcpy (&t->ul, MXF_UL (CODEC), 16);
4308 t->size = 16;
4309 t->data = g_slice_alloc (t->size);
4310 t->g_slice = TRUE;
4311 memcpy (t->data, &self->codec, 16);
4312 mxf_primer_pack_add_mapping (primer, 0x3005, &t->ul);
4313 ret = g_list_prepend (ret, t);
4314 }
4315
4316 return ret;
4317 }
4318
4319 static void
mxf_metadata_file_descriptor_init(MXFMetadataFileDescriptor * self)4320 mxf_metadata_file_descriptor_init (MXFMetadataFileDescriptor * self)
4321 {
4322
4323 }
4324
4325 static void
mxf_metadata_file_descriptor_class_init(MXFMetadataFileDescriptorClass * klass)4326 mxf_metadata_file_descriptor_class_init (MXFMetadataFileDescriptorClass * klass)
4327 {
4328 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
4329 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
4330
4331 metadata_base_class->handle_tag = mxf_metadata_file_descriptor_handle_tag;
4332 metadata_base_class->name_quark = MXF_QUARK (FILE_DESCRIPTOR);
4333 metadata_base_class->to_structure = mxf_metadata_file_descriptor_to_structure;
4334 metadata_base_class->write_tags = mxf_metadata_file_descriptor_write_tags;
4335 metadata_class->type = 0x0125;
4336 }
4337
4338 G_DEFINE_TYPE (MXFMetadataGenericPictureEssenceDescriptor,
4339 mxf_metadata_generic_picture_essence_descriptor,
4340 MXF_TYPE_METADATA_FILE_DESCRIPTOR);
4341
4342 static gboolean
mxf_metadata_generic_picture_essence_descriptor_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)4343 mxf_metadata_generic_picture_essence_descriptor_handle_tag (MXFMetadataBase *
4344 metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
4345 guint tag_size)
4346 {
4347 MXFMetadataGenericPictureEssenceDescriptor *self =
4348 MXF_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (metadata);
4349 gboolean ret = TRUE;
4350 #ifndef GST_DISABLE_GST_DEBUG
4351 gchar str[48];
4352 #endif
4353
4354 switch (tag) {
4355 case 0x3215:
4356 if (tag_size != 1)
4357 goto error;
4358 self->signal_standard = GST_READ_UINT8 (tag_data);
4359 GST_DEBUG (" signal standard = %u", self->signal_standard);
4360 break;
4361 case 0x320c:
4362 if (tag_size != 1)
4363 goto error;
4364 self->frame_layout = GST_READ_UINT8 (tag_data);
4365 GST_DEBUG (" frame layout = %u", self->frame_layout);
4366 break;
4367 case 0x3203:
4368 if (tag_size != 4)
4369 goto error;
4370 self->stored_width = GST_READ_UINT32_BE (tag_data);
4371 GST_DEBUG (" stored width = %u", self->stored_width);
4372 break;
4373 case 0x3202:
4374 if (tag_size != 4)
4375 goto error;
4376 self->stored_height = GST_READ_UINT32_BE (tag_data);
4377 GST_DEBUG (" stored height = %u", self->stored_height);
4378 break;
4379 case 0x3216:
4380 if (tag_size != 4)
4381 goto error;
4382 self->stored_f2_offset = GST_READ_UINT32_BE (tag_data);
4383 GST_DEBUG (" stored f2 offset = %d", self->stored_f2_offset);
4384 break;
4385 case 0x3205:
4386 if (tag_size != 4)
4387 goto error;
4388 self->sampled_width = GST_READ_UINT32_BE (tag_data);
4389 GST_DEBUG (" sampled width = %u", self->sampled_width);
4390 break;
4391 case 0x3204:
4392 if (tag_size != 4)
4393 goto error;
4394 self->sampled_height = GST_READ_UINT32_BE (tag_data);
4395 GST_DEBUG (" sampled height = %u", self->sampled_height);
4396 break;
4397 case 0x3206:
4398 if (tag_size != 4)
4399 goto error;
4400 self->sampled_x_offset = GST_READ_UINT32_BE (tag_data);
4401 GST_DEBUG (" sampled x offset = %d", self->sampled_x_offset);
4402 break;
4403 case 0x3207:
4404 if (tag_size != 4)
4405 goto error;
4406 self->sampled_y_offset = GST_READ_UINT32_BE (tag_data);
4407 GST_DEBUG (" sampled y offset = %d", self->sampled_y_offset);
4408 break;
4409 case 0x3208:
4410 if (tag_size != 4)
4411 goto error;
4412 self->display_height = GST_READ_UINT32_BE (tag_data);
4413 GST_DEBUG (" display height = %u", self->display_height);
4414 break;
4415 case 0x3209:
4416 if (tag_size != 4)
4417 goto error;
4418 self->display_width = GST_READ_UINT32_BE (tag_data);
4419 GST_DEBUG (" display width = %u", self->display_width);
4420 break;
4421 case 0x320a:
4422 if (tag_size != 4)
4423 goto error;
4424 self->display_x_offset = GST_READ_UINT32_BE (tag_data);
4425 GST_DEBUG (" display x offset = %d", self->display_x_offset);
4426 break;
4427 case 0x320b:
4428 if (tag_size != 4)
4429 goto error;
4430 self->display_y_offset = GST_READ_UINT32_BE (tag_data);
4431 GST_DEBUG (" display y offset = %d", self->display_y_offset);
4432 break;
4433 case 0x3217:
4434 if (tag_size != 4)
4435 goto error;
4436 self->display_f2_offset = GST_READ_UINT32_BE (tag_data);
4437 GST_DEBUG (" display f2 offset = %d", self->display_f2_offset);
4438 break;
4439 case 0x320e:
4440 if (!mxf_fraction_parse (&self->aspect_ratio, tag_data, tag_size))
4441 goto error;
4442 GST_DEBUG (" aspect ratio = %d/%d", self->aspect_ratio.n,
4443 self->aspect_ratio.d);
4444 break;
4445 case 0x3218:
4446 if (tag_size != 1)
4447 goto error;
4448 self->active_format_descriptor = GST_READ_UINT8 (tag_data);
4449 GST_DEBUG (" active format descriptor = %u",
4450 self->active_format_descriptor);
4451 break;
4452 case 0x320d:
4453 if (tag_size < 8)
4454 goto error;
4455
4456 if (GST_READ_UINT32_BE (tag_data) == 0)
4457 return TRUE;
4458
4459 if (GST_READ_UINT32_BE (tag_data + 4) != 4)
4460 goto error;
4461
4462 if (GST_READ_UINT32_BE (tag_data) != 1 &&
4463 GST_READ_UINT32_BE (tag_data) != 2)
4464 goto error;
4465
4466 if ((GST_READ_UINT32_BE (tag_data) == 1 && tag_size != 12) ||
4467 (GST_READ_UINT32_BE (tag_data) == 2 && tag_size != 16))
4468 goto error;
4469
4470 self->video_line_map[0] = GST_READ_UINT32_BE (tag_data + 8);
4471
4472 /* Workaround for files created by ffmpeg */
4473 if (GST_READ_UINT32_BE (tag_data) == 1)
4474 self->video_line_map[0] = 0;
4475 else
4476 self->video_line_map[1] = GST_READ_UINT32_BE (tag_data + 12);
4477
4478 GST_DEBUG (" video line map = {%i, %i}", self->video_line_map[0],
4479 self->video_line_map[1]);
4480 break;
4481 case 0x320f:
4482 if (tag_size != 1)
4483 goto error;
4484 self->alpha_transparency = GST_READ_UINT8 (tag_data);
4485 GST_DEBUG (" alpha transparency = %u", self->alpha_transparency);
4486 break;
4487 case 0x3210:
4488 if (tag_size != 16)
4489 goto error;
4490 memcpy (&self->capture_gamma, tag_data, 16);
4491 GST_DEBUG (" capture gamma = %s",
4492 mxf_ul_to_string (&self->capture_gamma, str));
4493 break;
4494 case 0x3211:
4495 if (tag_size != 4)
4496 goto error;
4497 self->image_alignment_offset = GST_READ_UINT32_BE (tag_data);
4498 GST_DEBUG (" image alignment offset = %u", self->image_alignment_offset);
4499 break;
4500 case 0x3213:
4501 if (tag_size != 4)
4502 goto error;
4503 self->image_start_offset = GST_READ_UINT32_BE (tag_data);
4504 GST_DEBUG (" image start offset = %u", self->image_start_offset);
4505 break;
4506 case 0x3214:
4507 if (tag_size != 4)
4508 goto error;
4509 self->image_end_offset = GST_READ_UINT32_BE (tag_data);
4510 GST_DEBUG (" image end offset = %u", self->image_end_offset);
4511 break;
4512 case 0x3212:
4513 if (tag_size != 1)
4514 goto error;
4515 self->field_dominance = GST_READ_UINT8 (tag_data);
4516 GST_DEBUG (" field dominance = %u", self->field_dominance);
4517 break;
4518 case 0x3201:
4519 if (tag_size != 16)
4520 goto error;
4521 memcpy (&self->picture_essence_coding, tag_data, 16);
4522 GST_DEBUG (" picture essence coding = %s",
4523 mxf_ul_to_string (&self->picture_essence_coding, str));
4524 break;
4525 default:
4526 ret =
4527 MXF_METADATA_BASE_CLASS
4528 (mxf_metadata_generic_picture_essence_descriptor_parent_class)->handle_tag
4529 (metadata, primer, tag, tag_data, tag_size);
4530 break;
4531 }
4532
4533 return ret;
4534
4535 error:
4536
4537 GST_ERROR
4538 ("Invalid generic picture essence descriptor local tag 0x%04x of size %u",
4539 tag, tag_size);
4540
4541 return FALSE;
4542 }
4543
4544 static GstStructure *
mxf_metadata_generic_picture_essence_descriptor_to_structure(MXFMetadataBase * m)4545 mxf_metadata_generic_picture_essence_descriptor_to_structure (MXFMetadataBase *
4546 m)
4547 {
4548 GstStructure *ret =
4549 MXF_METADATA_BASE_CLASS
4550 (mxf_metadata_generic_picture_essence_descriptor_parent_class)->to_structure
4551 (m);
4552 MXFMetadataGenericPictureEssenceDescriptor *self =
4553 MXF_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (m);
4554 gchar str[48];
4555
4556 gst_structure_id_set (ret, MXF_QUARK (SIGNAL_STANDARD), G_TYPE_UCHAR,
4557 self->signal_standard, NULL);
4558
4559 gst_structure_id_set (ret, MXF_QUARK (FRAME_LAYOUT), G_TYPE_UCHAR,
4560 self->frame_layout, NULL);
4561
4562 gst_structure_id_set (ret, MXF_QUARK (STORED_WIDTH), G_TYPE_UINT,
4563 self->stored_width, MXF_QUARK (STORED_HEIGHT), G_TYPE_UINT,
4564 self->stored_height, NULL);
4565
4566 if (self->stored_f2_offset != 0)
4567 gst_structure_id_set (ret, MXF_QUARK (STORED_F2_OFFSET), G_TYPE_INT,
4568 self->stored_f2_offset, NULL);
4569
4570 if (self->sampled_width != 0 && self->sampled_height != 0)
4571 gst_structure_id_set (ret, MXF_QUARK (SAMPLED_WIDTH), G_TYPE_UINT,
4572 self->sampled_width, MXF_QUARK (SAMPLED_HEIGHT), G_TYPE_UINT,
4573 self->sampled_height, NULL);
4574
4575 if (self->sampled_x_offset != 0)
4576 gst_structure_id_set (ret, MXF_QUARK (SAMPLED_X_OFFSET), G_TYPE_INT,
4577 self->sampled_x_offset, NULL);
4578
4579 if (self->sampled_y_offset != 0)
4580 gst_structure_id_set (ret, MXF_QUARK (SAMPLED_Y_OFFSET), G_TYPE_INT,
4581 self->sampled_y_offset, NULL);
4582
4583 if (self->display_width != 0 && self->display_height != 0)
4584 gst_structure_id_set (ret, MXF_QUARK (DISPLAY_WIDTH), G_TYPE_UINT,
4585 self->display_width, MXF_QUARK (DISPLAY_HEIGHT), G_TYPE_UINT,
4586 self->display_height, NULL);
4587
4588 if (self->display_x_offset != 0)
4589 gst_structure_id_set (ret, MXF_QUARK (DISPLAY_X_OFFSET), G_TYPE_INT,
4590 self->display_x_offset, NULL);
4591
4592 if (self->display_y_offset != 0)
4593 gst_structure_id_set (ret, MXF_QUARK (DISPLAY_Y_OFFSET), G_TYPE_INT,
4594 self->display_y_offset, NULL);
4595
4596 if (self->display_f2_offset != 0)
4597 gst_structure_id_set (ret, MXF_QUARK (DISPLAY_F2_OFFSET), G_TYPE_INT,
4598 self->display_f2_offset, NULL);
4599
4600 if (self->aspect_ratio.n != 0 && self->aspect_ratio.d != 0)
4601 gst_structure_id_set (ret, MXF_QUARK (ASPECT_RATIO), GST_TYPE_FRACTION,
4602 self->aspect_ratio.n, self->aspect_ratio.d, NULL);
4603
4604 if (self->active_format_descriptor)
4605 gst_structure_id_set (ret, MXF_QUARK (ACTIVE_FORMAT_DESCRIPTOR),
4606 G_TYPE_UCHAR, self->active_format_descriptor, NULL);
4607
4608 gst_structure_id_set (ret, MXF_QUARK (VIDEO_LINE_MAP_0), G_TYPE_UINT,
4609 self->video_line_map[0], MXF_QUARK (VIDEO_LINE_MAP_1), G_TYPE_UINT,
4610 self->video_line_map[1], NULL);
4611
4612 if (self->alpha_transparency != 0)
4613 gst_structure_id_set (ret, MXF_QUARK (ALPHA_TRANSPARENCY), G_TYPE_UCHAR,
4614 self->alpha_transparency, NULL);
4615
4616 if (!mxf_ul_is_zero (&self->capture_gamma)) {
4617 mxf_ul_to_string (&self->capture_gamma, str);
4618 gst_structure_id_set (ret, MXF_QUARK (CAPTURE_GAMMA), G_TYPE_STRING, str,
4619 NULL);
4620 }
4621
4622 if (self->image_alignment_offset != 0)
4623 gst_structure_id_set (ret, MXF_QUARK (IMAGE_ALIGNMENT_OFFSET), G_TYPE_UINT,
4624 self->image_alignment_offset, NULL);
4625
4626 if (self->image_start_offset != 0)
4627 gst_structure_id_set (ret, MXF_QUARK (IMAGE_START_OFFSET), G_TYPE_UINT,
4628 self->image_start_offset, NULL);
4629
4630 if (self->image_end_offset != 0)
4631 gst_structure_id_set (ret, MXF_QUARK (IMAGE_END_OFFSET), G_TYPE_UINT,
4632 self->image_end_offset, NULL);
4633
4634 if (self->field_dominance != 0)
4635 gst_structure_id_set (ret, MXF_QUARK (FIELD_DOMINANCE), G_TYPE_UCHAR,
4636 self->field_dominance, NULL);
4637
4638 if (!mxf_ul_is_zero (&self->picture_essence_coding)) {
4639 mxf_ul_to_string (&self->picture_essence_coding, str);
4640 gst_structure_id_set (ret, MXF_QUARK (PICTURE_ESSENCE_CODING),
4641 G_TYPE_STRING, str, NULL);
4642 }
4643
4644 return ret;
4645 }
4646
4647 static GList *
mxf_metadata_generic_picture_essence_descriptor_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)4648 mxf_metadata_generic_picture_essence_descriptor_write_tags (MXFMetadataBase * m,
4649 MXFPrimerPack * primer)
4650 {
4651 MXFMetadataGenericPictureEssenceDescriptor *self =
4652 MXF_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (m);
4653 GList *ret =
4654 MXF_METADATA_BASE_CLASS
4655 (mxf_metadata_generic_picture_essence_descriptor_parent_class)->write_tags
4656 (m, primer);
4657 MXFLocalTag *t;
4658
4659 if (self->signal_standard != 1) {
4660 t = g_slice_new0 (MXFLocalTag);
4661 memcpy (&t->ul, MXF_UL (SIGNAL_STANDARD), 16);
4662 t->size = 1;
4663 t->data = g_slice_alloc (t->size);
4664 t->g_slice = TRUE;
4665 GST_WRITE_UINT8 (t->data, self->signal_standard);
4666 mxf_primer_pack_add_mapping (primer, 0x3215, &t->ul);
4667 ret = g_list_prepend (ret, t);
4668 }
4669
4670 t = g_slice_new0 (MXFLocalTag);
4671 memcpy (&t->ul, MXF_UL (FRAME_LAYOUT), 16);
4672 t->size = 1;
4673 t->data = g_slice_alloc (t->size);
4674 t->g_slice = TRUE;
4675 GST_WRITE_UINT8 (t->data, self->frame_layout);
4676 mxf_primer_pack_add_mapping (primer, 0x320c, &t->ul);
4677 ret = g_list_prepend (ret, t);
4678
4679 t = g_slice_new0 (MXFLocalTag);
4680 memcpy (&t->ul, MXF_UL (STORED_WIDTH), 16);
4681 t->size = 4;
4682 t->data = g_slice_alloc (t->size);
4683 t->g_slice = TRUE;
4684 GST_WRITE_UINT32_BE (t->data, self->stored_width);
4685 mxf_primer_pack_add_mapping (primer, 0x3203, &t->ul);
4686 ret = g_list_prepend (ret, t);
4687
4688 t = g_slice_new0 (MXFLocalTag);
4689 memcpy (&t->ul, MXF_UL (STORED_HEIGHT), 16);
4690 t->size = 4;
4691 t->data = g_slice_alloc (t->size);
4692 t->g_slice = TRUE;
4693 GST_WRITE_UINT32_BE (t->data, self->stored_height);
4694 mxf_primer_pack_add_mapping (primer, 0x3202, &t->ul);
4695 ret = g_list_prepend (ret, t);
4696
4697 if (self->stored_f2_offset != 0) {
4698 t = g_slice_new0 (MXFLocalTag);
4699 memcpy (&t->ul, MXF_UL (STORED_F2_OFFSET), 16);
4700 t->size = 4;
4701 t->data = g_slice_alloc (t->size);
4702 t->g_slice = TRUE;
4703 GST_WRITE_UINT32_BE (t->data, self->stored_f2_offset);
4704 mxf_primer_pack_add_mapping (primer, 0x3216, &t->ul);
4705 ret = g_list_prepend (ret, t);
4706 }
4707
4708 if (self->sampled_width != 0) {
4709 t = g_slice_new0 (MXFLocalTag);
4710 memcpy (&t->ul, MXF_UL (SAMPLED_WIDTH), 16);
4711 t->size = 4;
4712 t->data = g_slice_alloc (t->size);
4713 t->g_slice = TRUE;
4714 GST_WRITE_UINT32_BE (t->data, self->sampled_width);
4715 mxf_primer_pack_add_mapping (primer, 0x3205, &t->ul);
4716 ret = g_list_prepend (ret, t);
4717 }
4718
4719 if (self->sampled_height != 0) {
4720 t = g_slice_new0 (MXFLocalTag);
4721 memcpy (&t->ul, MXF_UL (SAMPLED_HEIGHT), 16);
4722 t->size = 4;
4723 t->data = g_slice_alloc (t->size);
4724 t->g_slice = TRUE;
4725 GST_WRITE_UINT32_BE (t->data, self->sampled_height);
4726 mxf_primer_pack_add_mapping (primer, 0x3204, &t->ul);
4727 ret = g_list_prepend (ret, t);
4728 }
4729
4730 if (self->sampled_x_offset != 0) {
4731 t = g_slice_new0 (MXFLocalTag);
4732 memcpy (&t->ul, MXF_UL (SAMPLED_X_OFFSET), 16);
4733 t->size = 4;
4734 t->data = g_slice_alloc (t->size);
4735 t->g_slice = TRUE;
4736 GST_WRITE_UINT32_BE (t->data, self->sampled_x_offset);
4737 mxf_primer_pack_add_mapping (primer, 0x3206, &t->ul);
4738 ret = g_list_prepend (ret, t);
4739 }
4740
4741 if (self->sampled_y_offset != 0) {
4742 t = g_slice_new0 (MXFLocalTag);
4743 memcpy (&t->ul, MXF_UL (SAMPLED_Y_OFFSET), 16);
4744 t->size = 4;
4745 t->data = g_slice_alloc (t->size);
4746 t->g_slice = TRUE;
4747 GST_WRITE_UINT32_BE (t->data, self->sampled_y_offset);
4748 mxf_primer_pack_add_mapping (primer, 0x3207, &t->ul);
4749 ret = g_list_prepend (ret, t);
4750 }
4751
4752 if (self->display_height != 0) {
4753 t = g_slice_new0 (MXFLocalTag);
4754 memcpy (&t->ul, MXF_UL (DISPLAY_HEIGHT), 16);
4755 t->size = 4;
4756 t->data = g_slice_alloc (t->size);
4757 t->g_slice = TRUE;
4758 GST_WRITE_UINT32_BE (t->data, self->display_height);
4759 mxf_primer_pack_add_mapping (primer, 0x3208, &t->ul);
4760 ret = g_list_prepend (ret, t);
4761 }
4762
4763 if (self->display_width != 0) {
4764 t = g_slice_new0 (MXFLocalTag);
4765 memcpy (&t->ul, MXF_UL (DISPLAY_WIDTH), 16);
4766 t->size = 4;
4767 t->data = g_slice_alloc (t->size);
4768 t->g_slice = TRUE;
4769 GST_WRITE_UINT32_BE (t->data, self->display_width);
4770 mxf_primer_pack_add_mapping (primer, 0x3209, &t->ul);
4771 ret = g_list_prepend (ret, t);
4772 }
4773
4774 if (self->display_x_offset != 0) {
4775 t = g_slice_new0 (MXFLocalTag);
4776 memcpy (&t->ul, MXF_UL (DISPLAY_X_OFFSET), 16);
4777 t->size = 4;
4778 t->data = g_slice_alloc (t->size);
4779 t->g_slice = TRUE;
4780 GST_WRITE_UINT32_BE (t->data, self->display_x_offset);
4781 mxf_primer_pack_add_mapping (primer, 0x320a, &t->ul);
4782 ret = g_list_prepend (ret, t);
4783 }
4784
4785 if (self->display_y_offset != 0) {
4786 t = g_slice_new0 (MXFLocalTag);
4787 memcpy (&t->ul, MXF_UL (DISPLAY_Y_OFFSET), 16);
4788 t->size = 4;
4789 t->data = g_slice_alloc (t->size);
4790 t->g_slice = TRUE;
4791 GST_WRITE_UINT32_BE (t->data, self->display_y_offset);
4792 mxf_primer_pack_add_mapping (primer, 0x320b, &t->ul);
4793 ret = g_list_prepend (ret, t);
4794 }
4795
4796 if (self->display_f2_offset != 0) {
4797 t = g_slice_new0 (MXFLocalTag);
4798 memcpy (&t->ul, MXF_UL (DISPLAY_F2_OFFSET), 16);
4799 t->size = 4;
4800 t->data = g_slice_alloc (t->size);
4801 t->g_slice = TRUE;
4802 GST_WRITE_UINT32_BE (t->data, self->display_f2_offset);
4803 mxf_primer_pack_add_mapping (primer, 0x3217, &t->ul);
4804 ret = g_list_prepend (ret, t);
4805 }
4806
4807 t = g_slice_new0 (MXFLocalTag);
4808 memcpy (&t->ul, MXF_UL (ASPECT_RATIO), 16);
4809 t->size = 8;
4810 t->data = g_slice_alloc (t->size);
4811 t->g_slice = TRUE;
4812 GST_WRITE_UINT32_BE (t->data, self->aspect_ratio.n);
4813 GST_WRITE_UINT32_BE (t->data + 4, self->aspect_ratio.d);
4814 mxf_primer_pack_add_mapping (primer, 0x320e, &t->ul);
4815 ret = g_list_prepend (ret, t);
4816
4817 if (self->active_format_descriptor != 0) {
4818 t = g_slice_new0 (MXFLocalTag);
4819 memcpy (&t->ul, MXF_UL (ACTIVE_FORMAT_DESCRIPTOR), 16);
4820 t->size = 1;
4821 t->data = g_slice_alloc (t->size);
4822 t->g_slice = TRUE;
4823 GST_WRITE_UINT8 (t->data, self->active_format_descriptor);
4824 mxf_primer_pack_add_mapping (primer, 0x3218, &t->ul);
4825 ret = g_list_prepend (ret, t);
4826 }
4827
4828 t = g_slice_new0 (MXFLocalTag);
4829 memcpy (&t->ul, MXF_UL (VIDEO_LINE_MAP), 16);
4830 t->size = 16;
4831 t->data = g_slice_alloc (t->size);
4832 t->g_slice = TRUE;
4833 GST_WRITE_UINT32_BE (t->data, 2);
4834 GST_WRITE_UINT32_BE (t->data + 4, 4);
4835 GST_WRITE_UINT32_BE (t->data + 8, self->video_line_map[0]);
4836 GST_WRITE_UINT32_BE (t->data + 12, self->video_line_map[1]);
4837 mxf_primer_pack_add_mapping (primer, 0x320d, &t->ul);
4838 ret = g_list_prepend (ret, t);
4839
4840 if (self->alpha_transparency != 0) {
4841 t = g_slice_new0 (MXFLocalTag);
4842 memcpy (&t->ul, MXF_UL (ALPHA_TRANSPARENCY), 16);
4843 t->size = 1;
4844 t->data = g_slice_alloc (t->size);
4845 t->g_slice = TRUE;
4846 GST_WRITE_UINT8 (t->data, self->alpha_transparency);
4847 mxf_primer_pack_add_mapping (primer, 0x320f, &t->ul);
4848 ret = g_list_prepend (ret, t);
4849 }
4850
4851 if (!mxf_ul_is_zero (&self->capture_gamma)) {
4852 t = g_slice_new0 (MXFLocalTag);
4853 memcpy (&t->ul, MXF_UL (CAPTURE_GAMMA), 16);
4854 t->size = 16;
4855 t->data = g_slice_alloc (t->size);
4856 t->g_slice = TRUE;
4857 memcpy (t->data, &self->capture_gamma, 16);
4858 mxf_primer_pack_add_mapping (primer, 0x3210, &t->ul);
4859 ret = g_list_prepend (ret, t);
4860 }
4861
4862 if (self->image_alignment_offset != 0) {
4863 t = g_slice_new0 (MXFLocalTag);
4864 memcpy (&t->ul, MXF_UL (IMAGE_ALIGNMENT_OFFSET), 16);
4865 t->size = 4;
4866 t->data = g_slice_alloc (t->size);
4867 t->g_slice = TRUE;
4868 GST_WRITE_UINT32_BE (t->data, self->image_alignment_offset);
4869 mxf_primer_pack_add_mapping (primer, 0x3211, &t->ul);
4870 ret = g_list_prepend (ret, t);
4871 }
4872
4873 if (self->image_start_offset != 0) {
4874 t = g_slice_new0 (MXFLocalTag);
4875 memcpy (&t->ul, MXF_UL (IMAGE_START_OFFSET), 16);
4876 t->size = 4;
4877 t->data = g_slice_alloc (t->size);
4878 t->g_slice = TRUE;
4879 GST_WRITE_UINT32_BE (t->data, self->image_start_offset);
4880 mxf_primer_pack_add_mapping (primer, 0x3213, &t->ul);
4881 ret = g_list_prepend (ret, t);
4882 }
4883
4884 if (self->image_end_offset != 0) {
4885 t = g_slice_new0 (MXFLocalTag);
4886 memcpy (&t->ul, MXF_UL (IMAGE_END_OFFSET), 16);
4887 t->size = 4;
4888 t->data = g_slice_alloc (t->size);
4889 t->g_slice = TRUE;
4890 GST_WRITE_UINT32_BE (t->data, self->image_end_offset);
4891 mxf_primer_pack_add_mapping (primer, 0x3214, &t->ul);
4892 ret = g_list_prepend (ret, t);
4893 }
4894
4895 if (self->field_dominance != 0) {
4896 t = g_slice_new0 (MXFLocalTag);
4897 memcpy (&t->ul, MXF_UL (FIELD_DOMINANCE), 16);
4898 t->size = 1;
4899 t->data = g_slice_alloc (t->size);
4900 t->g_slice = TRUE;
4901 GST_WRITE_UINT8 (t->data, self->field_dominance);
4902 mxf_primer_pack_add_mapping (primer, 0x3212, &t->ul);
4903 ret = g_list_prepend (ret, t);
4904 }
4905
4906 if (!mxf_ul_is_zero (&self->picture_essence_coding)) {
4907 t = g_slice_new0 (MXFLocalTag);
4908 memcpy (&t->ul, MXF_UL (PICTURE_ESSENCE_CODING), 16);
4909 t->size = 16;
4910 t->data = g_slice_alloc (t->size);
4911 t->g_slice = TRUE;
4912 memcpy (t->data, &self->picture_essence_coding, 16);
4913 mxf_primer_pack_add_mapping (primer, 0x3201, &t->ul);
4914 ret = g_list_prepend (ret, t);
4915 }
4916
4917 return ret;
4918 }
4919
4920 static void
mxf_metadata_generic_picture_essence_descriptor_init(MXFMetadataGenericPictureEssenceDescriptor * self)4921 mxf_metadata_generic_picture_essence_descriptor_init
4922 (MXFMetadataGenericPictureEssenceDescriptor * self)
4923 {
4924 self->signal_standard = 1;
4925 self->frame_layout = 255;
4926 }
4927
4928 static void
mxf_metadata_generic_picture_essence_descriptor_class_init(MXFMetadataGenericPictureEssenceDescriptorClass * klass)4929 mxf_metadata_generic_picture_essence_descriptor_class_init
4930 (MXFMetadataGenericPictureEssenceDescriptorClass * klass)
4931 {
4932 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
4933 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
4934
4935 metadata_base_class->handle_tag =
4936 mxf_metadata_generic_picture_essence_descriptor_handle_tag;
4937 metadata_base_class->name_quark =
4938 MXF_QUARK (GENERIC_PICTURE_ESSENCE_DESCRIPTOR);
4939 metadata_base_class->to_structure =
4940 mxf_metadata_generic_picture_essence_descriptor_to_structure;
4941 metadata_base_class->write_tags =
4942 mxf_metadata_generic_picture_essence_descriptor_write_tags;
4943 metadata_class->type = 0x0127;
4944 }
4945
mxf_metadata_generic_picture_essence_descriptor_set_caps(MXFMetadataGenericPictureEssenceDescriptor * self,GstCaps * caps)4946 void mxf_metadata_generic_picture_essence_descriptor_set_caps
4947 (MXFMetadataGenericPictureEssenceDescriptor * self, GstCaps * caps)
4948 {
4949 guint par_n, par_d;
4950 guint width, height;
4951 MXFMetadataFileDescriptor *f = (MXFMetadataFileDescriptor *) self;
4952
4953 g_return_if_fail (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (self));
4954 g_return_if_fail (GST_IS_CAPS (caps));
4955
4956 if (f->sample_rate.d == 0) {
4957 GST_ERROR ("Invalid framerate");
4958 } else {
4959 gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION, f->sample_rate.n,
4960 f->sample_rate.d, NULL);
4961 }
4962
4963 width = self->stored_width;
4964 height = self->stored_height;
4965 if (self->sampled_width && self->sampled_height) {
4966 width = self->sampled_width;
4967 height = self->sampled_height;
4968 }
4969 if (self->display_width && self->display_height) {
4970 width = self->display_width;
4971 height = self->display_height;
4972 }
4973
4974 /* If the video is stored as separate fields the
4975 * height is only the height of one field, i.e.
4976 * half the height of the frame.
4977 *
4978 * See SMPTE 377M E2.2 and E1.2
4979 */
4980 if (self->frame_layout == 1 || self->frame_layout == 2
4981 || self->frame_layout == 4) {
4982 height *= 2;
4983 gst_caps_set_simple (caps, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL);
4984
4985 if (self->field_dominance == 2) {
4986 gst_caps_set_simple (caps, "field-order", G_TYPE_STRING,
4987 "bottom-field-first", NULL);
4988 } else {
4989 gst_caps_set_simple (caps, "field-order", G_TYPE_STRING,
4990 "top-field-first", NULL);
4991 }
4992 }
4993
4994 if (width == 0 || height == 0) {
4995 GST_ERROR ("Invalid width/height");
4996 return;
4997 }
4998
4999 gst_caps_set_simple (caps, "width", G_TYPE_INT, width, "height", G_TYPE_INT,
5000 height, NULL);
5001
5002 if (self->aspect_ratio.n == 0 && self->aspect_ratio.d == 0) {
5003 gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
5004 1, 1, NULL);
5005 } else if (self->aspect_ratio.n == 0 || self->aspect_ratio.d == 0) {
5006 GST_ERROR ("Invalid aspect ratio");
5007 } else {
5008 par_n = height * self->aspect_ratio.n;
5009 par_d = width * self->aspect_ratio.d;
5010
5011 gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
5012 par_n, par_d, NULL);
5013 }
5014 }
5015
5016 static gint
gst_greatest_common_divisor(gint a,gint b)5017 gst_greatest_common_divisor (gint a, gint b)
5018 {
5019 while (b != 0) {
5020 int temp = a;
5021
5022 a = b;
5023 b = temp % b;
5024 }
5025
5026 return ABS (a);
5027 }
5028
5029 gboolean
mxf_metadata_generic_picture_essence_descriptor_from_caps(MXFMetadataGenericPictureEssenceDescriptor * self,GstCaps * caps)5030 mxf_metadata_generic_picture_essence_descriptor_from_caps
5031 (MXFMetadataGenericPictureEssenceDescriptor * self, GstCaps * caps) {
5032 gint par_n, par_d, gcd;
5033 gint width, height;
5034 gint fps_n, fps_d;
5035 MXFMetadataFileDescriptor *f = (MXFMetadataFileDescriptor *) self;
5036 GstStructure *s;
5037 gboolean interlaced = FALSE;
5038 const gchar *field_order = NULL;
5039
5040 g_return_val_if_fail (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR
5041 (self), FALSE);
5042 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
5043
5044 s = gst_caps_get_structure (caps, 0);
5045
5046 if (!gst_structure_get_boolean (s, "interlaced", &interlaced) || !interlaced) {
5047 self->frame_layout = 0;
5048 } else {
5049 self->frame_layout = 3;
5050 field_order = gst_structure_get_string (s, "field-order");
5051 if (!field_order || strcmp (field_order, "top-field-first") == 0)
5052 self->field_dominance = 1;
5053 else
5054 self->field_dominance = 2;
5055 }
5056
5057 if (!gst_structure_get_fraction (s, "framerate", &fps_n, &fps_d)) {
5058 GST_ERROR ("Invalid framerate");
5059 return FALSE;
5060 }
5061 f->sample_rate.n = fps_n;
5062 f->sample_rate.d = fps_d;
5063
5064 if (!gst_structure_get_int (s, "width", &width) ||
5065 !gst_structure_get_int (s, "height", &height)) {
5066 GST_ERROR ("Invalid width/height");
5067 return FALSE;
5068 }
5069
5070 self->stored_width = width;
5071 self->stored_height = height;
5072
5073 if (!gst_structure_get_fraction (s, "pixel-aspect-ratio", &par_n, &par_d)) {
5074 par_n = 1;
5075 par_d = 1;
5076 }
5077
5078 self->aspect_ratio.n = par_n * width;
5079 self->aspect_ratio.d = par_d * height;
5080 gcd =
5081 gst_greatest_common_divisor (self->aspect_ratio.n, self->aspect_ratio.d);
5082 self->aspect_ratio.n /= gcd;
5083 self->aspect_ratio.d /= gcd;
5084
5085 return TRUE;
5086 }
5087
5088
5089 G_DEFINE_TYPE (MXFMetadataGenericSoundEssenceDescriptor,
5090 mxf_metadata_generic_sound_essence_descriptor,
5091 MXF_TYPE_METADATA_FILE_DESCRIPTOR);
5092
5093 static gboolean
mxf_metadata_generic_sound_essence_descriptor_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)5094 mxf_metadata_generic_sound_essence_descriptor_handle_tag (MXFMetadataBase *
5095 metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
5096 guint tag_size)
5097 {
5098 MXFMetadataGenericSoundEssenceDescriptor *self =
5099 MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (metadata);
5100 gboolean ret = TRUE;
5101 #ifndef GST_DISABLE_GST_DEBUG
5102 gchar str[48];
5103 #endif
5104
5105 switch (tag) {
5106 case 0x3d03:
5107 if (!mxf_fraction_parse (&self->audio_sampling_rate, tag_data, tag_size))
5108 goto error;
5109 GST_DEBUG (" audio sampling rate = %d/%d",
5110 self->audio_sampling_rate.n, self->audio_sampling_rate.d);
5111 break;
5112 case 0x3d02:
5113 if (tag_size != 1)
5114 goto error;
5115 self->locked = (GST_READ_UINT8 (tag_data) != 0);
5116 GST_DEBUG (" locked = %s", (self->locked) ? "yes" : "no");
5117 break;
5118 case 0x3d04:
5119 if (tag_size != 1)
5120 goto error;
5121 self->audio_ref_level = GST_READ_UINT8 (tag_data);
5122 GST_DEBUG (" audio ref level = %d", self->audio_ref_level);
5123 break;
5124 case 0x3d05:
5125 if (tag_size != 1)
5126 goto error;
5127 self->electro_spatial_formulation = GST_READ_UINT8 (tag_data);
5128 GST_DEBUG (" electro spatial formulation = %u",
5129 self->electro_spatial_formulation);
5130 break;
5131 case 0x3d07:
5132 if (tag_size != 4)
5133 goto error;
5134 self->channel_count = GST_READ_UINT32_BE (tag_data);
5135 GST_DEBUG (" channel count = %u", self->channel_count);
5136 break;
5137 case 0x3d01:
5138 if (tag_size != 4)
5139 goto error;
5140 self->quantization_bits = GST_READ_UINT32_BE (tag_data);
5141 GST_DEBUG (" quantization bits = %u", self->quantization_bits);
5142 break;
5143 case 0x3d0c:
5144 if (tag_size != 1)
5145 goto error;
5146 self->dial_norm = GST_READ_UINT8 (tag_data);
5147 GST_DEBUG (" dial norm = %d", self->dial_norm);
5148 break;
5149 case 0x3d06:
5150 if (tag_size != 16)
5151 goto error;
5152 memcpy (&self->sound_essence_compression, tag_data, 16);
5153 GST_DEBUG (" sound essence compression = %s",
5154 mxf_ul_to_string (&self->sound_essence_compression, str));
5155 break;
5156 default:
5157 ret =
5158 MXF_METADATA_BASE_CLASS
5159 (mxf_metadata_generic_sound_essence_descriptor_parent_class)->handle_tag
5160 (metadata, primer, tag, tag_data, tag_size);
5161 break;
5162 }
5163
5164 return ret;
5165
5166 error:
5167
5168 GST_ERROR
5169 ("Invalid generic sound essence descriptor local tag 0x%04x of size %u",
5170 tag, tag_size);
5171
5172 return FALSE;
5173 }
5174
5175 static GstStructure *
mxf_metadata_generic_sound_essence_descriptor_to_structure(MXFMetadataBase * m)5176 mxf_metadata_generic_sound_essence_descriptor_to_structure (MXFMetadataBase * m)
5177 {
5178 GstStructure *ret =
5179 MXF_METADATA_BASE_CLASS
5180 (mxf_metadata_generic_sound_essence_descriptor_parent_class)->to_structure
5181 (m);
5182 MXFMetadataGenericSoundEssenceDescriptor *self =
5183 MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (m);
5184
5185 gst_structure_id_set (ret, MXF_QUARK (AUDIO_SAMPLING_RATE), GST_TYPE_FRACTION,
5186 self->audio_sampling_rate.n, self->audio_sampling_rate.d, NULL);
5187
5188 gst_structure_id_set (ret, MXF_QUARK (LOCKED), G_TYPE_BOOLEAN, self->locked,
5189 NULL);
5190
5191 if (self->electro_spatial_formulation != 0)
5192 gst_structure_id_set (ret, MXF_QUARK (ELECTRO_SPATIAL_FORMULATION),
5193 G_TYPE_UCHAR, self->electro_spatial_formulation, NULL);
5194
5195 gst_structure_id_set (ret, MXF_QUARK (CHANNEL_COUNT), G_TYPE_UINT,
5196 self->channel_count, NULL);
5197
5198 gst_structure_id_set (ret, MXF_QUARK (QUANTIZATION_BITS), G_TYPE_UINT,
5199 self->quantization_bits, NULL);
5200
5201 if (self->dial_norm != 0)
5202 gst_structure_id_set (ret, MXF_QUARK (DIAL_NORM), G_TYPE_CHAR,
5203 self->dial_norm, NULL);
5204
5205 if (!mxf_ul_is_zero (&self->sound_essence_compression)) {
5206 gchar str[48];
5207
5208 mxf_ul_to_string (&self->sound_essence_compression, str);
5209 gst_structure_id_set (ret, MXF_QUARK (SOUND_ESSENCE_COMPRESSION),
5210 G_TYPE_STRING, str, NULL);
5211 }
5212
5213 return ret;
5214 }
5215
5216 static GList *
mxf_metadata_generic_sound_essence_descriptor_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)5217 mxf_metadata_generic_sound_essence_descriptor_write_tags (MXFMetadataBase * m,
5218 MXFPrimerPack * primer)
5219 {
5220 MXFMetadataGenericSoundEssenceDescriptor *self =
5221 MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (m);
5222 GList *ret =
5223 MXF_METADATA_BASE_CLASS
5224 (mxf_metadata_generic_sound_essence_descriptor_parent_class)->write_tags
5225 (m, primer);
5226 MXFLocalTag *t;
5227
5228 t = g_slice_new0 (MXFLocalTag);
5229 memcpy (&t->ul, MXF_UL (AUDIO_SAMPLING_RATE), 16);
5230 t->size = 8;
5231 t->data = g_slice_alloc (t->size);
5232 t->g_slice = TRUE;
5233 GST_WRITE_UINT32_BE (t->data, self->audio_sampling_rate.n);
5234 GST_WRITE_UINT32_BE (t->data + 4, self->audio_sampling_rate.d);
5235 mxf_primer_pack_add_mapping (primer, 0x3d03, &t->ul);
5236 ret = g_list_prepend (ret, t);
5237
5238 t = g_slice_new0 (MXFLocalTag);
5239 memcpy (&t->ul, MXF_UL (LOCKED), 16);
5240 t->size = 1;
5241 t->data = g_slice_alloc (t->size);
5242 t->g_slice = TRUE;
5243 GST_WRITE_UINT8 (t->data, (self->locked) ? 1 : 0);
5244 mxf_primer_pack_add_mapping (primer, 0x3d02, &t->ul);
5245 ret = g_list_prepend (ret, t);
5246
5247 if (self->audio_ref_level) {
5248 t = g_slice_new0 (MXFLocalTag);
5249 memcpy (&t->ul, MXF_UL (AUDIO_REF_LEVEL), 16);
5250 t->size = 1;
5251 t->data = g_slice_alloc (t->size);
5252 t->g_slice = TRUE;
5253 GST_WRITE_UINT8 (t->data, self->audio_ref_level);
5254 mxf_primer_pack_add_mapping (primer, 0x3d04, &t->ul);
5255 ret = g_list_prepend (ret, t);
5256 }
5257
5258 if (self->electro_spatial_formulation != 255) {
5259 t = g_slice_new0 (MXFLocalTag);
5260 memcpy (&t->ul, MXF_UL (ELECTRO_SPATIAL_FORMULATION), 16);
5261 t->size = 1;
5262 t->data = g_slice_alloc (t->size);
5263 t->g_slice = TRUE;
5264 GST_WRITE_UINT8 (t->data, self->electro_spatial_formulation);
5265 mxf_primer_pack_add_mapping (primer, 0x3d05, &t->ul);
5266 ret = g_list_prepend (ret, t);
5267 }
5268
5269 t = g_slice_new0 (MXFLocalTag);
5270 memcpy (&t->ul, MXF_UL (CHANNEL_COUNT), 16);
5271 t->size = 4;
5272 t->data = g_slice_alloc (t->size);
5273 t->g_slice = TRUE;
5274 GST_WRITE_UINT32_BE (t->data, self->channel_count);
5275 mxf_primer_pack_add_mapping (primer, 0x3d07, &t->ul);
5276 ret = g_list_prepend (ret, t);
5277
5278 t = g_slice_new0 (MXFLocalTag);
5279 memcpy (&t->ul, MXF_UL (QUANTIZATION_BITS), 16);
5280 t->size = 4;
5281 t->data = g_slice_alloc (t->size);
5282 t->g_slice = TRUE;
5283 GST_WRITE_UINT32_BE (t->data, self->quantization_bits);
5284 mxf_primer_pack_add_mapping (primer, 0x3d01, &t->ul);
5285 ret = g_list_prepend (ret, t);
5286
5287 if (self->dial_norm != 0) {
5288 t = g_slice_new0 (MXFLocalTag);
5289 memcpy (&t->ul, MXF_UL (DIAL_NORM), 16);
5290 t->size = 1;
5291 t->data = g_slice_alloc (t->size);
5292 t->g_slice = TRUE;
5293 GST_WRITE_UINT8 (t->data, self->dial_norm);
5294 mxf_primer_pack_add_mapping (primer, 0x3d0c, &t->ul);
5295 ret = g_list_prepend (ret, t);
5296 }
5297
5298 if (!mxf_ul_is_zero (&self->sound_essence_compression)) {
5299 t = g_slice_new0 (MXFLocalTag);
5300 memcpy (&t->ul, MXF_UL (SOUND_ESSENCE_COMPRESSION), 16);
5301 t->size = 16;
5302 t->data = g_slice_alloc (t->size);
5303 t->g_slice = TRUE;
5304 memcpy (t->data, &self->sound_essence_compression, 16);
5305 mxf_primer_pack_add_mapping (primer, 0x3d06, &t->ul);
5306 ret = g_list_prepend (ret, t);
5307 }
5308
5309 return ret;
5310 }
5311
5312 static void
mxf_metadata_generic_sound_essence_descriptor_init(MXFMetadataGenericSoundEssenceDescriptor * self)5313 mxf_metadata_generic_sound_essence_descriptor_init
5314 (MXFMetadataGenericSoundEssenceDescriptor * self)
5315 {
5316 self->audio_sampling_rate.n = 0;
5317 self->audio_sampling_rate.d = 1;
5318 self->electro_spatial_formulation = 255;
5319 }
5320
5321 static void
mxf_metadata_generic_sound_essence_descriptor_class_init(MXFMetadataGenericSoundEssenceDescriptorClass * klass)5322 mxf_metadata_generic_sound_essence_descriptor_class_init
5323 (MXFMetadataGenericSoundEssenceDescriptorClass * klass)
5324 {
5325 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
5326 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
5327
5328 metadata_base_class->handle_tag =
5329 mxf_metadata_generic_sound_essence_descriptor_handle_tag;
5330 metadata_base_class->name_quark =
5331 MXF_QUARK (GENERIC_SOUND_ESSENCE_DESCRIPTOR);
5332 metadata_base_class->to_structure =
5333 mxf_metadata_generic_sound_essence_descriptor_to_structure;
5334 metadata_base_class->write_tags =
5335 mxf_metadata_generic_sound_essence_descriptor_write_tags;
5336 metadata_class->type = 0x0142;
5337 }
5338
mxf_metadata_generic_sound_essence_descriptor_set_caps(MXFMetadataGenericSoundEssenceDescriptor * self,GstCaps * caps)5339 void mxf_metadata_generic_sound_essence_descriptor_set_caps
5340 (MXFMetadataGenericSoundEssenceDescriptor * self, GstCaps * caps)
5341 {
5342 g_return_if_fail (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (self));
5343 g_return_if_fail (GST_IS_CAPS (caps));
5344
5345 if (self->audio_sampling_rate.n == 0 || self->audio_sampling_rate.d == 0) {
5346 GST_ERROR ("Invalid audio sampling rate");
5347 } else {
5348 gst_caps_set_simple (caps, "rate", G_TYPE_INT,
5349 (gint) (mxf_fraction_to_double (&self->audio_sampling_rate) + 0.5),
5350 NULL);
5351 }
5352
5353 if (self->channel_count == 0) {
5354 GST_ERROR ("Invalid number of channels (0)");
5355 } else {
5356 gst_caps_set_simple (caps, "channels", G_TYPE_INT, self->channel_count,
5357 NULL);
5358 }
5359 }
5360
mxf_metadata_generic_sound_essence_descriptor_create_caps(MXFMetadataGenericSoundEssenceDescriptor * self,GstAudioFormat * format)5361 GstCaps *mxf_metadata_generic_sound_essence_descriptor_create_caps
5362 (MXFMetadataGenericSoundEssenceDescriptor * self, GstAudioFormat * format)
5363 {
5364 GstAudioInfo info;
5365 gint rate = 0;
5366 gint channels = 0;
5367
5368 g_return_val_if_fail (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (self),
5369 NULL);
5370
5371 gst_audio_info_init (&info);
5372
5373 if (self->audio_sampling_rate.n == 0 || self->audio_sampling_rate.d == 0) {
5374 GST_ERROR ("Invalid audio sampling rate");
5375 } else {
5376 rate = (gint) (mxf_fraction_to_double (&self->audio_sampling_rate)
5377 + 0.5);
5378 }
5379
5380 if (self->channel_count == 0) {
5381 GST_ERROR ("Invalid number of channels (0)");
5382 } else {
5383 channels = self->channel_count;
5384 }
5385
5386 gst_audio_info_set_format (&info, *format, rate, channels, NULL);
5387
5388 return gst_audio_info_to_caps (&info);
5389 }
5390
5391 gboolean
mxf_metadata_generic_sound_essence_descriptor_from_caps(MXFMetadataGenericSoundEssenceDescriptor * self,GstCaps * caps)5392 mxf_metadata_generic_sound_essence_descriptor_from_caps
5393 (MXFMetadataGenericSoundEssenceDescriptor * self, GstCaps * caps) {
5394 gint rate;
5395 gint channels;
5396 GstStructure *s;
5397
5398 g_return_val_if_fail (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (self),
5399 FALSE);
5400 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
5401
5402 s = gst_caps_get_structure (caps, 0);
5403
5404 if (!gst_structure_get_int (s, "rate", &rate) || rate == 0) {
5405 GST_WARNING ("No samplerate");
5406 return FALSE;
5407 } else {
5408 self->audio_sampling_rate.n = rate;
5409 self->audio_sampling_rate.d = 1;
5410 }
5411
5412 if (!gst_structure_get_int (s, "channels", &channels) || channels == 0) {
5413 GST_WARNING ("No channels");
5414 return FALSE;
5415 } else {
5416 self->channel_count = channels;
5417 }
5418
5419 return TRUE;
5420 }
5421
5422
5423 G_DEFINE_TYPE (MXFMetadataCDCIPictureEssenceDescriptor,
5424 mxf_metadata_cdci_picture_essence_descriptor,
5425 MXF_TYPE_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR);
5426
5427 static gboolean
mxf_metadata_cdci_picture_essence_descriptor_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)5428 mxf_metadata_cdci_picture_essence_descriptor_handle_tag (MXFMetadataBase *
5429 metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
5430 guint tag_size)
5431 {
5432 MXFMetadataCDCIPictureEssenceDescriptor *self =
5433 MXF_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (metadata);
5434 gboolean ret = TRUE;
5435
5436 switch (tag) {
5437 case 0x3301:
5438 if (tag_size != 4)
5439 goto error;
5440 self->component_depth = GST_READ_UINT32_BE (tag_data);
5441 GST_DEBUG (" component depth = %u", self->component_depth);
5442 break;
5443 case 0x3302:
5444 if (tag_size != 4)
5445 goto error;
5446 self->horizontal_subsampling = GST_READ_UINT32_BE (tag_data);
5447 GST_DEBUG (" horizontal subsampling = %u", self->horizontal_subsampling);
5448 break;
5449 case 0x3308:
5450 if (tag_size != 4)
5451 goto error;
5452 self->vertical_subsampling = GST_READ_UINT32_BE (tag_data);
5453 GST_DEBUG (" vertical subsampling = %u", self->vertical_subsampling);
5454 break;
5455 case 0x3303:
5456 if (tag_size != 1)
5457 goto error;
5458 self->color_siting = GST_READ_UINT8 (tag_data);
5459 GST_DEBUG (" color siting = %u", self->color_siting);
5460 break;
5461 case 0x330b:
5462 if (tag_size != 1)
5463 goto error;
5464 self->reversed_byte_order = GST_READ_UINT8 (tag_data);
5465 GST_DEBUG (" reversed byte order = %s",
5466 (self->reversed_byte_order) ? "yes" : "no");
5467 break;
5468 case 0x3307:
5469 if (tag_size != 2)
5470 goto error;
5471 self->padding_bits = GST_READ_UINT16_BE (tag_data);
5472 GST_DEBUG (" padding bits = %d", self->padding_bits);
5473 break;
5474 case 0x3309:
5475 if (tag_size != 4)
5476 goto error;
5477 self->alpha_sample_depth = GST_READ_UINT32_BE (tag_data);
5478 GST_DEBUG (" alpha sample depth = %u", self->alpha_sample_depth);
5479 break;
5480 case 0x3304:
5481 if (tag_size != 4)
5482 goto error;
5483 self->black_ref_level = GST_READ_UINT32_BE (tag_data);
5484 GST_DEBUG (" black ref level = %u", self->black_ref_level);
5485 break;
5486 case 0x3305:
5487 if (tag_size != 4)
5488 goto error;
5489 self->white_ref_level = GST_READ_UINT32_BE (tag_data);
5490 GST_DEBUG (" white ref level = %u", self->white_ref_level);
5491 break;
5492 case 0x3306:
5493 if (tag_size != 4)
5494 goto error;
5495 self->color_range = GST_READ_UINT32_BE (tag_data);
5496 GST_DEBUG (" color range = %u", self->color_range);
5497 break;
5498 default:
5499 ret =
5500 MXF_METADATA_BASE_CLASS
5501 (mxf_metadata_cdci_picture_essence_descriptor_parent_class)->handle_tag
5502 (metadata, primer, tag, tag_data, tag_size);
5503 break;
5504 }
5505
5506 return ret;
5507
5508 error:
5509
5510 GST_ERROR
5511 ("Invalid CDCI picture essence descriptor local tag 0x%04x of size %u",
5512 tag, tag_size);
5513
5514 return FALSE;
5515 }
5516
5517 static GstStructure *
mxf_metadata_cdci_picture_essence_descriptor_to_structure(MXFMetadataBase * m)5518 mxf_metadata_cdci_picture_essence_descriptor_to_structure (MXFMetadataBase * m)
5519 {
5520 GstStructure *ret =
5521 MXF_METADATA_BASE_CLASS
5522 (mxf_metadata_cdci_picture_essence_descriptor_parent_class)->to_structure
5523 (m);
5524 MXFMetadataCDCIPictureEssenceDescriptor *self =
5525 MXF_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (m);
5526
5527 gst_structure_id_set (ret, MXF_QUARK (COMPONENT_DEPTH), G_TYPE_UINT,
5528 self->component_depth, NULL);
5529
5530 gst_structure_id_set (ret, MXF_QUARK (HORIZONTAL_SUBSAMPLING), G_TYPE_UINT,
5531 self->horizontal_subsampling, NULL);
5532
5533 if (self->vertical_subsampling != 0)
5534 gst_structure_id_set (ret, MXF_QUARK (VERTICAL_SUBSAMPLING), G_TYPE_UINT,
5535 self->vertical_subsampling, NULL);
5536
5537 if (self->color_siting != 255)
5538 gst_structure_id_set (ret, MXF_QUARK (COLOR_SITING), G_TYPE_UCHAR,
5539 self->color_siting, NULL);
5540
5541 gst_structure_id_set (ret, MXF_QUARK (REVERSED_BYTE_ORDER), G_TYPE_BOOLEAN,
5542 self->reversed_byte_order, NULL);
5543
5544 if (self->padding_bits != 0)
5545 gst_structure_id_set (ret, MXF_QUARK (PADDING_BITS), G_TYPE_INT,
5546 self->padding_bits, NULL);
5547
5548 if (self->alpha_sample_depth != 0)
5549 gst_structure_id_set (ret, MXF_QUARK (ALPHA_SAMPLE_DEPTH), G_TYPE_UINT,
5550 self->alpha_sample_depth, NULL);
5551
5552 if (self->black_ref_level != 0)
5553 gst_structure_id_set (ret, MXF_QUARK (BLACK_REF_LEVEL), G_TYPE_UINT,
5554 self->black_ref_level, NULL);
5555
5556 if (self->white_ref_level != 0)
5557 gst_structure_id_set (ret, MXF_QUARK (WHITE_REF_LEVEL), G_TYPE_UINT,
5558 self->white_ref_level, NULL);
5559
5560 if (self->color_range != 0)
5561 gst_structure_id_set (ret, MXF_QUARK (COLOR_RANGE), G_TYPE_UINT,
5562 self->color_range, NULL);
5563
5564 return ret;
5565 }
5566
5567 static GList *
mxf_metadata_cdci_picture_essence_descriptor_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)5568 mxf_metadata_cdci_picture_essence_descriptor_write_tags (MXFMetadataBase * m,
5569 MXFPrimerPack * primer)
5570 {
5571 MXFMetadataCDCIPictureEssenceDescriptor *self =
5572 MXF_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (m);
5573 GList *ret =
5574 MXF_METADATA_BASE_CLASS
5575 (mxf_metadata_cdci_picture_essence_descriptor_parent_class)->write_tags
5576 (m, primer);
5577 MXFLocalTag *t;
5578
5579 t = g_slice_new0 (MXFLocalTag);
5580 memcpy (&t->ul, MXF_UL (COMPONENT_DEPTH), 16);
5581 t->size = 4;
5582 t->data = g_slice_alloc (t->size);
5583 t->g_slice = TRUE;
5584 GST_WRITE_UINT32_BE (t->data, self->component_depth);
5585 mxf_primer_pack_add_mapping (primer, 0x3301, &t->ul);
5586 ret = g_list_prepend (ret, t);
5587
5588 t = g_slice_new0 (MXFLocalTag);
5589 memcpy (&t->ul, MXF_UL (HORIZONTAL_SUBSAMPLING), 16);
5590 t->size = 4;
5591 t->data = g_slice_alloc (t->size);
5592 t->g_slice = TRUE;
5593 GST_WRITE_UINT32_BE (t->data, self->horizontal_subsampling);
5594 mxf_primer_pack_add_mapping (primer, 0x3302, &t->ul);
5595 ret = g_list_prepend (ret, t);
5596
5597 if (self->vertical_subsampling) {
5598 t = g_slice_new0 (MXFLocalTag);
5599 memcpy (&t->ul, MXF_UL (VERTICAL_SUBSAMPLING), 16);
5600 t->size = 4;
5601 t->data = g_slice_alloc (t->size);
5602 t->g_slice = TRUE;
5603 GST_WRITE_UINT32_BE (t->data, self->vertical_subsampling);
5604 mxf_primer_pack_add_mapping (primer, 0x3308, &t->ul);
5605 ret = g_list_prepend (ret, t);
5606 }
5607
5608 if (self->color_siting != 0xff) {
5609 t = g_slice_new0 (MXFLocalTag);
5610 memcpy (&t->ul, MXF_UL (COLOR_SITING), 16);
5611 t->size = 1;
5612 t->data = g_slice_alloc (t->size);
5613 t->g_slice = TRUE;
5614 GST_WRITE_UINT8 (t->data, self->color_siting);
5615 mxf_primer_pack_add_mapping (primer, 0x3303, &t->ul);
5616 ret = g_list_prepend (ret, t);
5617 }
5618
5619 if (self->reversed_byte_order) {
5620 t = g_slice_new0 (MXFLocalTag);
5621 memcpy (&t->ul, MXF_UL (REVERSED_BYTE_ORDER), 16);
5622 t->size = 1;
5623 t->data = g_slice_alloc (t->size);
5624 t->g_slice = TRUE;
5625 GST_WRITE_UINT8 (t->data, (self->reversed_byte_order) ? 1 : 0);
5626 mxf_primer_pack_add_mapping (primer, 0x330b, &t->ul);
5627 ret = g_list_prepend (ret, t);
5628 }
5629
5630 if (self->padding_bits) {
5631 t = g_slice_new0 (MXFLocalTag);
5632 memcpy (&t->ul, MXF_UL (PADDING_BITS), 16);
5633 t->size = 2;
5634 t->data = g_slice_alloc (t->size);
5635 t->g_slice = TRUE;
5636 GST_WRITE_UINT16_BE (t->data, self->padding_bits);
5637 mxf_primer_pack_add_mapping (primer, 0x3307, &t->ul);
5638 ret = g_list_prepend (ret, t);
5639 }
5640
5641 if (self->alpha_sample_depth) {
5642 t = g_slice_new0 (MXFLocalTag);
5643 memcpy (&t->ul, MXF_UL (ALPHA_SAMPLE_DEPTH), 16);
5644 t->size = 4;
5645 t->data = g_slice_alloc (t->size);
5646 t->g_slice = TRUE;
5647 GST_WRITE_UINT32_BE (t->data, self->alpha_sample_depth);
5648 mxf_primer_pack_add_mapping (primer, 0x3309, &t->ul);
5649 ret = g_list_prepend (ret, t);
5650 }
5651
5652 if (self->black_ref_level) {
5653 t = g_slice_new0 (MXFLocalTag);
5654 memcpy (&t->ul, MXF_UL (BLACK_REF_LEVEL), 16);
5655 t->size = 4;
5656 t->data = g_slice_alloc (t->size);
5657 t->g_slice = TRUE;
5658 GST_WRITE_UINT32_BE (t->data, self->black_ref_level);
5659 mxf_primer_pack_add_mapping (primer, 0x3304, &t->ul);
5660 ret = g_list_prepend (ret, t);
5661 }
5662
5663 if (self->white_ref_level) {
5664 t = g_slice_new0 (MXFLocalTag);
5665 memcpy (&t->ul, MXF_UL (WHITE_REF_LEVEL), 16);
5666 t->size = 4;
5667 t->data = g_slice_alloc (t->size);
5668 t->g_slice = TRUE;
5669 GST_WRITE_UINT32_BE (t->data, self->white_ref_level);
5670 mxf_primer_pack_add_mapping (primer, 0x3305, &t->ul);
5671 ret = g_list_prepend (ret, t);
5672 }
5673
5674 if (self->color_range) {
5675 t = g_slice_new0 (MXFLocalTag);
5676 memcpy (&t->ul, MXF_UL (COLOR_RANGE), 16);
5677 t->size = 4;
5678 t->data = g_slice_alloc (t->size);
5679 t->g_slice = TRUE;
5680 GST_WRITE_UINT32_BE (t->data, self->color_range);
5681 mxf_primer_pack_add_mapping (primer, 0x3306, &t->ul);
5682 ret = g_list_prepend (ret, t);
5683 }
5684
5685 return ret;
5686 }
5687
5688 static void
mxf_metadata_cdci_picture_essence_descriptor_init(MXFMetadataCDCIPictureEssenceDescriptor * self)5689 mxf_metadata_cdci_picture_essence_descriptor_init
5690 (MXFMetadataCDCIPictureEssenceDescriptor * self)
5691 {
5692 self->color_siting = 0xff;
5693 }
5694
5695 static void
mxf_metadata_cdci_picture_essence_descriptor_class_init(MXFMetadataCDCIPictureEssenceDescriptorClass * klass)5696 mxf_metadata_cdci_picture_essence_descriptor_class_init
5697 (MXFMetadataCDCIPictureEssenceDescriptorClass * klass)
5698 {
5699 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
5700 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
5701
5702 metadata_base_class->handle_tag =
5703 mxf_metadata_cdci_picture_essence_descriptor_handle_tag;
5704 metadata_base_class->name_quark = MXF_QUARK (CDCI_PICTURE_ESSENCE_DESCRIPTOR);
5705 metadata_base_class->to_structure =
5706 mxf_metadata_cdci_picture_essence_descriptor_to_structure;
5707 metadata_base_class->write_tags =
5708 mxf_metadata_cdci_picture_essence_descriptor_write_tags;
5709 metadata_class->type = 0x0128;
5710 }
5711
5712 G_DEFINE_TYPE (MXFMetadataRGBAPictureEssenceDescriptor,
5713 mxf_metadata_rgba_picture_essence_descriptor,
5714 MXF_TYPE_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR);
5715
5716 static void
mxf_metadata_rgba_picture_essence_descriptor_finalize(GObject * object)5717 mxf_metadata_rgba_picture_essence_descriptor_finalize (GObject * object)
5718 {
5719 MXFMetadataRGBAPictureEssenceDescriptor *self =
5720 MXF_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (object);
5721
5722 g_free (self->pixel_layout);
5723 self->pixel_layout = NULL;
5724
5725 G_OBJECT_CLASS
5726 (mxf_metadata_rgba_picture_essence_descriptor_parent_class)->finalize
5727 (object);
5728 }
5729
5730 static gboolean
mxf_metadata_rgba_picture_essence_descriptor_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)5731 mxf_metadata_rgba_picture_essence_descriptor_handle_tag (MXFMetadataBase *
5732 metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
5733 guint tag_size)
5734 {
5735 MXFMetadataRGBAPictureEssenceDescriptor *self =
5736 MXF_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (metadata);
5737 gboolean ret = TRUE;
5738
5739 switch (tag) {
5740 case 0x3406:
5741 if (tag_size != 4)
5742 goto error;
5743 self->component_max_ref = GST_READ_UINT32_BE (tag_data);
5744 GST_DEBUG (" component max ref = %u", self->component_max_ref);
5745 break;
5746 case 0x3407:
5747 if (tag_size != 4)
5748 goto error;
5749 self->component_min_ref = GST_READ_UINT32_BE (tag_data);
5750 GST_DEBUG (" component min ref = %u", self->component_min_ref);
5751 break;
5752 case 0x3408:
5753 if (tag_size != 4)
5754 goto error;
5755 self->alpha_max_ref = GST_READ_UINT32_BE (tag_data);
5756 GST_DEBUG (" alpha max ref = %u", self->alpha_max_ref);
5757 break;
5758 case 0x3409:
5759 if (tag_size != 4)
5760 goto error;
5761 self->alpha_min_ref = GST_READ_UINT32_BE (tag_data);
5762 GST_DEBUG (" alpha min ref = %u", self->alpha_min_ref);
5763 break;
5764 case 0x3405:
5765 if (tag_size != 1)
5766 goto error;
5767 self->scanning_direction = GST_READ_UINT8 (tag_data);
5768 GST_DEBUG (" scanning direction = %u", self->scanning_direction);
5769 break;
5770 case 0x3401:{
5771 guint i, len;
5772
5773 if (tag_size % 2 != 0 || tag_size > 16)
5774 goto error;
5775
5776 i = 0;
5777 while (tag_data[i] != 0 && tag_data[i + 1] != 0 && i + 2 <= tag_size)
5778 i += 2;
5779 len = i / 2;
5780
5781 self->n_pixel_layout = len;
5782 GST_DEBUG (" number of pixel layouts = %u", len);
5783 if (len == 0)
5784 return TRUE;
5785
5786 self->pixel_layout = g_malloc0 (16);
5787
5788 for (i = 0; i < len; i++) {
5789 self->pixel_layout[2 * i] = tag_data[2 * i];
5790 self->pixel_layout[2 * i + 1] = tag_data[2 * i + 1];
5791 GST_DEBUG (" pixel layout %u = %c : %u", i,
5792 (gchar) self->pixel_layout[2 * i], self->pixel_layout[2 * i + 1]);
5793 }
5794
5795 break;
5796 }
5797 case 0x3403:
5798 case 0x3404:
5799 /* TODO: handle this */
5800 GST_WARNING (" tag 0x%04x not implemented yet", tag);
5801 break;
5802 default:
5803 ret =
5804 MXF_METADATA_BASE_CLASS
5805 (mxf_metadata_rgba_picture_essence_descriptor_parent_class)->handle_tag
5806 (metadata, primer, tag, tag_data, tag_size);
5807 break;
5808 }
5809
5810 return ret;
5811
5812 error:
5813
5814 GST_ERROR
5815 ("Invalid RGBA picture essence descriptor local tag 0x%04x of size %u",
5816 tag, tag_size);
5817
5818 return FALSE;
5819 }
5820
5821 static GstStructure *
mxf_metadata_rgba_picture_essence_descriptor_to_structure(MXFMetadataBase * m)5822 mxf_metadata_rgba_picture_essence_descriptor_to_structure (MXFMetadataBase * m)
5823 {
5824 GstStructure *ret =
5825 MXF_METADATA_BASE_CLASS
5826 (mxf_metadata_rgba_picture_essence_descriptor_parent_class)->to_structure
5827 (m);
5828 MXFMetadataRGBAPictureEssenceDescriptor *self =
5829 MXF_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (m);
5830
5831 if (self->component_max_ref != 255)
5832 gst_structure_id_set (ret, MXF_QUARK (COMPONENT_MAX_REF), G_TYPE_UINT,
5833 self->component_max_ref, NULL);
5834
5835 if (self->component_min_ref != 0)
5836 gst_structure_id_set (ret, MXF_QUARK (COMPONENT_MIN_REF), G_TYPE_UINT,
5837 self->component_min_ref, NULL);
5838
5839 if (self->alpha_max_ref != 255)
5840 gst_structure_id_set (ret, MXF_QUARK (ALPHA_MAX_REF), G_TYPE_UINT,
5841 self->alpha_max_ref, NULL);
5842
5843 if (self->alpha_min_ref != 0)
5844 gst_structure_id_set (ret, MXF_QUARK (ALPHA_MIN_REF), G_TYPE_UINT,
5845 self->alpha_min_ref, NULL);
5846
5847 if (self->scanning_direction != 0)
5848 gst_structure_id_set (ret, MXF_QUARK (SCANNING_DIRECTION), G_TYPE_UCHAR,
5849 self->scanning_direction, NULL);
5850
5851 if (self->n_pixel_layout != 0) {
5852 gchar *pl = g_new0 (gchar, self->n_pixel_layout * 2 + 1);
5853
5854 memcpy (pl, self->pixel_layout, self->n_pixel_layout * 2);
5855
5856 gst_structure_id_set (ret, MXF_QUARK (PIXEL_LAYOUT), G_TYPE_STRING, pl,
5857 NULL);
5858
5859 g_free (pl);
5860 }
5861
5862 return ret;
5863 }
5864
5865 static GList *
mxf_metadata_rgba_picture_essence_descriptor_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)5866 mxf_metadata_rgba_picture_essence_descriptor_write_tags (MXFMetadataBase * m,
5867 MXFPrimerPack * primer)
5868 {
5869 MXFMetadataRGBAPictureEssenceDescriptor *self =
5870 MXF_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (m);
5871 GList *ret =
5872 MXF_METADATA_BASE_CLASS
5873 (mxf_metadata_rgba_picture_essence_descriptor_parent_class)->write_tags
5874 (m, primer);
5875 MXFLocalTag *t;
5876
5877 if (self->component_max_ref != 255) {
5878 t = g_slice_new0 (MXFLocalTag);
5879 memcpy (&t->ul, MXF_UL (COMPONENT_MAX_REF), 16);
5880 t->size = 4;
5881 t->data = g_slice_alloc (t->size);
5882 t->g_slice = TRUE;
5883 GST_WRITE_UINT32_BE (t->data, self->component_max_ref);
5884 mxf_primer_pack_add_mapping (primer, 0x3406, &t->ul);
5885 ret = g_list_prepend (ret, t);
5886 }
5887
5888 if (self->component_min_ref) {
5889 t = g_slice_new0 (MXFLocalTag);
5890 memcpy (&t->ul, MXF_UL (COMPONENT_MIN_REF), 16);
5891 t->size = 4;
5892 t->data = g_slice_alloc (t->size);
5893 t->g_slice = TRUE;
5894 GST_WRITE_UINT32_BE (t->data, self->component_min_ref);
5895 mxf_primer_pack_add_mapping (primer, 0x3407, &t->ul);
5896 ret = g_list_prepend (ret, t);
5897 }
5898
5899 if (self->alpha_max_ref != 255) {
5900 t = g_slice_new0 (MXFLocalTag);
5901 memcpy (&t->ul, MXF_UL (ALPHA_MAX_REF), 16);
5902 t->size = 4;
5903 t->data = g_slice_alloc (t->size);
5904 t->g_slice = TRUE;
5905 GST_WRITE_UINT32_BE (t->data, self->alpha_max_ref);
5906 mxf_primer_pack_add_mapping (primer, 0x3408, &t->ul);
5907 ret = g_list_prepend (ret, t);
5908 }
5909
5910 if (self->alpha_min_ref) {
5911 t = g_slice_new0 (MXFLocalTag);
5912 memcpy (&t->ul, MXF_UL (ALPHA_MIN_REF), 16);
5913 t->size = 4;
5914 t->data = g_slice_alloc (t->size);
5915 t->g_slice = TRUE;
5916 GST_WRITE_UINT32_BE (t->data, self->alpha_min_ref);
5917 mxf_primer_pack_add_mapping (primer, 0x3409, &t->ul);
5918 ret = g_list_prepend (ret, t);
5919 }
5920
5921 if (self->scanning_direction) {
5922 t = g_slice_new0 (MXFLocalTag);
5923 memcpy (&t->ul, MXF_UL (SCANNING_DIRECTION), 16);
5924 t->size = 1;
5925 t->data = g_slice_alloc (t->size);
5926 t->g_slice = TRUE;
5927 GST_WRITE_UINT8 (t->data, self->scanning_direction);
5928 mxf_primer_pack_add_mapping (primer, 0x3405, &t->ul);
5929 ret = g_list_prepend (ret, t);
5930 }
5931
5932 t = g_slice_new0 (MXFLocalTag);
5933 memcpy (&t->ul, MXF_UL (PIXEL_LAYOUT), 16);
5934 t->size = 16;
5935 t->data = g_slice_alloc0 (t->size);
5936 t->g_slice = TRUE;
5937 if (self->pixel_layout)
5938 memcpy (t->data, self->pixel_layout, self->n_pixel_layout * 2);
5939 mxf_primer_pack_add_mapping (primer, 0x3401, &t->ul);
5940 ret = g_list_prepend (ret, t);
5941
5942 return ret;
5943 }
5944
5945 static void
mxf_metadata_rgba_picture_essence_descriptor_init(MXFMetadataRGBAPictureEssenceDescriptor * self)5946 mxf_metadata_rgba_picture_essence_descriptor_init
5947 (MXFMetadataRGBAPictureEssenceDescriptor * self)
5948 {
5949 self->component_max_ref = 255;
5950 self->alpha_max_ref = 255;
5951 }
5952
5953 static void
mxf_metadata_rgba_picture_essence_descriptor_class_init(MXFMetadataRGBAPictureEssenceDescriptorClass * klass)5954 mxf_metadata_rgba_picture_essence_descriptor_class_init
5955 (MXFMetadataRGBAPictureEssenceDescriptorClass * klass)
5956 {
5957 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
5958 GObjectClass *object_class = (GObjectClass *) klass;
5959 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
5960
5961 object_class->finalize =
5962 mxf_metadata_rgba_picture_essence_descriptor_finalize;
5963 metadata_base_class->handle_tag =
5964 mxf_metadata_rgba_picture_essence_descriptor_handle_tag;
5965 metadata_base_class->name_quark = MXF_QUARK (RGBA_PICTURE_ESSENCE_DESCRIPTOR);
5966 metadata_base_class->to_structure =
5967 mxf_metadata_rgba_picture_essence_descriptor_to_structure;
5968 metadata_base_class->write_tags =
5969 mxf_metadata_rgba_picture_essence_descriptor_write_tags;
5970 metadata_class->type = 0x0129;
5971 }
5972
5973 G_DEFINE_TYPE (MXFMetadataGenericDataEssenceDescriptor,
5974 mxf_metadata_generic_data_essence_descriptor,
5975 MXF_TYPE_METADATA_FILE_DESCRIPTOR);
5976
5977 static gboolean
mxf_metadata_generic_data_essence_descriptor_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)5978 mxf_metadata_generic_data_essence_descriptor_handle_tag (MXFMetadataBase *
5979 metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
5980 guint tag_size)
5981 {
5982 MXFMetadataGenericDataEssenceDescriptor *self =
5983 MXF_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR (metadata);
5984 gboolean ret = TRUE;
5985 #ifndef GST_DISABLE_GST_DEBUG
5986 gchar str[48];
5987 #endif
5988
5989 switch (tag) {
5990 case 0x3e01:
5991 if (tag_size != 16)
5992 goto error;
5993 memcpy (&self->data_essence_coding, tag_data, 16);
5994 GST_DEBUG (" data essence coding = %s",
5995 mxf_ul_to_string (&self->data_essence_coding, str));
5996 break;
5997 default:
5998 ret =
5999 MXF_METADATA_BASE_CLASS
6000 (mxf_metadata_generic_data_essence_descriptor_parent_class)->handle_tag
6001 (metadata, primer, tag, tag_data, tag_size);
6002 break;
6003 }
6004
6005 return ret;
6006
6007 error:
6008
6009 GST_ERROR
6010 ("Invalid generic data essence descriptor local tag 0x%04x of size %u",
6011 tag, tag_size);
6012
6013 return FALSE;
6014 }
6015
6016 static GstStructure *
mxf_metadata_generic_data_essence_descriptor_to_structure(MXFMetadataBase * m)6017 mxf_metadata_generic_data_essence_descriptor_to_structure (MXFMetadataBase * m)
6018 {
6019 GstStructure *ret =
6020 MXF_METADATA_BASE_CLASS
6021 (mxf_metadata_generic_data_essence_descriptor_parent_class)->to_structure
6022 (m);
6023 MXFMetadataGenericDataEssenceDescriptor *self =
6024 MXF_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR (m);
6025 gchar str[48];
6026
6027 if (!mxf_ul_is_zero (&self->data_essence_coding)) {
6028 mxf_ul_to_string (&self->data_essence_coding, str);
6029 gst_structure_id_set (ret, MXF_QUARK (DATA_ESSENCE_CODING), G_TYPE_STRING,
6030 str, NULL);
6031 }
6032
6033 return ret;
6034 }
6035
6036 static GList *
mxf_metadata_generic_data_essence_descriptor_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)6037 mxf_metadata_generic_data_essence_descriptor_write_tags (MXFMetadataBase * m,
6038 MXFPrimerPack * primer)
6039 {
6040 MXFMetadataGenericDataEssenceDescriptor *self =
6041 MXF_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR (m);
6042 GList *ret =
6043 MXF_METADATA_BASE_CLASS
6044 (mxf_metadata_generic_data_essence_descriptor_parent_class)->write_tags
6045 (m, primer);
6046 MXFLocalTag *t;
6047
6048 if (!mxf_ul_is_zero (&self->data_essence_coding)) {
6049 t = g_slice_new0 (MXFLocalTag);
6050 memcpy (&t->ul, MXF_UL (DATA_ESSENCE_CODING), 16);
6051 t->size = 16;
6052 t->data = g_slice_alloc (t->size);
6053 t->g_slice = TRUE;
6054 memcpy (t->data, &self->data_essence_coding, 16);
6055 mxf_primer_pack_add_mapping (primer, 0x3e01, &t->ul);
6056 ret = g_list_prepend (ret, t);
6057 }
6058
6059 return ret;
6060 }
6061
6062 static void
mxf_metadata_generic_data_essence_descriptor_init(MXFMetadataGenericDataEssenceDescriptor * self)6063 mxf_metadata_generic_data_essence_descriptor_init
6064 (MXFMetadataGenericDataEssenceDescriptor * self)
6065 {
6066
6067 }
6068
6069 static void
mxf_metadata_generic_data_essence_descriptor_class_init(MXFMetadataGenericDataEssenceDescriptorClass * klass)6070 mxf_metadata_generic_data_essence_descriptor_class_init
6071 (MXFMetadataGenericDataEssenceDescriptorClass * klass)
6072 {
6073 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
6074 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
6075
6076 metadata_base_class->handle_tag =
6077 mxf_metadata_generic_data_essence_descriptor_handle_tag;
6078 metadata_base_class->name_quark = MXF_QUARK (GENERIC_DATA_ESSENCE_DESCRIPTOR);
6079 metadata_base_class->to_structure =
6080 mxf_metadata_generic_data_essence_descriptor_to_structure;
6081 metadata_base_class->write_tags =
6082 mxf_metadata_generic_data_essence_descriptor_write_tags;
6083 metadata_class->type = 0x0143;
6084 }
6085
6086 G_DEFINE_TYPE (MXFMetadataMultipleDescriptor, mxf_metadata_multiple_descriptor,
6087 MXF_TYPE_METADATA_FILE_DESCRIPTOR);
6088
6089 static void
mxf_metadata_multiple_descriptor_finalize(GObject * object)6090 mxf_metadata_multiple_descriptor_finalize (GObject * object)
6091 {
6092 MXFMetadataMultipleDescriptor *self =
6093 MXF_METADATA_MULTIPLE_DESCRIPTOR (object);
6094
6095 g_free (self->sub_descriptors_uids);
6096 self->sub_descriptors_uids = NULL;
6097 g_free (self->sub_descriptors);
6098 self->sub_descriptors = NULL;
6099
6100 G_OBJECT_CLASS
6101 (mxf_metadata_multiple_descriptor_parent_class)->finalize (object);
6102 }
6103
6104 static gboolean
mxf_metadata_multiple_descriptor_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)6105 mxf_metadata_multiple_descriptor_handle_tag (MXFMetadataBase * metadata,
6106 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
6107 guint tag_size)
6108 {
6109 MXFMetadataMultipleDescriptor *self =
6110 MXF_METADATA_MULTIPLE_DESCRIPTOR (metadata);
6111 gboolean ret = TRUE;
6112 #ifndef GST_DISABLE_GST_DEBUG
6113 gchar str[48];
6114 #endif
6115
6116 switch (tag) {
6117 case 0x3f01:
6118 if (!mxf_uuid_array_parse (&self->sub_descriptors_uids,
6119 &self->n_sub_descriptors, tag_data, tag_size))
6120 goto error;
6121
6122 GST_DEBUG (" number of sub descriptors = %u", self->n_sub_descriptors);
6123 #ifndef GST_DISABLE_GST_DEBUG
6124 {
6125 guint i;
6126 for (i = 0; i < self->n_sub_descriptors; i++) {
6127 GST_DEBUG (" sub descriptor %u = %s", i,
6128 mxf_uuid_to_string (&self->sub_descriptors_uids[i], str));
6129 }
6130 }
6131 #endif
6132
6133 break;
6134 default:
6135 ret =
6136 MXF_METADATA_BASE_CLASS
6137 (mxf_metadata_multiple_descriptor_parent_class)->handle_tag (metadata,
6138 primer, tag, tag_data, tag_size);
6139 break;
6140 }
6141
6142 return ret;
6143
6144 error:
6145
6146 GST_ERROR ("Invalid multiple descriptor local tag 0x%04x of size %u", tag,
6147 tag_size);
6148
6149 return FALSE;
6150 }
6151
6152 static gboolean
mxf_metadata_multiple_descriptor_resolve(MXFMetadataBase * m,GHashTable * metadata)6153 mxf_metadata_multiple_descriptor_resolve (MXFMetadataBase * m,
6154 GHashTable * metadata)
6155 {
6156 MXFMetadataMultipleDescriptor *self = MXF_METADATA_MULTIPLE_DESCRIPTOR (m);
6157 MXFMetadataBase *current = NULL;
6158 guint i, have_subdescriptors = 0;
6159 #ifndef GST_DISABLE_GST_DEBUG
6160 gchar str[48];
6161 #endif
6162
6163 if (self->sub_descriptors)
6164 memset (self->sub_descriptors, 0,
6165 sizeof (gpointer) * self->n_sub_descriptors);
6166 else
6167 self->sub_descriptors =
6168 g_new0 (MXFMetadataGenericDescriptor *, self->n_sub_descriptors);
6169 for (i = 0; i < self->n_sub_descriptors; i++) {
6170 current = g_hash_table_lookup (metadata, &self->sub_descriptors_uids[i]);
6171 if (current && MXF_IS_METADATA_GENERIC_DESCRIPTOR (current)) {
6172 if (mxf_metadata_base_resolve (current, metadata)) {
6173 self->sub_descriptors[i] = MXF_METADATA_GENERIC_DESCRIPTOR (current);
6174 have_subdescriptors++;
6175 } else {
6176 GST_ERROR ("Couldn't resolve descriptor %s",
6177 mxf_uuid_to_string (&self->sub_descriptors_uids[i], str));
6178 return FALSE;
6179 }
6180 } else {
6181 GST_ERROR ("Descriptor %s not found",
6182 mxf_uuid_to_string (&self->sub_descriptors_uids[i], str));
6183 }
6184 }
6185
6186 return
6187 MXF_METADATA_BASE_CLASS
6188 (mxf_metadata_multiple_descriptor_parent_class)->resolve (m, metadata);
6189 }
6190
6191 static GstStructure *
mxf_metadata_multiple_descriptor_to_structure(MXFMetadataBase * m)6192 mxf_metadata_multiple_descriptor_to_structure (MXFMetadataBase * m)
6193 {
6194 GstStructure *ret =
6195 MXF_METADATA_BASE_CLASS
6196 (mxf_metadata_multiple_descriptor_parent_class)->to_structure (m);
6197 MXFMetadataMultipleDescriptor *self = MXF_METADATA_MULTIPLE_DESCRIPTOR (m);
6198 guint i;
6199
6200 if (self->n_sub_descriptors > 0) {
6201 GValue arr = { 0, }
6202 , val = {
6203 0,};
6204
6205 g_value_init (&arr, GST_TYPE_ARRAY);
6206
6207 for (i = 0; i < self->n_sub_descriptors; i++) {
6208 GstStructure *s;
6209
6210 if (self->sub_descriptors[i] == NULL)
6211 continue;
6212
6213 g_value_init (&val, GST_TYPE_STRUCTURE);
6214
6215 s = mxf_metadata_base_to_structure (MXF_METADATA_BASE
6216 (self->sub_descriptors[i]));
6217 gst_value_set_structure (&val, s);
6218 gst_structure_free (s);
6219 gst_value_array_append_value (&arr, &val);
6220 g_value_unset (&val);
6221 }
6222
6223 if (gst_value_array_get_size (&arr) > 0)
6224 gst_structure_id_set_value (ret, MXF_QUARK (SUB_DESCRIPTORS), &arr);
6225
6226 g_value_unset (&arr);
6227 }
6228
6229 return ret;
6230 }
6231
6232 static GList *
mxf_metadata_multiple_descriptor_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)6233 mxf_metadata_multiple_descriptor_write_tags (MXFMetadataBase * m,
6234 MXFPrimerPack * primer)
6235 {
6236 MXFMetadataMultipleDescriptor *self = MXF_METADATA_MULTIPLE_DESCRIPTOR (m);
6237 GList *ret =
6238 MXF_METADATA_BASE_CLASS
6239 (mxf_metadata_multiple_descriptor_parent_class)->write_tags (m, primer);
6240 MXFLocalTag *t;
6241
6242 if (self->sub_descriptors) {
6243 guint i;
6244
6245 t = g_slice_new0 (MXFLocalTag);
6246 memcpy (&t->ul, MXF_UL (SUB_DESCRIPTORS), 16);
6247 t->size = 8 + 16 * self->n_sub_descriptors;
6248 t->data = g_slice_alloc0 (t->size);
6249 t->g_slice = TRUE;
6250 GST_WRITE_UINT32_BE (t->data, self->n_sub_descriptors);
6251 GST_WRITE_UINT32_BE (t->data + 4, 16);
6252 for (i = 0; i < self->n_sub_descriptors; i++) {
6253 if (!self->sub_descriptors[i])
6254 continue;
6255
6256 memcpy (t->data + 8 + 16 * i,
6257 &MXF_METADATA_BASE (self->sub_descriptors[i])->instance_uid, 16);
6258 }
6259 mxf_primer_pack_add_mapping (primer, 0x3f01, &t->ul);
6260 ret = g_list_prepend (ret, t);
6261 }
6262
6263 return ret;
6264 }
6265
6266 static void
mxf_metadata_multiple_descriptor_init(MXFMetadataMultipleDescriptor * self)6267 mxf_metadata_multiple_descriptor_init (MXFMetadataMultipleDescriptor * self)
6268 {
6269
6270 }
6271
6272 static void
mxf_metadata_multiple_descriptor_class_init(MXFMetadataMultipleDescriptorClass * klass)6273 mxf_metadata_multiple_descriptor_class_init (MXFMetadataMultipleDescriptorClass
6274 * klass)
6275 {
6276 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
6277 GObjectClass *object_class = (GObjectClass *) klass;
6278 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
6279
6280 object_class->finalize = mxf_metadata_multiple_descriptor_finalize;
6281 metadata_base_class->handle_tag = mxf_metadata_multiple_descriptor_handle_tag;
6282 metadata_base_class->resolve = mxf_metadata_multiple_descriptor_resolve;
6283 metadata_base_class->name_quark = MXF_QUARK (MULTIPLE_DESCRIPTOR);
6284 metadata_base_class->to_structure =
6285 mxf_metadata_multiple_descriptor_to_structure;
6286 metadata_base_class->write_tags = mxf_metadata_multiple_descriptor_write_tags;
6287 metadata_class->type = 0x0144;
6288 }
6289
6290 G_DEFINE_ABSTRACT_TYPE (MXFMetadataLocator, mxf_metadata_locator,
6291 MXF_TYPE_METADATA);
6292
6293 static void
mxf_metadata_locator_init(MXFMetadataLocator * self)6294 mxf_metadata_locator_init (MXFMetadataLocator * self)
6295 {
6296 }
6297
6298 static void
mxf_metadata_locator_class_init(MXFMetadataLocatorClass * klass)6299 mxf_metadata_locator_class_init (MXFMetadataLocatorClass * klass)
6300 {
6301 }
6302
6303 G_DEFINE_TYPE (MXFMetadataTextLocator, mxf_metadata_text_locator,
6304 MXF_TYPE_METADATA_LOCATOR);
6305
6306 static void
mxf_metadata_text_locator_finalize(GObject * object)6307 mxf_metadata_text_locator_finalize (GObject * object)
6308 {
6309 MXFMetadataTextLocator *self = MXF_METADATA_TEXT_LOCATOR (object);
6310
6311 g_free (self->locator_name);
6312 self->locator_name = NULL;
6313
6314 G_OBJECT_CLASS (mxf_metadata_text_locator_parent_class)->finalize (object);
6315 }
6316
6317 static gboolean
mxf_metadata_text_locator_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)6318 mxf_metadata_text_locator_handle_tag (MXFMetadataBase * metadata,
6319 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
6320 guint tag_size)
6321 {
6322 MXFMetadataTextLocator *self = MXF_METADATA_TEXT_LOCATOR (metadata);
6323 gboolean ret = TRUE;
6324
6325 switch (tag) {
6326 case 0x4101:
6327 self->locator_name = mxf_utf16_to_utf8 (tag_data, tag_size);
6328 GST_DEBUG (" text locator = %s", GST_STR_NULL (self->locator_name));
6329 break;
6330 default:
6331 ret =
6332 MXF_METADATA_BASE_CLASS
6333 (mxf_metadata_text_locator_parent_class)->handle_tag (metadata,
6334 primer, tag, tag_data, tag_size);
6335 break;
6336 }
6337
6338 return ret;
6339 }
6340
6341 static GstStructure *
mxf_metadata_text_locator_to_structure(MXFMetadataBase * m)6342 mxf_metadata_text_locator_to_structure (MXFMetadataBase * m)
6343 {
6344 GstStructure *ret =
6345 MXF_METADATA_BASE_CLASS
6346 (mxf_metadata_text_locator_parent_class)->to_structure (m);
6347 MXFMetadataTextLocator *self = MXF_METADATA_TEXT_LOCATOR (m);
6348
6349 gst_structure_id_set (ret, MXF_QUARK (LOCATOR_NAME), G_TYPE_STRING,
6350 self->locator_name, NULL);
6351
6352 return ret;
6353 }
6354
6355 static GList *
mxf_metadata_text_locator_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)6356 mxf_metadata_text_locator_write_tags (MXFMetadataBase * m,
6357 MXFPrimerPack * primer)
6358 {
6359 MXFMetadataTextLocator *self = MXF_METADATA_TEXT_LOCATOR (m);
6360 GList *ret =
6361 MXF_METADATA_BASE_CLASS
6362 (mxf_metadata_text_locator_parent_class)->write_tags (m, primer);
6363 MXFLocalTag *t;
6364
6365 if (self->locator_name) {
6366 t = g_slice_new0 (MXFLocalTag);
6367 memcpy (&t->ul, MXF_UL (LOCATOR_NAME), 16);
6368 t->data = mxf_utf8_to_utf16 (self->locator_name, &t->size);
6369 mxf_primer_pack_add_mapping (primer, 0x4101, &t->ul);
6370 ret = g_list_prepend (ret, t);
6371 }
6372
6373 return ret;
6374 }
6375
6376 static void
mxf_metadata_text_locator_init(MXFMetadataTextLocator * self)6377 mxf_metadata_text_locator_init (MXFMetadataTextLocator * self)
6378 {
6379
6380 }
6381
6382 static void
mxf_metadata_text_locator_class_init(MXFMetadataTextLocatorClass * klass)6383 mxf_metadata_text_locator_class_init (MXFMetadataTextLocatorClass * klass)
6384 {
6385 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
6386 GObjectClass *object_class = (GObjectClass *) klass;
6387 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
6388
6389 object_class->finalize = mxf_metadata_text_locator_finalize;
6390 metadata_base_class->handle_tag = mxf_metadata_text_locator_handle_tag;
6391 metadata_base_class->name_quark = MXF_QUARK (TEXT_LOCATOR);
6392 metadata_base_class->to_structure = mxf_metadata_text_locator_to_structure;
6393 metadata_base_class->write_tags = mxf_metadata_text_locator_write_tags;
6394 metadata_class->type = 0x0133;
6395 }
6396
6397 G_DEFINE_TYPE (MXFMetadataNetworkLocator, mxf_metadata_network_locator,
6398 MXF_TYPE_METADATA_LOCATOR);
6399
6400 static void
mxf_metadata_network_locator_finalize(GObject * object)6401 mxf_metadata_network_locator_finalize (GObject * object)
6402 {
6403 MXFMetadataNetworkLocator *self = MXF_METADATA_NETWORK_LOCATOR (object);
6404
6405 g_free (self->url_string);
6406 self->url_string = NULL;
6407
6408 G_OBJECT_CLASS (mxf_metadata_network_locator_parent_class)->finalize (object);
6409 }
6410
6411 static gboolean
mxf_metadata_network_locator_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)6412 mxf_metadata_network_locator_handle_tag (MXFMetadataBase * metadata,
6413 MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
6414 guint tag_size)
6415 {
6416 MXFMetadataNetworkLocator *self = MXF_METADATA_NETWORK_LOCATOR (metadata);
6417 gboolean ret = TRUE;
6418
6419 switch (tag) {
6420 case 0x4101:
6421 self->url_string = mxf_utf16_to_utf8 (tag_data, tag_size);
6422 GST_DEBUG (" url string = %s", GST_STR_NULL (self->url_string));
6423 break;
6424 default:
6425 ret =
6426 MXF_METADATA_BASE_CLASS
6427 (mxf_metadata_network_locator_parent_class)->handle_tag (metadata,
6428 primer, tag, tag_data, tag_size);
6429 break;
6430 }
6431
6432 return ret;
6433 }
6434
6435 static GstStructure *
mxf_metadata_network_locator_to_structure(MXFMetadataBase * m)6436 mxf_metadata_network_locator_to_structure (MXFMetadataBase * m)
6437 {
6438 GstStructure *ret =
6439 MXF_METADATA_BASE_CLASS
6440 (mxf_metadata_network_locator_parent_class)->to_structure (m);
6441 MXFMetadataNetworkLocator *self = MXF_METADATA_NETWORK_LOCATOR (m);
6442
6443 gst_structure_id_set (ret, MXF_QUARK (URL_STRING), G_TYPE_STRING,
6444 self->url_string, NULL);
6445
6446 return ret;
6447 }
6448
6449 static GList *
mxf_metadata_network_locator_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)6450 mxf_metadata_network_locator_write_tags (MXFMetadataBase * m,
6451 MXFPrimerPack * primer)
6452 {
6453 MXFMetadataNetworkLocator *self = MXF_METADATA_NETWORK_LOCATOR (m);
6454 GList *ret =
6455 MXF_METADATA_BASE_CLASS
6456 (mxf_metadata_network_locator_parent_class)->write_tags (m, primer);
6457 MXFLocalTag *t;
6458
6459 if (self->url_string) {
6460 t = g_slice_new0 (MXFLocalTag);
6461 memcpy (&t->ul, MXF_UL (URL_STRING), 16);
6462 t->data = mxf_utf8_to_utf16 (self->url_string, &t->size);
6463 mxf_primer_pack_add_mapping (primer, 0x4001, &t->ul);
6464 ret = g_list_prepend (ret, t);
6465 }
6466
6467 return ret;
6468 }
6469
6470 static void
mxf_metadata_network_locator_init(MXFMetadataNetworkLocator * self)6471 mxf_metadata_network_locator_init (MXFMetadataNetworkLocator * self)
6472 {
6473 }
6474
6475 static void
mxf_metadata_network_locator_class_init(MXFMetadataNetworkLocatorClass * klass)6476 mxf_metadata_network_locator_class_init (MXFMetadataNetworkLocatorClass * klass)
6477 {
6478 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
6479 GObjectClass *object_class = (GObjectClass *) klass;
6480 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
6481
6482 object_class->finalize = mxf_metadata_network_locator_finalize;
6483 metadata_base_class->handle_tag = mxf_metadata_network_locator_handle_tag;
6484 metadata_base_class->name_quark = MXF_QUARK (NETWORK_LOCATOR);
6485 metadata_base_class->to_structure = mxf_metadata_network_locator_to_structure;
6486 metadata_base_class->write_tags = mxf_metadata_network_locator_write_tags;
6487 metadata_class->type = 0x0133;
6488 }
6489
6490 G_DEFINE_ABSTRACT_TYPE (MXFDescriptiveMetadata, mxf_descriptive_metadata,
6491 MXF_TYPE_METADATA_BASE);
6492
6493 static void
mxf_descriptive_metadata_init(MXFDescriptiveMetadata * self)6494 mxf_descriptive_metadata_init (MXFDescriptiveMetadata * self)
6495 {
6496 }
6497
6498 static void
mxf_descriptive_metadata_class_init(MXFDescriptiveMetadataClass * klass)6499 mxf_descriptive_metadata_class_init (MXFDescriptiveMetadataClass * klass)
6500 {
6501 }
6502
6503 typedef struct
6504 {
6505 guint8 scheme;
6506 GType *types;
6507 } _MXFDescriptiveMetadataScheme;
6508
6509 static GArray *_dm_schemes = NULL;
6510
6511 void
mxf_descriptive_metadata_register(guint8 scheme,GType * types)6512 mxf_descriptive_metadata_register (guint8 scheme, GType * types)
6513 {
6514 _MXFDescriptiveMetadataScheme s;
6515
6516 if (!_dm_schemes)
6517 _dm_schemes =
6518 g_array_new (FALSE, TRUE, sizeof (_MXFDescriptiveMetadataScheme));
6519
6520 s.scheme = scheme;
6521 s.types = types;
6522
6523 g_array_append_val (_dm_schemes, s);
6524 }
6525
6526 MXFDescriptiveMetadata *
mxf_descriptive_metadata_new(guint8 scheme,guint32 type,MXFPrimerPack * primer,guint64 offset,const guint8 * data,guint size)6527 mxf_descriptive_metadata_new (guint8 scheme, guint32 type,
6528 MXFPrimerPack * primer, guint64 offset, const guint8 * data, guint size)
6529 {
6530 guint i;
6531 GType t = G_TYPE_INVALID, *p;
6532 _MXFDescriptiveMetadataScheme *s = NULL;
6533 MXFDescriptiveMetadata *ret = NULL;
6534
6535 g_return_val_if_fail (primer != NULL, NULL);
6536
6537 if (G_UNLIKELY (type == 0)) {
6538 GST_WARNING ("Type 0 is invalid");
6539 return NULL;
6540 }
6541
6542 for (i = 0; _dm_schemes && i < _dm_schemes->len; i++) {
6543 _MXFDescriptiveMetadataScheme *data =
6544 &g_array_index (_dm_schemes, _MXFDescriptiveMetadataScheme, i);
6545
6546 if (data->scheme == scheme) {
6547 s = data;
6548 break;
6549 }
6550 }
6551
6552 if (s == NULL) {
6553 GST_WARNING ("Descriptive metadata scheme 0x%02x not supported", scheme);
6554 return NULL;
6555 }
6556
6557 p = s->types;
6558 while (*p) {
6559 GType tmp = *p;
6560 MXFDescriptiveMetadataClass *klass =
6561 MXF_DESCRIPTIVE_METADATA_CLASS (g_type_class_ref (tmp));
6562
6563 if (klass->type == type) {
6564 g_type_class_unref (klass);
6565 t = tmp;
6566 break;
6567 }
6568 g_type_class_unref (klass);
6569 p++;
6570 }
6571
6572 if (t == G_TYPE_INVALID) {
6573 GST_WARNING
6574 ("No handler for type 0x%06x of descriptive metadata scheme 0x%02x found",
6575 type, scheme);
6576 return NULL;
6577 }
6578
6579 GST_DEBUG ("DM scheme 0x%02x type 0x%06x is handled by type %s", scheme, type,
6580 g_type_name (t));
6581
6582 ret = (MXFDescriptiveMetadata *) g_type_create_instance (t);
6583 if (!mxf_metadata_base_parse (MXF_METADATA_BASE (ret), primer, data, size)) {
6584 GST_ERROR ("Parsing metadata failed");
6585 g_object_unref (ret);
6586 return NULL;
6587 }
6588
6589 ret->parent.offset = offset;
6590
6591 return ret;
6592 }
6593
6594 GType
mxf_descriptive_metadata_framework_get_type(void)6595 mxf_descriptive_metadata_framework_get_type (void)
6596 {
6597 static gsize type = 0;
6598 if (g_once_init_enter (&type)) {
6599 GType _type = 0;
6600 static const GTypeInfo info = {
6601 sizeof (MXFDescriptiveMetadataFrameworkInterface),
6602 NULL, /* base_init */
6603 NULL, /* base_finalize */
6604 NULL, /* class_init */
6605 NULL, /* class_finalize */
6606 NULL, /* class_data */
6607 0, /* instance_size */
6608 0, /* n_preallocs */
6609 NULL /* instance_init */
6610 };
6611 _type = g_type_register_static (G_TYPE_INTERFACE,
6612 "MXFDescriptiveMetadataFrameworkInterface", &info, 0);
6613
6614 g_type_interface_add_prerequisite (_type, MXF_TYPE_DESCRIPTIVE_METADATA);
6615
6616 g_once_init_leave (&type, (gsize) _type);
6617 }
6618
6619 return (GType) type;
6620 }
6621
6622 GHashTable *
mxf_metadata_hash_table_new(void)6623 mxf_metadata_hash_table_new (void)
6624 {
6625 return g_hash_table_new_full ((GHashFunc) mxf_uuid_hash,
6626 (GEqualFunc) mxf_uuid_is_equal, (GDestroyNotify) NULL,
6627 (GDestroyNotify) g_object_unref);
6628 }
6629