1 /* GStreamer
2 * Copyright (C) 2008-2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 /* Implementation of SMPTE 382M - Mapping AES3 and Broadcast Wave
21 * Audio into the MXF Generic Container
22 */
23
24 /* TODO:
25 * - Handle the case were a track only references specific channels
26 * of the essence (ChannelID property)
27 * - Add support for more codecs
28 * - Handle more of the metadata inside the descriptors
29 */
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #include <gst/gst.h>
36 #include <gst/audio/audio.h>
37
38 #include <string.h>
39
40 #include "mxfaes-bwf.h"
41 #include "mxfessence.h"
42 #include "mxfquark.h"
43
44 GST_DEBUG_CATEGORY_EXTERN (mxf_debug);
45 #define GST_CAT_DEFAULT mxf_debug
46
47 /* SMPTE 382M Annex 1 */
48 #define MXF_TYPE_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR \
49 (mxf_metadata_wave_audio_essence_descriptor_get_type())
50 #define MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR(obj) \
51 (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR, MXFMetadataWaveAudioEssenceDescriptor))
52 #define MXF_IS_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR(obj) \
53 (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR))
54 typedef struct _MXFMetadataWaveAudioEssenceDescriptor
55 MXFMetadataWaveAudioEssenceDescriptor;
56 typedef MXFMetadataClass MXFMetadataWaveAudioEssenceDescriptorClass;
57 GType mxf_metadata_wave_audio_essence_descriptor_get_type (void);
58
59 struct _MXFMetadataWaveAudioEssenceDescriptor
60 {
61 MXFMetadataGenericSoundEssenceDescriptor parent;
62
63 guint16 block_align;
64 guint8 sequence_offset;
65
66 guint32 avg_bps;
67
68 MXFUL channel_assignment;
69
70 guint32 peak_envelope_version;
71 guint32 peak_envelope_format;
72 guint32 points_per_peak_value;
73 guint32 peak_envelope_block_size;
74 guint32 peak_channels;
75 guint32 peak_frames;
76 gint64 peak_of_peaks_position;
77 MXFTimestamp peak_envelope_timestamp;
78
79 guint8 *peak_envelope_data;
80 guint16 peak_envelope_data_length;
81 };
82
83 /* SMPTE 382M Annex 2 */
84 #define MXF_TYPE_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR \
85 (mxf_metadata_aes3_audio_essence_descriptor_get_type())
86 #define MXF_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR(obj) \
87 (G_TYPE_CHECK_INSTANCE_CAST((obj),MXF_TYPE_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR, MXFMetadataAES3AudioEssenceDescriptor))
88 #define MXF_IS_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR(obj) \
89 (G_TYPE_CHECK_INSTANCE_TYPE((obj),MXF_TYPE_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR))
90 typedef struct _MXFMetadataAES3AudioEssenceDescriptor
91 MXFMetadataAES3AudioEssenceDescriptor;
92 typedef MXFMetadataClass MXFMetadataAES3AudioEssenceDescriptorClass;
93 GType mxf_metadata_aes3_audio_essence_descriptor_get_type (void);
94
95 struct _MXFMetadataAES3AudioEssenceDescriptor
96 {
97 MXFMetadataWaveAudioEssenceDescriptor parent;
98
99 guint8 emphasis;
100 guint16 block_start_offset;
101 guint8 auxiliary_bits_mode;
102
103 guint32 n_channel_status_mode;
104 guint8 *channel_status_mode;
105
106 guint32 n_fixed_channel_status_data;
107 guint8 **fixed_channel_status_data;
108
109 guint32 n_user_data_mode;
110 guint8 *user_data_mode;
111
112 guint32 n_fixed_user_data;
113 guint8 **fixed_user_data;
114
115 guint32 linked_timecode_track_id;
116 guint8 stream_number;
117 };
118
119 /* SMPTE 382M Annex 1 */
120 G_DEFINE_TYPE (MXFMetadataWaveAudioEssenceDescriptor,
121 mxf_metadata_wave_audio_essence_descriptor,
122 MXF_TYPE_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR);
123
124 static gboolean
mxf_metadata_wave_audio_essence_descriptor_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)125 mxf_metadata_wave_audio_essence_descriptor_handle_tag (MXFMetadataBase *
126 metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
127 guint tag_size)
128 {
129 MXFMetadataWaveAudioEssenceDescriptor *self =
130 MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR (metadata);
131 gboolean ret = TRUE;
132 #ifndef GST_DISABLE_GST_DEBUG
133 gchar str[48];
134 #endif
135
136 switch (tag) {
137 case 0x3d0a:
138 if (tag_size != 2)
139 goto error;
140 self->block_align = GST_READ_UINT16_BE (tag_data);
141 GST_DEBUG (" block align = %u", self->block_align);
142 break;
143 case 0x3d0b:
144 if (tag_size != 1)
145 goto error;
146 self->sequence_offset = GST_READ_UINT8 (tag_data);
147 GST_DEBUG (" sequence offset = %u", self->sequence_offset);
148 break;
149 case 0x3d09:
150 if (tag_size != 4)
151 goto error;
152 self->avg_bps = GST_READ_UINT32_BE (tag_data);
153 GST_DEBUG (" average bps = %u", self->avg_bps);
154 break;
155 case 0x3d32:
156 if (tag_size != 16)
157 goto error;
158 memcpy (&self->channel_assignment, tag_data, 16);
159 GST_DEBUG (" channel assignment = %s",
160 mxf_ul_to_string (&self->channel_assignment, str));
161 break;
162 case 0x3d29:
163 if (tag_size != 4)
164 goto error;
165 self->peak_envelope_version = GST_READ_UINT32_BE (tag_data);
166 GST_DEBUG (" peak envelope version = %u", self->peak_envelope_version);
167 break;
168 case 0x3d2a:
169 if (tag_size != 4)
170 goto error;
171 self->peak_envelope_format = GST_READ_UINT32_BE (tag_data);
172 GST_DEBUG (" peak envelope format = %u", self->peak_envelope_format);
173 break;
174 case 0x3d2b:
175 if (tag_size != 4)
176 goto error;
177 self->points_per_peak_value = GST_READ_UINT32_BE (tag_data);
178 GST_DEBUG (" points per peak value = %u", self->points_per_peak_value);
179 break;
180 case 0x3d2c:
181 if (tag_size != 4)
182 goto error;
183 self->peak_envelope_block_size = GST_READ_UINT32_BE (tag_data);
184 GST_DEBUG (" peak envelope block size = %u",
185 self->peak_envelope_block_size);
186 break;
187 case 0x3d2d:
188 if (tag_size != 4)
189 goto error;
190 self->peak_channels = GST_READ_UINT32_BE (tag_data);
191 GST_DEBUG (" peak channels = %u", self->peak_channels);
192 break;
193 case 0x3d2e:
194 if (tag_size != 4)
195 goto error;
196 self->peak_frames = GST_READ_UINT32_BE (tag_data);
197 GST_DEBUG (" peak frames = %u", self->peak_frames);
198 break;
199 case 0x3d2f:
200 if (tag_size != 8)
201 goto error;
202 self->peak_of_peaks_position = GST_READ_UINT64_BE (tag_data);
203 GST_DEBUG (" peak of peaks position = %" G_GINT64_FORMAT,
204 self->peak_of_peaks_position);
205 break;
206 case 0x3d30:
207 if (!mxf_timestamp_parse (&self->peak_envelope_timestamp,
208 tag_data, tag_size))
209 goto error;
210 GST_DEBUG (" peak envelope timestamp = %s",
211 mxf_timestamp_to_string (&self->peak_envelope_timestamp, str));
212 break;
213 case 0x3d31:
214 self->peak_envelope_data = g_memdup2 (tag_data, tag_size);
215 self->peak_envelope_data_length = tag_size;
216 GST_DEBUG (" peak evelope data size = %u",
217 self->peak_envelope_data_length);
218 break;
219 default:
220 ret =
221 MXF_METADATA_BASE_CLASS
222 (mxf_metadata_wave_audio_essence_descriptor_parent_class)->handle_tag
223 (metadata, primer, tag, tag_data, tag_size);
224 break;
225 }
226
227 return ret;
228
229 error:
230
231 GST_ERROR
232 ("Invalid wave audio essence descriptor local tag 0x%04x of size %u", tag,
233 tag_size);
234
235 return FALSE;
236 }
237
238 static GstStructure *
mxf_metadata_wave_audio_essence_descriptor_to_structure(MXFMetadataBase * m)239 mxf_metadata_wave_audio_essence_descriptor_to_structure (MXFMetadataBase * m)
240 {
241 GstStructure *ret =
242 MXF_METADATA_BASE_CLASS
243 (mxf_metadata_wave_audio_essence_descriptor_parent_class)->to_structure
244 (m);
245 MXFMetadataWaveAudioEssenceDescriptor *self =
246 MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR (m);
247 gchar str[48];
248
249 gst_structure_id_set (ret, MXF_QUARK (BLOCK_ALIGN), G_TYPE_UINT,
250 self->block_align, NULL);
251
252 if (self->sequence_offset)
253 gst_structure_id_set (ret, MXF_QUARK (SEQUENCE_OFFSET), G_TYPE_UCHAR,
254 self->sequence_offset, NULL);
255
256 if (self->avg_bps)
257 gst_structure_id_set (ret, MXF_QUARK (AVG_BPS), G_TYPE_UINT, self->avg_bps,
258 NULL);
259
260 if (!mxf_ul_is_zero (&self->channel_assignment)) {
261 gst_structure_id_set (ret, MXF_QUARK (CHANNEL_ASSIGNMENT), G_TYPE_STRING,
262 mxf_ul_to_string (&self->channel_assignment, str), NULL);
263 }
264
265 if (self->peak_envelope_version)
266 gst_structure_id_set (ret, MXF_QUARK (PEAK_ENVELOPE_VERSION), G_TYPE_UINT,
267 self->peak_envelope_version, NULL);
268
269 if (self->peak_envelope_format)
270 gst_structure_id_set (ret, MXF_QUARK (PEAK_ENVELOPE_FORMAT), G_TYPE_UINT,
271 self->peak_envelope_format, NULL);
272
273 if (self->points_per_peak_value)
274 gst_structure_id_set (ret, MXF_QUARK (POINTS_PER_PEAK_VALUE), G_TYPE_UINT,
275 self->points_per_peak_value, NULL);
276
277 if (self->peak_envelope_block_size)
278 gst_structure_id_set (ret, MXF_QUARK (PEAK_ENVELOPE_BLOCK_SIZE),
279 G_TYPE_UINT, self->peak_envelope_block_size, NULL);
280
281 if (self->peak_channels)
282 gst_structure_id_set (ret, MXF_QUARK (PEAK_CHANNELS), G_TYPE_UINT,
283 self->peak_channels, NULL);
284
285 if (self->peak_frames)
286 gst_structure_id_set (ret, MXF_QUARK (PEAK_FRAMES), G_TYPE_UINT,
287 self->peak_frames, NULL);
288
289 if (self->peak_of_peaks_position)
290 gst_structure_id_set (ret, MXF_QUARK (PEAK_OF_PEAKS_POSITION), G_TYPE_INT64,
291 self->peak_of_peaks_position, NULL);
292
293 if (!mxf_timestamp_is_unknown (&self->peak_envelope_timestamp))
294 gst_structure_id_set (ret, MXF_QUARK (PEAK_ENVELOPE_TIMESTAMP),
295 G_TYPE_STRING, mxf_timestamp_to_string (&self->peak_envelope_timestamp,
296 str), NULL);
297
298 if (self->peak_envelope_data) {
299 GstBuffer *buf = gst_buffer_new_and_alloc (self->peak_envelope_data_length);
300 GstMapInfo map;
301
302 gst_buffer_map (buf, &map, GST_MAP_WRITE);
303 memcpy (map.data, self->peak_envelope_data,
304 self->peak_envelope_data_length);
305 gst_buffer_unmap (buf, &map);
306 gst_structure_id_set (ret, MXF_QUARK (PEAK_ENVELOPE_DATA), GST_TYPE_BUFFER,
307 buf, NULL);
308 gst_buffer_unref (buf);
309 }
310
311 return ret;
312 }
313
314 static GList *
mxf_metadata_wave_audio_essence_descriptor_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)315 mxf_metadata_wave_audio_essence_descriptor_write_tags (MXFMetadataBase * m,
316 MXFPrimerPack * primer)
317 {
318 MXFMetadataWaveAudioEssenceDescriptor *self =
319 MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR (m);
320 GList *ret =
321 MXF_METADATA_BASE_CLASS
322 (mxf_metadata_wave_audio_essence_descriptor_parent_class)->write_tags (m,
323 primer);
324 MXFLocalTag *t;
325 static const guint8 block_align_ul[] = {
326 0x06, 0x0E, 0x2B, 0x34, 0x01, 0x01, 0x01, 0x05,
327 0x04, 0x02, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00
328 };
329 static const guint8 sequence_offset_ul[] = {
330 0x06, 0x0E, 0x2B, 0x34, 0x01, 0x01, 0x01, 0x05,
331 0x04, 0x02, 0x03, 0x02, 0x02, 0x00, 0x00, 0x00
332 };
333 static const guint8 avg_bps_ul[] = {
334 0x06, 0x0E, 0x2B, 0x34, 0x01, 0x01, 0x01, 0x05,
335 0x04, 0x02, 0x03, 0x03, 0x05, 0x00, 0x00, 0x00
336 };
337 static const guint8 channel_assignment_ul[] = {
338 0x06, 0x0E, 0x2B, 0x34, 0x01, 0x01, 0x01, 0x07,
339 0x04, 0x02, 0x01, 0x01, 0x05, 0x00, 0x00, 0x00
340 };
341 static const guint8 peak_envelope_version_ul[] = {
342 0x06, 0x0E, 0x2B, 0x34, 0x01, 0x01, 0x01, 0x08,
343 0x04, 0x02, 0x03, 0x01, 0x06, 0x00, 0x00, 0x00
344 };
345 static const guint8 peak_envelope_format_ul[] = {
346 0x06, 0x0E, 0x2B, 0x34, 0x01, 0x01, 0x01, 0x08,
347 0x04, 0x02, 0x03, 0x01, 0x07, 0x00, 0x00, 0x00
348 };
349 static const guint8 points_per_peak_value_ul[] = {
350 0x06, 0x0E, 0x2B, 0x34, 0x01, 0x01, 0x01, 0x08,
351 0x04, 0x02, 0x03, 0x01, 0x08, 0x00, 0x00, 0x00
352 };
353 static const guint8 peak_envelope_block_size_ul[] = {
354 0x06, 0x0E, 0x2B, 0x34, 0x01, 0x01, 0x01, 0x08,
355 0x04, 0x02, 0x03, 0x01, 0x09, 0x00, 0x00, 0x00
356 };
357 static const guint8 peak_channels_ul[] = {
358 0x06, 0x0E, 0x2B, 0x34, 0x01, 0x01, 0x01, 0x08,
359 0x04, 0x02, 0x03, 0x01, 0x0A, 0x00, 0x00, 0x00
360 };
361 static const guint8 peak_frames_ul[] = {
362 0x06, 0x0E, 0x2B, 0x34, 0x01, 0x01, 0x01, 0x08,
363 0x04, 0x02, 0x03, 0x01, 0x0B, 0x00, 0x00, 0x00
364 };
365 static const guint8 peak_of_peaks_position_ul[] = {
366 0x06, 0x0E, 0x2B, 0x34, 0x01, 0x01, 0x01, 0x08,
367 0x04, 0x02, 0x03, 0x01, 0x0C, 0x00, 0x00, 0x00
368 };
369 static const guint8 peak_envelope_timestamp_ul[] = {
370 0x06, 0x0E, 0x2B, 0x34, 0x01, 0x01, 0x01, 0x08,
371 0x04, 0x02, 0x03, 0x01, 0x0D, 0x00, 0x00, 0x00
372 };
373 static const guint8 peak_envelope_data_ul[] = {
374 0x06, 0x0E, 0x2B, 0x34, 0x01, 0x01, 0x01, 0x08,
375 0x04, 0x02, 0x03, 0x01, 0x0E, 0x00, 0x00, 0x00
376 };
377
378 t = g_slice_new0 (MXFLocalTag);
379 memcpy (&t->ul, &block_align_ul, 16);
380 t->size = 2;
381 t->data = g_slice_alloc (t->size);
382 t->g_slice = TRUE;
383 GST_WRITE_UINT16_BE (t->data, self->block_align);
384 mxf_primer_pack_add_mapping (primer, 0x3d0a, &t->ul);
385 ret = g_list_prepend (ret, t);
386
387 if (self->sequence_offset) {
388 t = g_slice_new0 (MXFLocalTag);
389 memcpy (&t->ul, &sequence_offset_ul, 16);
390 t->size = 1;
391 t->data = g_slice_alloc (t->size);
392 t->g_slice = TRUE;
393 GST_WRITE_UINT8 (t->data, self->sequence_offset);
394 mxf_primer_pack_add_mapping (primer, 0x3d0b, &t->ul);
395 ret = g_list_prepend (ret, t);
396 }
397
398 t = g_slice_new0 (MXFLocalTag);
399 memcpy (&t->ul, &avg_bps_ul, 16);
400 t->size = 4;
401 t->data = g_slice_alloc (t->size);
402 t->g_slice = TRUE;
403 GST_WRITE_UINT32_BE (t->data, self->avg_bps);
404 mxf_primer_pack_add_mapping (primer, 0x3d09, &t->ul);
405 ret = g_list_prepend (ret, t);
406
407 if (!mxf_ul_is_zero (&self->channel_assignment)) {
408 t = g_slice_new0 (MXFLocalTag);
409 memcpy (&t->ul, &channel_assignment_ul, 16);
410 t->size = 16;
411 t->data = g_slice_alloc (t->size);
412 t->g_slice = TRUE;
413 memcpy (t->data, &self->channel_assignment, 16);
414 mxf_primer_pack_add_mapping (primer, 0x3d32, &t->ul);
415 ret = g_list_prepend (ret, t);
416 }
417
418 if (self->peak_envelope_version) {
419 t = g_slice_new0 (MXFLocalTag);
420 memcpy (&t->ul, &peak_envelope_version_ul, 16);
421 t->size = 4;
422 t->data = g_slice_alloc (t->size);
423 t->g_slice = TRUE;
424 GST_WRITE_UINT32_BE (t->data, self->peak_envelope_version);
425 mxf_primer_pack_add_mapping (primer, 0x3d29, &t->ul);
426 ret = g_list_prepend (ret, t);
427 }
428
429 if (self->peak_envelope_format) {
430 t = g_slice_new0 (MXFLocalTag);
431 memcpy (&t->ul, &peak_envelope_format_ul, 16);
432 t->size = 4;
433 t->data = g_slice_alloc (t->size);
434 t->g_slice = TRUE;
435 GST_WRITE_UINT32_BE (t->data, self->peak_envelope_format);
436 mxf_primer_pack_add_mapping (primer, 0x3d2a, &t->ul);
437 ret = g_list_prepend (ret, t);
438 }
439
440 if (self->points_per_peak_value) {
441 t = g_slice_new0 (MXFLocalTag);
442 memcpy (&t->ul, &points_per_peak_value_ul, 16);
443 t->size = 4;
444 t->data = g_slice_alloc (t->size);
445 t->g_slice = TRUE;
446 GST_WRITE_UINT32_BE (t->data, self->points_per_peak_value);
447 mxf_primer_pack_add_mapping (primer, 0x3d2b, &t->ul);
448 ret = g_list_prepend (ret, t);
449 }
450
451 if (self->peak_envelope_block_size) {
452 t = g_slice_new0 (MXFLocalTag);
453 memcpy (&t->ul, &peak_envelope_block_size_ul, 16);
454 t->size = 4;
455 t->data = g_slice_alloc (t->size);
456 t->g_slice = TRUE;
457 GST_WRITE_UINT32_BE (t->data, self->peak_envelope_block_size);
458 mxf_primer_pack_add_mapping (primer, 0x3d2c, &t->ul);
459 ret = g_list_prepend (ret, t);
460 }
461
462 if (self->peak_channels) {
463 t = g_slice_new0 (MXFLocalTag);
464 memcpy (&t->ul, &peak_channels_ul, 16);
465 t->size = 4;
466 t->data = g_slice_alloc (t->size);
467 t->g_slice = TRUE;
468 GST_WRITE_UINT32_BE (t->data, self->peak_channels);
469 mxf_primer_pack_add_mapping (primer, 0x3d2d, &t->ul);
470 ret = g_list_prepend (ret, t);
471 }
472
473 if (self->peak_frames) {
474 t = g_slice_new0 (MXFLocalTag);
475 memcpy (&t->ul, &peak_frames_ul, 16);
476 t->size = 4;
477 t->data = g_slice_alloc (t->size);
478 t->g_slice = TRUE;
479 GST_WRITE_UINT32_BE (t->data, self->peak_frames);
480 mxf_primer_pack_add_mapping (primer, 0x3d2e, &t->ul);
481 ret = g_list_prepend (ret, t);
482 }
483
484 if (self->peak_of_peaks_position) {
485 t = g_slice_new0 (MXFLocalTag);
486 memcpy (&t->ul, &peak_of_peaks_position_ul, 16);
487 t->size = 8;
488 t->data = g_slice_alloc (t->size);
489 t->g_slice = TRUE;
490 GST_WRITE_UINT64_BE (t->data, self->peak_of_peaks_position);
491 mxf_primer_pack_add_mapping (primer, 0x3d2f, &t->ul);
492 ret = g_list_prepend (ret, t);
493 }
494
495 if (!mxf_timestamp_is_unknown (&self->peak_envelope_timestamp)) {
496 t = g_slice_new0 (MXFLocalTag);
497 memcpy (&t->ul, &peak_envelope_timestamp_ul, 16);
498 t->size = 8;
499 t->data = g_slice_alloc (t->size);
500 t->g_slice = TRUE;
501 mxf_timestamp_write (&self->peak_envelope_timestamp, t->data);
502 mxf_primer_pack_add_mapping (primer, 0x3d30, &t->ul);
503 ret = g_list_prepend (ret, t);
504 }
505
506 if (self->peak_envelope_data) {
507 t = g_slice_new0 (MXFLocalTag);
508 memcpy (&t->ul, &peak_envelope_data_ul, 16);
509 t->size = self->peak_envelope_data_length;
510 t->data = g_memdup2 (self->peak_envelope_data, t->size);
511 mxf_primer_pack_add_mapping (primer, 0x3d31, &t->ul);
512 ret = g_list_prepend (ret, t);
513 }
514
515 return ret;
516 }
517
518 static void
mxf_metadata_wave_audio_essence_descriptor_init(MXFMetadataWaveAudioEssenceDescriptor * self)519 mxf_metadata_wave_audio_essence_descriptor_init
520 (MXFMetadataWaveAudioEssenceDescriptor * self)
521 {
522
523 }
524
525 static void
mxf_metadata_wave_audio_essence_descriptor_class_init(MXFMetadataWaveAudioEssenceDescriptorClass * klass)526 mxf_metadata_wave_audio_essence_descriptor_class_init
527 (MXFMetadataWaveAudioEssenceDescriptorClass * klass)
528 {
529 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
530 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
531
532 metadata_base_class->handle_tag =
533 mxf_metadata_wave_audio_essence_descriptor_handle_tag;
534 metadata_base_class->name_quark = MXF_QUARK (WAVE_AUDIO_ESSENCE_DESCRIPTOR);
535 metadata_base_class->to_structure =
536 mxf_metadata_wave_audio_essence_descriptor_to_structure;
537 metadata_base_class->write_tags =
538 mxf_metadata_wave_audio_essence_descriptor_write_tags;
539 metadata_class->type = 0x0148;
540 }
541
542 /* SMPTE 382M Annex 2 */
543 G_DEFINE_TYPE (MXFMetadataAES3AudioEssenceDescriptor,
544 mxf_metadata_aes3_audio_essence_descriptor,
545 MXF_TYPE_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR);
546
547 static void
mxf_metadata_aes3_audio_essence_descriptor_finalize(GObject * object)548 mxf_metadata_aes3_audio_essence_descriptor_finalize (GObject * object)
549 {
550 MXFMetadataAES3AudioEssenceDescriptor *self =
551 MXF_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR (object);
552
553 g_free (self->channel_status_mode);
554 self->channel_status_mode = NULL;
555 g_free (self->fixed_channel_status_data);
556 self->fixed_channel_status_data = NULL;
557 g_free (self->user_data_mode);
558 self->user_data_mode = NULL;
559 g_free (self->fixed_user_data);
560 self->fixed_user_data = NULL;
561
562 G_OBJECT_CLASS
563 (mxf_metadata_aes3_audio_essence_descriptor_parent_class)->finalize
564 (object);
565 }
566
567 static gboolean
mxf_metadata_aes3_audio_essence_descriptor_handle_tag(MXFMetadataBase * metadata,MXFPrimerPack * primer,guint16 tag,const guint8 * tag_data,guint tag_size)568 mxf_metadata_aes3_audio_essence_descriptor_handle_tag (MXFMetadataBase *
569 metadata, MXFPrimerPack * primer, guint16 tag, const guint8 * tag_data,
570 guint tag_size)
571 {
572 MXFMetadataAES3AudioEssenceDescriptor *self =
573 MXF_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR (metadata);
574 gboolean ret = TRUE;
575
576 switch (tag) {
577 case 0x3d0d:
578 if (tag_size != 1)
579 goto error;
580 self->emphasis = GST_READ_UINT8 (tag_data);
581 GST_DEBUG (" emphasis = %u", self->emphasis);
582 break;
583 case 0x3d0f:
584 if (tag_size != 2)
585 goto error;
586 self->block_start_offset = GST_READ_UINT16_BE (tag_data);
587 GST_DEBUG (" block start offset = %u", self->block_start_offset);
588 break;
589 case 0x3d08:
590 if (tag_size != 1)
591 goto error;
592 self->auxiliary_bits_mode = GST_READ_UINT8 (tag_data);
593 GST_DEBUG (" auxiliary bits mode = %u", self->auxiliary_bits_mode);
594 break;
595 case 0x3d10:{
596 guint32 len;
597 guint i;
598
599 if (tag_size < 8)
600 goto error;
601 len = GST_READ_UINT32_BE (tag_data);
602 GST_DEBUG (" number of channel status mode = %u", len);
603 self->n_channel_status_mode = len;
604 if (len == 0)
605 return TRUE;
606
607 if (GST_READ_UINT32_BE (tag_data + 4) != 1)
608 goto error;
609
610 tag_data += 8;
611 tag_size -= 8;
612
613 if (tag_size != len)
614 goto error;
615
616 self->channel_status_mode = g_new0 (guint8, len);
617
618 for (i = 0; i < len; i++) {
619 self->channel_status_mode[i] = GST_READ_UINT8 (tag_data);
620 GST_DEBUG (" channel status mode %u = %u", i,
621 self->channel_status_mode[i]);
622 tag_data++;
623 tag_size--;
624 }
625
626 break;
627 }
628 case 0x3d11:{
629 guint32 len;
630 guint i;
631
632 if (tag_size < 8)
633 goto error;
634 len = GST_READ_UINT32_BE (tag_data);
635 GST_DEBUG (" number of fixed channel status data = %u", len);
636 self->n_fixed_channel_status_data = len;
637 if (len == 0)
638 return TRUE;
639
640 if (GST_READ_UINT32_BE (tag_data + 4) != 24)
641 goto error;
642
643 tag_data += 8;
644 tag_size -= 8;
645
646 if (tag_size / 24 != len)
647 goto error;
648
649 if (G_MAXINT / (24 + sizeof (guint8 *)) < len)
650 goto error;
651
652 self->fixed_channel_status_data =
653 g_malloc0 (len * (sizeof (guint8 *) + 24));
654
655 for (i = 0; i < len; i++) {
656 self->fixed_channel_status_data[i] =
657 ((guint8 *) self->fixed_channel_status_data) +
658 len * sizeof (guint8 *) + i * 24;
659
660 memcpy (self->fixed_channel_status_data[i], tag_data, 24);
661 GST_DEBUG
662 (" fixed channel status data %u = 0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x",
663 i, self->fixed_channel_status_data[i][0],
664 self->fixed_channel_status_data[i][1],
665 self->fixed_channel_status_data[i][2],
666 self->fixed_channel_status_data[i][3],
667 self->fixed_channel_status_data[i][4],
668 self->fixed_channel_status_data[i][5],
669 self->fixed_channel_status_data[i][6],
670 self->fixed_channel_status_data[i][7],
671 self->fixed_channel_status_data[i][8],
672 self->fixed_channel_status_data[i][9],
673 self->fixed_channel_status_data[i][10],
674 self->fixed_channel_status_data[i][11],
675 self->fixed_channel_status_data[i][12],
676 self->fixed_channel_status_data[i][13],
677 self->fixed_channel_status_data[i][14],
678 self->fixed_channel_status_data[i][15],
679 self->fixed_channel_status_data[i][16],
680 self->fixed_channel_status_data[i][17],
681 self->fixed_channel_status_data[i][18],
682 self->fixed_channel_status_data[i][19],
683 self->fixed_channel_status_data[i][20],
684 self->fixed_channel_status_data[i][21],
685 self->fixed_channel_status_data[i][22],
686 self->fixed_channel_status_data[i][23]
687 );
688 tag_data += 24;
689 tag_size -= 24;
690 }
691
692 break;
693 }
694 case 0x3d12:{
695 guint32 len;
696 guint i;
697
698 if (tag_size < 8)
699 goto error;
700 len = GST_READ_UINT32_BE (tag_data);
701 GST_DEBUG (" number of user data mode = %u", len);
702 self->n_user_data_mode = len;
703 if (len == 0)
704 return TRUE;
705
706 if (GST_READ_UINT32_BE (tag_data + 4) != 1)
707 goto error;
708
709 tag_data += 8;
710 tag_size -= 8;
711
712 if (tag_size != len)
713 goto error;
714
715 self->user_data_mode = g_new0 (guint8, len);
716
717 for (i = 0; i < len; i++) {
718 self->user_data_mode[i] = GST_READ_UINT8 (tag_data);
719 GST_DEBUG (" user data mode %u = %u", i, self->user_data_mode[i]);
720 tag_data++;
721 tag_size--;
722 }
723
724 break;
725 }
726 case 0x3d13:{
727 guint32 len;
728 guint i;
729
730 if (tag_size < 8)
731 goto error;
732 len = GST_READ_UINT32_BE (tag_data);
733 GST_DEBUG (" number of fixed user data = %u", len);
734 self->n_fixed_user_data = len;
735 if (len == 0)
736 return TRUE;
737
738 if (GST_READ_UINT32_BE (tag_data + 4) != 24)
739 goto error;
740
741 tag_data += 8;
742 tag_size -= 8;
743
744 if (tag_size / 24 != len)
745 goto error;
746
747 if (G_MAXINT / (24 + sizeof (guint8 *)) < len)
748 goto error;
749
750 self->fixed_user_data = g_malloc0 (len * (sizeof (guint8 *) + 24));
751
752 for (i = 0; i < len; i++) {
753 self->fixed_user_data[i] =
754 ((guint8 *) self->fixed_user_data) + len * sizeof (guint8 *) +
755 i * 24;
756
757 memcpy (self->fixed_user_data[i], tag_data, 24);
758 GST_DEBUG
759 (" fixed user data %u = 0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x.0x%02x",
760 i, self->fixed_user_data[i][0],
761 self->fixed_user_data[i][1],
762 self->fixed_user_data[i][2],
763 self->fixed_user_data[i][3],
764 self->fixed_user_data[i][4],
765 self->fixed_user_data[i][5],
766 self->fixed_user_data[i][6],
767 self->fixed_user_data[i][7],
768 self->fixed_user_data[i][8],
769 self->fixed_user_data[i][9],
770 self->fixed_user_data[i][10],
771 self->fixed_user_data[i][11],
772 self->fixed_user_data[i][12],
773 self->fixed_user_data[i][13],
774 self->fixed_user_data[i][14],
775 self->fixed_user_data[i][15],
776 self->fixed_user_data[i][16],
777 self->fixed_user_data[i][17],
778 self->fixed_user_data[i][18],
779 self->fixed_user_data[i][19],
780 self->fixed_user_data[i][20],
781 self->fixed_user_data[i][21],
782 self->fixed_user_data[i][22], self->fixed_user_data[i][23]
783 );
784 tag_data += 24;
785 tag_size -= 24;
786 }
787
788 break;
789 }
790 /* TODO: linked timecode track / data_stream_number parsing, see
791 * SMPTE 382M Annex 2 */
792 default:
793 ret =
794 MXF_METADATA_BASE_CLASS
795 (mxf_metadata_aes3_audio_essence_descriptor_parent_class)->handle_tag
796 (metadata, primer, tag, tag_data, tag_size);
797 break;
798 }
799
800 return ret;
801
802 error:
803
804 GST_ERROR
805 ("Invalid AES3 audio essence descriptor local tag 0x%04x of size %u", tag,
806 tag_size);
807
808 return FALSE;
809 }
810
811 static GstStructure *
mxf_metadata_aes3_audio_essence_descriptor_to_structure(MXFMetadataBase * m)812 mxf_metadata_aes3_audio_essence_descriptor_to_structure (MXFMetadataBase * m)
813 {
814 GstStructure *ret =
815 MXF_METADATA_BASE_CLASS
816 (mxf_metadata_aes3_audio_essence_descriptor_parent_class)->to_structure
817 (m);
818 MXFMetadataAES3AudioEssenceDescriptor *self =
819 MXF_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR (m);
820
821 if (self->emphasis)
822 gst_structure_id_set (ret, MXF_QUARK (EMPHASIS), G_TYPE_UCHAR,
823 self->emphasis, NULL);
824
825 if (self->block_start_offset)
826 gst_structure_id_set (ret, MXF_QUARK (BLOCK_START_OFFSET), G_TYPE_UINT,
827 self->block_start_offset, NULL);
828
829 if (self->auxiliary_bits_mode)
830 gst_structure_id_set (ret, MXF_QUARK (AUXILIARY_BITS_MODE), G_TYPE_UCHAR,
831 self->auxiliary_bits_mode, NULL);
832
833 if (self->channel_status_mode) {
834 GstBuffer *buf = gst_buffer_new_and_alloc (self->n_channel_status_mode);
835 GstMapInfo map;
836
837 gst_buffer_map (buf, &map, GST_MAP_WRITE);
838 memcpy (map.data, self->channel_status_mode, self->n_channel_status_mode);
839 gst_buffer_unmap (buf, &map);
840 gst_structure_id_set (ret, MXF_QUARK (CHANNEL_STATUS_MODE), GST_TYPE_BUFFER,
841 buf, NULL);
842 gst_buffer_unref (buf);
843 }
844
845 if (self->channel_status_mode) {
846 GstBuffer *buf = gst_buffer_new_and_alloc (self->n_channel_status_mode);
847 GstMapInfo map;
848
849 gst_buffer_map (buf, &map, GST_MAP_WRITE);
850 memcpy (map.data, self->channel_status_mode, self->n_channel_status_mode);
851 gst_buffer_unmap (buf, &map);
852 gst_structure_id_set (ret, MXF_QUARK (CHANNEL_STATUS_MODE), GST_TYPE_BUFFER,
853 buf, NULL);
854 gst_buffer_unref (buf);
855 }
856
857 if (self->fixed_channel_status_data) {
858 guint i;
859 GValue va = { 0, }
860 , v = {
861 0,};
862 GstBuffer *buf;
863 GstMapInfo map;
864
865 g_value_init (&va, GST_TYPE_ARRAY);
866
867 for (i = 0; i < self->n_fixed_channel_status_data; i++) {
868 buf = gst_buffer_new_and_alloc (24);
869 g_value_init (&v, GST_TYPE_BUFFER);
870
871 gst_buffer_map (buf, &map, GST_MAP_WRITE);
872 memcpy (map.data, self->fixed_channel_status_data[i], 24);
873 gst_buffer_unmap (buf, &map);
874 gst_value_set_buffer (&v, buf);
875 gst_value_array_append_value (&va, &v);
876 gst_buffer_unref (buf);
877 g_value_unset (&v);
878 }
879
880 if (gst_value_array_get_size (&va) > 0)
881 gst_structure_id_set_value (ret, MXF_QUARK (FIXED_CHANNEL_STATUS_DATA),
882 &va);
883 g_value_unset (&va);
884 }
885
886
887 if (self->user_data_mode) {
888 GstBuffer *buf = gst_buffer_new_and_alloc (self->n_user_data_mode);
889 GstMapInfo map;
890
891 gst_buffer_map (buf, &map, GST_MAP_WRITE);
892 memcpy (map.data, self->user_data_mode, self->n_user_data_mode);
893 gst_buffer_unmap (buf, &map);
894 gst_structure_id_set (ret, MXF_QUARK (USER_DATA_MODE), GST_TYPE_BUFFER, buf,
895 NULL);
896 gst_buffer_unref (buf);
897 }
898
899 if (self->fixed_user_data) {
900 guint i;
901 GValue va = { 0, }
902 , v = {
903 0,};
904 GstBuffer *buf;
905 GstMapInfo map;
906
907 g_value_init (&va, GST_TYPE_ARRAY);
908
909 for (i = 0; i < self->n_fixed_user_data; i++) {
910 buf = gst_buffer_new_and_alloc (24);
911 g_value_init (&v, GST_TYPE_BUFFER);
912
913 gst_buffer_map (buf, &map, GST_MAP_WRITE);
914 memcpy (map.data, self->fixed_user_data[i], 24);
915 gst_buffer_unmap (buf, &map);
916 gst_value_set_buffer (&v, buf);
917 gst_value_array_append_value (&va, &v);
918 gst_buffer_unref (buf);
919 g_value_unset (&v);
920 }
921
922 if (gst_value_array_get_size (&va) > 0)
923 gst_structure_id_set_value (ret, MXF_QUARK (FIXED_USER_DATA), &va);
924 g_value_unset (&va);
925 }
926
927 if (self->linked_timecode_track_id)
928 gst_structure_id_set (ret, MXF_QUARK (LINKED_TIMECODE_TRACK_ID),
929 G_TYPE_UINT, self->linked_timecode_track_id, NULL);
930
931 if (self->stream_number)
932 gst_structure_id_set (ret, MXF_QUARK (STREAM_NUMBER), G_TYPE_UCHAR,
933 self->stream_number, NULL);
934
935 return ret;
936 }
937
938 static GList *
mxf_metadata_aes3_audio_essence_descriptor_write_tags(MXFMetadataBase * m,MXFPrimerPack * primer)939 mxf_metadata_aes3_audio_essence_descriptor_write_tags (MXFMetadataBase * m,
940 MXFPrimerPack * primer)
941 {
942 MXFMetadataAES3AudioEssenceDescriptor *self =
943 MXF_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR (m);
944 GList *ret =
945 MXF_METADATA_BASE_CLASS
946 (mxf_metadata_aes3_audio_essence_descriptor_parent_class)->write_tags (m,
947 primer);
948 MXFLocalTag *t;
949 static const guint8 emphasis_ul[] = {
950 0x06, 0x0E, 0x2B, 0x34, 0x01, 0x01, 0x01, 0x05,
951 0x04, 0x02, 0x05, 0x01, 0x06, 0x00, 0x00, 0x00
952 };
953 static const guint8 block_start_offset_ul[] = {
954 0x06, 0x0E, 0x2B, 0x34, 0x01, 0x01, 0x01, 0x05,
955 0x04, 0x02, 0x03, 0x02, 0x03, 0x00, 0x00, 0x00
956 };
957 static const guint8 auxiliary_bits_mode_ul[] = {
958 0x06, 0x0E, 0x2B, 0x34, 0x01, 0x01, 0x01, 0x05,
959 0x04, 0x02, 0x05, 0x01, 0x01, 0x00, 0x00, 0x00
960 };
961 static const guint8 channel_status_mode_ul[] = {
962 0x06, 0x0E, 0x2B, 0x34, 0x01, 0x01, 0x01, 0x05,
963 0x04, 0x02, 0x05, 0x01, 0x02, 0x00, 0x00, 0x00
964 };
965 static const guint8 fixed_channel_status_data_ul[] = {
966 0x06, 0x0E, 0x2B, 0x34, 0x01, 0x01, 0x01, 0x05,
967 0x04, 0x02, 0x05, 0x01, 0x03, 0x00, 0x00, 0x00
968 };
969 static const guint8 user_data_mode_ul[] = {
970 0x06, 0x0E, 0x2B, 0x34, 0x01, 0x01, 0x01, 0x05,
971 0x04, 0x02, 0x05, 0x01, 0x04, 0x00, 0x00, 0x00
972 };
973 static const guint8 fixed_user_data_ul[] = {
974 0x06, 0x0E, 0x2B, 0x34, 0x01, 0x01, 0x01, 0x05,
975 0x04, 0x02, 0x05, 0x01, 0x05, 0x00, 0x00, 0x00
976 };
977
978 if (self->emphasis) {
979 t = g_slice_new0 (MXFLocalTag);
980 memcpy (&t->ul, &emphasis_ul, 16);
981 t->size = 1;
982 t->data = g_slice_alloc (t->size);
983 t->g_slice = TRUE;
984 GST_WRITE_UINT8 (t->data, self->emphasis);
985 mxf_primer_pack_add_mapping (primer, 0x3d0d, &t->ul);
986 ret = g_list_prepend (ret, t);
987 }
988
989 if (self->block_start_offset) {
990 t = g_slice_new0 (MXFLocalTag);
991 memcpy (&t->ul, &block_start_offset_ul, 16);
992 t->size = 2;
993 t->data = g_slice_alloc (t->size);
994 t->g_slice = TRUE;
995 GST_WRITE_UINT16_BE (t->data, self->block_start_offset);
996 mxf_primer_pack_add_mapping (primer, 0x3d0f, &t->ul);
997 ret = g_list_prepend (ret, t);
998 }
999
1000 if (self->auxiliary_bits_mode) {
1001 t = g_slice_new0 (MXFLocalTag);
1002 memcpy (&t->ul, &auxiliary_bits_mode_ul, 16);
1003 t->size = 1;
1004 t->data = g_slice_alloc (t->size);
1005 t->g_slice = TRUE;
1006 GST_WRITE_UINT8 (t->data, self->auxiliary_bits_mode);
1007 mxf_primer_pack_add_mapping (primer, 0x3d08, &t->ul);
1008 ret = g_list_prepend (ret, t);
1009 }
1010
1011 if (self->channel_status_mode) {
1012 t = g_slice_new0 (MXFLocalTag);
1013 memcpy (&t->ul, &channel_status_mode_ul, 16);
1014 t->size = 8 + self->n_channel_status_mode;
1015 t->data = g_slice_alloc (t->size);
1016 t->g_slice = TRUE;
1017 GST_WRITE_UINT32_BE (t->data, self->n_channel_status_mode);
1018 GST_WRITE_UINT32_BE (t->data + 4, 1);
1019 memcpy (t->data + 8, self->channel_status_mode, t->size);
1020 mxf_primer_pack_add_mapping (primer, 0x3d10, &t->ul);
1021 ret = g_list_prepend (ret, t);
1022 }
1023
1024 if (self->fixed_channel_status_data) {
1025 guint i;
1026
1027 t = g_slice_new0 (MXFLocalTag);
1028 memcpy (&t->ul, &fixed_channel_status_data_ul, 16);
1029 t->size = 8 + 24 * self->n_fixed_channel_status_data;
1030 t->data = g_slice_alloc (t->size);
1031 t->g_slice = TRUE;
1032 GST_WRITE_UINT32_BE (t->data, self->n_fixed_channel_status_data);
1033 GST_WRITE_UINT32_BE (t->data + 4, 24);
1034 for (i = 0; i < self->n_fixed_channel_status_data; i++)
1035 memcpy (t->data + 8 + 24 * i, self->fixed_channel_status_data[i], 24);
1036 mxf_primer_pack_add_mapping (primer, 0x3d11, &t->ul);
1037 ret = g_list_prepend (ret, t);
1038 }
1039
1040 if (self->user_data_mode) {
1041 t = g_slice_new0 (MXFLocalTag);
1042 memcpy (&t->ul, &user_data_mode_ul, 16);
1043 t->size = 8 + self->n_user_data_mode;
1044 t->data = g_slice_alloc (t->size);
1045 t->g_slice = TRUE;
1046 GST_WRITE_UINT32_BE (t->data, self->n_user_data_mode);
1047 GST_WRITE_UINT32_BE (t->data + 4, 1);
1048 memcpy (t->data + 8, self->user_data_mode, t->size);
1049 mxf_primer_pack_add_mapping (primer, 0x3d12, &t->ul);
1050 ret = g_list_prepend (ret, t);
1051 }
1052
1053 if (self->fixed_user_data) {
1054 guint i;
1055
1056 t = g_slice_new0 (MXFLocalTag);
1057 memcpy (&t->ul, &fixed_user_data_ul, 16);
1058 t->size = 8 + 24 * self->n_fixed_user_data;
1059 t->data = g_slice_alloc (t->size);
1060 t->g_slice = TRUE;
1061 GST_WRITE_UINT32_BE (t->data, self->n_fixed_user_data);
1062 GST_WRITE_UINT32_BE (t->data + 4, 24);
1063 for (i = 0; i < self->n_fixed_user_data; i++)
1064 memcpy (t->data + 8 + 24 * i, self->fixed_user_data[i], 24);
1065 mxf_primer_pack_add_mapping (primer, 0x3d11, &t->ul);
1066 ret = g_list_prepend (ret, t);
1067 }
1068
1069 return ret;
1070 }
1071
1072 static void
mxf_metadata_aes3_audio_essence_descriptor_init(MXFMetadataAES3AudioEssenceDescriptor * self)1073 mxf_metadata_aes3_audio_essence_descriptor_init
1074 (MXFMetadataAES3AudioEssenceDescriptor * self)
1075 {
1076
1077 }
1078
1079 static void
mxf_metadata_aes3_audio_essence_descriptor_class_init(MXFMetadataAES3AudioEssenceDescriptorClass * klass)1080 mxf_metadata_aes3_audio_essence_descriptor_class_init
1081 (MXFMetadataAES3AudioEssenceDescriptorClass * klass)
1082 {
1083 MXFMetadataBaseClass *metadata_base_class = (MXFMetadataBaseClass *) klass;
1084 GObjectClass *object_class = (GObjectClass *) klass;
1085 MXFMetadataClass *metadata_class = (MXFMetadataClass *) klass;
1086
1087 object_class->finalize = mxf_metadata_aes3_audio_essence_descriptor_finalize;
1088 metadata_base_class->handle_tag =
1089 mxf_metadata_aes3_audio_essence_descriptor_handle_tag;
1090 metadata_base_class->name_quark = MXF_QUARK (AES3_AUDIO_ESSENCE_DESCRIPTOR);
1091 metadata_base_class->to_structure =
1092 mxf_metadata_aes3_audio_essence_descriptor_to_structure;
1093 metadata_base_class->write_tags =
1094 mxf_metadata_aes3_audio_essence_descriptor_write_tags;
1095 metadata_class->type = 0x0147;
1096 }
1097
1098 static gboolean
mxf_is_aes_bwf_essence_track(const MXFMetadataTimelineTrack * track)1099 mxf_is_aes_bwf_essence_track (const MXFMetadataTimelineTrack * track)
1100 {
1101 guint i;
1102
1103 g_return_val_if_fail (track != NULL, FALSE);
1104
1105 if (track->parent.descriptor == NULL) {
1106 GST_ERROR ("No descriptor for this track");
1107 return FALSE;
1108 }
1109
1110 for (i = 0; i < track->parent.n_descriptor; i++) {
1111 MXFMetadataFileDescriptor *d = track->parent.descriptor[i];
1112 MXFUL *key;
1113
1114 if (!d)
1115 continue;
1116
1117 key = &d->essence_container;
1118 /* SMPTE 382M 9 */
1119 if (mxf_is_generic_container_essence_container_label (key) &&
1120 key->u[12] == 0x02 &&
1121 key->u[13] == 0x06 &&
1122 (key->u[14] == 0x01 ||
1123 key->u[14] == 0x02 ||
1124 key->u[14] == 0x03 ||
1125 key->u[14] == 0x04 || key->u[14] == 0x08 || key->u[14] == 0x09 ||
1126 key->u[14] == 0x0a || key->u[14] == 0x0b))
1127 return TRUE;
1128 }
1129
1130
1131 return FALSE;
1132 }
1133
1134 static MXFEssenceWrapping
mxf_aes_bwf_get_track_wrapping(const MXFMetadataTimelineTrack * track)1135 mxf_aes_bwf_get_track_wrapping (const MXFMetadataTimelineTrack * track)
1136 {
1137 guint i;
1138
1139 g_return_val_if_fail (track != NULL, MXF_ESSENCE_WRAPPING_CUSTOM_WRAPPING);
1140
1141 if (track->parent.descriptor == NULL) {
1142 GST_ERROR ("No descriptor found for this track");
1143 return MXF_ESSENCE_WRAPPING_CUSTOM_WRAPPING;
1144 }
1145
1146 for (i = 0; i < track->parent.n_descriptor; i++) {
1147 if (!track->parent.descriptor[i])
1148 continue;
1149 if (!MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->
1150 parent.descriptor[i]))
1151 continue;
1152
1153 switch (track->parent.descriptor[i]->essence_container.u[14]) {
1154 case 0x01:
1155 case 0x03:
1156 return MXF_ESSENCE_WRAPPING_FRAME_WRAPPING;
1157 break;
1158 case 0x02:
1159 case 0x04:
1160 return MXF_ESSENCE_WRAPPING_CLIP_WRAPPING;
1161 break;
1162 case 0x08:
1163 case 0x09:
1164 case 0x0a:
1165 case 0x0b:
1166 return MXF_ESSENCE_WRAPPING_CUSTOM_WRAPPING;
1167 default:
1168 GST_WARNING ("Unknown frame wrapping");
1169 return MXF_ESSENCE_WRAPPING_UNKNOWN_WRAPPING;
1170 break;
1171 }
1172 }
1173
1174 return MXF_ESSENCE_WRAPPING_CUSTOM_WRAPPING;
1175 }
1176
1177 static GstFlowReturn
mxf_bwf_handle_essence_element(const MXFUL * key,GstBuffer * buffer,GstCaps * caps,MXFMetadataTimelineTrack * track,gpointer mapping_data,GstBuffer ** outbuf)1178 mxf_bwf_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
1179 GstCaps * caps,
1180 MXFMetadataTimelineTrack * track,
1181 gpointer mapping_data, GstBuffer ** outbuf)
1182 {
1183 *outbuf = buffer;
1184
1185 /* SMPTE 382M Table 1: Check if this is some kind of Wave element */
1186 if (key->u[12] != 0x16 || (key->u[14] != 0x01 && key->u[14] != 0x02
1187 && key->u[14] != 0x0b)) {
1188 GST_ERROR ("Invalid BWF essence element");
1189 return GST_FLOW_ERROR;
1190 }
1191
1192 /* FIXME: check if the size is a multiply of the unit size, ... */
1193 return GST_FLOW_OK;
1194 }
1195
1196 static GstFlowReturn
mxf_aes3_handle_essence_element(const MXFUL * key,GstBuffer * buffer,GstCaps * caps,MXFMetadataTimelineTrack * track,gpointer mapping_data,GstBuffer ** outbuf)1197 mxf_aes3_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
1198 GstCaps * caps, MXFMetadataTimelineTrack * track,
1199 gpointer mapping_data, GstBuffer ** outbuf)
1200 {
1201 *outbuf = buffer;
1202
1203 /* SMPTE 382M Table 1: Check if this is some kind of Wave element */
1204 if (key->u[12] != 0x16 || (key->u[14] != 0x03 && key->u[14] != 0x04
1205 && key->u[14] != 0x0c)) {
1206 GST_ERROR ("Invalid AES3 essence element");
1207 return GST_FLOW_ERROR;
1208 }
1209
1210 /* FIXME: check if the size is a multiply of the unit size, ... */
1211 return GST_FLOW_OK;
1212 }
1213
1214
1215
1216 /* SMPTE RP224 */
1217 static const MXFUL mxf_sound_essence_compression_uncompressed =
1218 { {0x06, 0x0E, 0x2B, 0x34, 0x04, 0x01, 0x01, 0x01, 0x04, 0x02, 0x02, 0x01,
1219 0x7F, 0x00, 0x00, 0x00}
1220 };
1221
1222 /* Also seems to be uncompressed */
1223 static const MXFUL mxf_sound_essence_compression_s24le =
1224 { {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0a, 0x04, 0x02, 0x02, 0x01,
1225 0x01, 0x00, 0x00, 0x00}
1226 };
1227
1228 static const MXFUL mxf_sound_essence_compression_aiff =
1229 { {0x06, 0x0E, 0x2B, 0x34, 0x04, 0x01, 0x01, 0x07, 0x04, 0x02, 0x02, 0x01,
1230 0x7E, 0x00, 0x00, 0x00}
1231 };
1232
1233 static const MXFUL mxf_sound_essence_compression_alaw =
1234 { {0x06, 0x0E, 0x2B, 0x34, 0x04, 0x01, 0x01, 0x03, 0x04, 0x02, 0x02, 0x02,
1235 0x03, 0x01, 0x01, 0x00}
1236 };
1237
1238 static GstCaps *
mxf_bwf_create_caps(MXFMetadataTimelineTrack * track,MXFMetadataGenericSoundEssenceDescriptor * descriptor,GstTagList ** tags,gboolean * intra_only,MXFEssenceElementHandleFunc * handler,gpointer * mapping_data)1239 mxf_bwf_create_caps (MXFMetadataTimelineTrack * track,
1240 MXFMetadataGenericSoundEssenceDescriptor * descriptor, GstTagList ** tags,
1241 gboolean * intra_only,
1242 MXFEssenceElementHandleFunc * handler, gpointer * mapping_data)
1243 {
1244 GstCaps *ret = NULL;
1245 MXFMetadataWaveAudioEssenceDescriptor *wa_descriptor = NULL;
1246 #ifndef GST_DISABLE_GST_DEBUG
1247 gchar str[48];
1248 #endif
1249 gchar *codec_name = NULL;
1250
1251 if (MXF_IS_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR (descriptor))
1252 wa_descriptor = (MXFMetadataWaveAudioEssenceDescriptor *) descriptor;
1253
1254 /* TODO: Handle width=!depth, needs shifting of samples */
1255
1256 /* FIXME: set a channel layout */
1257
1258 if (mxf_ul_is_zero (&descriptor->sound_essence_compression) ||
1259 mxf_ul_is_subclass (&mxf_sound_essence_compression_uncompressed,
1260 &descriptor->sound_essence_compression) ||
1261 mxf_ul_is_subclass (&mxf_sound_essence_compression_s24le,
1262 &descriptor->sound_essence_compression)) {
1263 guint block_align;
1264 GstAudioFormat audio_format;
1265
1266 if (descriptor->channel_count == 0 ||
1267 descriptor->quantization_bits == 0 ||
1268 descriptor->audio_sampling_rate.n == 0 ||
1269 descriptor->audio_sampling_rate.d == 0) {
1270 GST_ERROR ("Invalid descriptor");
1271 return NULL;
1272 }
1273 if (wa_descriptor && wa_descriptor->block_align != 0)
1274 block_align = wa_descriptor->block_align;
1275 else
1276 block_align =
1277 (GST_ROUND_UP_8 (descriptor->quantization_bits) *
1278 descriptor->channel_count) / 8;
1279
1280 audio_format =
1281 gst_audio_format_build_integer (block_align !=
1282 descriptor->channel_count, G_LITTLE_ENDIAN,
1283 (block_align / descriptor->channel_count) * 8,
1284 (block_align / descriptor->channel_count) * 8);
1285 ret =
1286 mxf_metadata_generic_sound_essence_descriptor_create_caps (descriptor,
1287 &audio_format);
1288
1289 codec_name =
1290 g_strdup_printf ("Uncompressed %u-bit little endian integer PCM audio",
1291 (block_align / descriptor->channel_count) * 8);
1292 } else if (mxf_ul_is_subclass (&mxf_sound_essence_compression_aiff,
1293 &descriptor->sound_essence_compression)) {
1294 guint block_align;
1295 GstAudioFormat audio_format;
1296
1297 if (descriptor->channel_count == 0 ||
1298 descriptor->quantization_bits == 0 ||
1299 descriptor->audio_sampling_rate.n == 0 ||
1300 descriptor->audio_sampling_rate.d == 0) {
1301 GST_ERROR ("Invalid descriptor");
1302 return NULL;
1303 }
1304
1305 if (wa_descriptor && wa_descriptor->block_align != 0)
1306 block_align = wa_descriptor->block_align;
1307 else
1308 block_align =
1309 (GST_ROUND_UP_8 (descriptor->quantization_bits) *
1310 descriptor->channel_count) / 8;
1311
1312 audio_format =
1313 gst_audio_format_build_integer (block_align !=
1314 descriptor->channel_count, G_BIG_ENDIAN,
1315 (block_align / descriptor->channel_count) * 8,
1316 (block_align / descriptor->channel_count) * 8);
1317 ret =
1318 mxf_metadata_generic_sound_essence_descriptor_create_caps (descriptor,
1319 &audio_format);
1320
1321 codec_name =
1322 g_strdup_printf ("Uncompressed %u-bit big endian integer PCM audio",
1323 (block_align / descriptor->channel_count) * 8);
1324 } else if (mxf_ul_is_subclass (&mxf_sound_essence_compression_alaw,
1325 &descriptor->sound_essence_compression)) {
1326
1327 if (descriptor->audio_sampling_rate.n != 0 ||
1328 descriptor->audio_sampling_rate.d != 0 ||
1329 descriptor->channel_count != 0) {
1330 GST_ERROR ("Invalid descriptor");
1331 return NULL;
1332 }
1333 ret = gst_caps_new_empty_simple ("audio/x-alaw");
1334 mxf_metadata_generic_sound_essence_descriptor_set_caps (descriptor, ret);
1335
1336 codec_name = g_strdup ("A-law encoded audio");
1337 } else {
1338 GST_ERROR ("Unsupported sound essence compression: %s",
1339 mxf_ul_to_string (&descriptor->sound_essence_compression, str));
1340 }
1341
1342 *handler = mxf_bwf_handle_essence_element;
1343
1344 if (!*tags)
1345 *tags = gst_tag_list_new_empty ();
1346
1347 if (codec_name) {
1348 gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_AUDIO_CODEC,
1349 codec_name, NULL);
1350 g_free (codec_name);
1351 }
1352
1353 if (wa_descriptor && wa_descriptor->avg_bps)
1354 gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_BITRATE,
1355 wa_descriptor->avg_bps * 8, NULL);
1356
1357 *intra_only = TRUE;
1358
1359 return ret;
1360 }
1361
1362 static GstCaps *
mxf_aes3_create_caps(MXFMetadataTimelineTrack * track,MXFMetadataGenericSoundEssenceDescriptor * descriptor,GstTagList ** tags,gboolean * intra_only,MXFEssenceElementHandleFunc * handler,gpointer * mapping_data)1363 mxf_aes3_create_caps (MXFMetadataTimelineTrack * track,
1364 MXFMetadataGenericSoundEssenceDescriptor * descriptor, GstTagList ** tags,
1365 gboolean * intra_only, MXFEssenceElementHandleFunc * handler,
1366 gpointer * mapping_data)
1367 {
1368 GstCaps *ret = NULL;
1369 MXFMetadataWaveAudioEssenceDescriptor *wa_descriptor = NULL;
1370 gchar *codec_name = NULL;
1371 GstAudioFormat audio_format;
1372 guint block_align;
1373
1374 if (MXF_IS_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR (descriptor))
1375 wa_descriptor = (MXFMetadataWaveAudioEssenceDescriptor *) descriptor;
1376
1377 /* FIXME: set a channel layout */
1378
1379 if (descriptor->channel_count == 0 ||
1380 descriptor->quantization_bits == 0 ||
1381 descriptor->audio_sampling_rate.n == 0 ||
1382 descriptor->audio_sampling_rate.d == 0) {
1383 GST_ERROR ("Invalid descriptor");
1384 return NULL;
1385 }
1386 if (wa_descriptor && wa_descriptor->block_align != 0)
1387 block_align = wa_descriptor->block_align;
1388 else
1389 block_align =
1390 (GST_ROUND_UP_8 (descriptor->quantization_bits) *
1391 descriptor->channel_count) / 8;
1392
1393 audio_format =
1394 gst_audio_format_build_integer (block_align != descriptor->channel_count,
1395 G_LITTLE_ENDIAN, (block_align / descriptor->channel_count) * 8,
1396 (block_align / descriptor->channel_count) * 8);
1397 ret =
1398 mxf_metadata_generic_sound_essence_descriptor_create_caps (descriptor,
1399 &audio_format);
1400
1401 codec_name =
1402 g_strdup_printf ("Uncompressed %u-bit AES3 audio",
1403 (block_align / descriptor->channel_count) * 8);
1404
1405 if (!*tags)
1406 *tags = gst_tag_list_new_empty ();
1407
1408 gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_AUDIO_CODEC,
1409 codec_name, GST_TAG_BITRATE,
1410 (gint) (block_align * 8 *
1411 mxf_fraction_to_double (&descriptor->audio_sampling_rate)) /
1412 (descriptor->channel_count), NULL);
1413 g_free (codec_name);
1414
1415 *handler = mxf_aes3_handle_essence_element;
1416 *intra_only = TRUE;
1417
1418 return ret;
1419 }
1420
1421 static GstCaps *
mxf_aes_bwf_create_caps(MXFMetadataTimelineTrack * track,GstTagList ** tags,gboolean * intra_only,MXFEssenceElementHandleFunc * handler,gpointer * mapping_data)1422 mxf_aes_bwf_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
1423 gboolean * intra_only, MXFEssenceElementHandleFunc * handler,
1424 gpointer * mapping_data)
1425 {
1426 MXFMetadataGenericSoundEssenceDescriptor *s = NULL;
1427 gboolean bwf = FALSE;
1428 guint i;
1429
1430 g_return_val_if_fail (track != NULL, NULL);
1431
1432 if (track->parent.descriptor == NULL) {
1433 GST_ERROR ("No descriptor found for this track");
1434 return NULL;
1435 }
1436
1437 for (i = 0; i < track->parent.n_descriptor; i++) {
1438 if (!track->parent.descriptor[i])
1439 continue;
1440
1441 if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->parent.
1442 descriptor[i])
1443 && (track->parent.descriptor[i]->essence_container.u[14] == 0x01
1444 || track->parent.descriptor[i]->essence_container.u[14] == 0x02
1445 || track->parent.descriptor[i]->essence_container.u[14] == 0x08
1446 || track->parent.descriptor[i]->essence_container.u[14] == 0x0a)) {
1447 s = (MXFMetadataGenericSoundEssenceDescriptor *) track->parent.
1448 descriptor[i];
1449 bwf = TRUE;
1450 break;
1451 } else
1452 if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->parent.
1453 descriptor[i])
1454 && (track->parent.descriptor[i]->essence_container.u[14] == 0x03
1455 || track->parent.descriptor[i]->essence_container.u[14] == 0x04
1456 || track->parent.descriptor[i]->essence_container.u[14] == 0x09
1457 || track->parent.descriptor[i]->essence_container.u[14] == 0x0b)) {
1458
1459 s = (MXFMetadataGenericSoundEssenceDescriptor *) track->parent.
1460 descriptor[i];
1461 bwf = FALSE;
1462 break;
1463 }
1464 }
1465
1466 if (!s) {
1467 GST_ERROR ("No descriptor found for this track");
1468 return NULL;
1469 } else if (bwf) {
1470 return mxf_bwf_create_caps (track, s, tags, intra_only, handler,
1471 mapping_data);
1472 } else {
1473 return mxf_aes3_create_caps (track, s, tags, intra_only, handler,
1474 mapping_data);
1475 }
1476
1477 return NULL;
1478 }
1479
1480 static const MXFEssenceElementHandler mxf_aes_bwf_essence_handler = {
1481 mxf_is_aes_bwf_essence_track,
1482 mxf_aes_bwf_get_track_wrapping,
1483 mxf_aes_bwf_create_caps
1484 };
1485
1486 typedef struct
1487 {
1488 guint64 error;
1489 gint width, rate, channels;
1490 MXFFraction edit_rate;
1491 } BWFMappingData;
1492
1493 static GstFlowReturn
mxf_bwf_write_func(GstBuffer * buffer,gpointer mapping_data,GstAdapter * adapter,GstBuffer ** outbuf,gboolean flush)1494 mxf_bwf_write_func (GstBuffer * buffer, gpointer mapping_data,
1495 GstAdapter * adapter, GstBuffer ** outbuf, gboolean flush)
1496 {
1497 BWFMappingData *md = mapping_data;
1498 guint bytes;
1499 guint64 speu =
1500 gst_util_uint64_scale (md->rate, md->edit_rate.d, md->edit_rate.n);
1501
1502 md->error += (md->edit_rate.d * md->rate) % (md->edit_rate.n);
1503 if (md->error >= md->edit_rate.n) {
1504 md->error = 0;
1505 speu += 1;
1506 }
1507
1508 bytes = (speu * md->channels * md->width) / 8;
1509
1510 if (buffer)
1511 gst_adapter_push (adapter, buffer);
1512
1513 if (gst_adapter_available (adapter) == 0)
1514 return GST_FLOW_OK;
1515
1516 if (flush)
1517 bytes = MIN (gst_adapter_available (adapter), bytes);
1518
1519 if (gst_adapter_available (adapter) >= bytes) {
1520 *outbuf = gst_adapter_take_buffer (adapter, bytes);
1521 }
1522
1523 if (gst_adapter_available (adapter) >= bytes)
1524 return GST_FLOW_CUSTOM_SUCCESS;
1525 else
1526 return GST_FLOW_OK;
1527 }
1528
1529 static const guint8 bwf_essence_container_ul[] = {
1530 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01,
1531 0x0d, 0x01, 0x03, 0x01, 0x02, 0x06, 0x01, 0x00
1532 };
1533
1534 static MXFMetadataFileDescriptor *
mxf_bwf_get_descriptor(GstPadTemplate * tmpl,GstCaps * caps,MXFEssenceElementWriteFunc * handler,gpointer * mapping_data)1535 mxf_bwf_get_descriptor (GstPadTemplate * tmpl, GstCaps * caps,
1536 MXFEssenceElementWriteFunc * handler, gpointer * mapping_data)
1537 {
1538 MXFMetadataWaveAudioEssenceDescriptor *ret;
1539 BWFMappingData *md;
1540 GstAudioInfo info;
1541
1542 if (!gst_audio_info_from_caps (&info, caps)) {
1543 GST_ERROR ("Invalid caps %" GST_PTR_FORMAT, caps);
1544 return NULL;
1545 }
1546
1547 ret = (MXFMetadataWaveAudioEssenceDescriptor *)
1548 g_object_new (MXF_TYPE_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR, NULL);
1549
1550 memcpy (&ret->parent.parent.essence_container, &bwf_essence_container_ul, 16);
1551 if (info.finfo->endianness == G_LITTLE_ENDIAN)
1552 memcpy (&ret->parent.sound_essence_compression,
1553 &mxf_sound_essence_compression_uncompressed, 16);
1554 else
1555 memcpy (&ret->parent.sound_essence_compression,
1556 &mxf_sound_essence_compression_aiff, 16);
1557
1558 ret->block_align = (info.finfo->width / 8) * info.channels;
1559 ret->parent.quantization_bits = info.finfo->width;
1560 ret->avg_bps = ret->block_align * info.rate;
1561
1562 if (!mxf_metadata_generic_sound_essence_descriptor_from_caps (&ret->parent,
1563 caps)) {
1564 g_object_unref (ret);
1565 return NULL;
1566 }
1567
1568 *handler = mxf_bwf_write_func;
1569
1570 md = g_new0 (BWFMappingData, 1);
1571 md->width = info.finfo->width;
1572 md->rate = info.rate;
1573 md->channels = info.channels;
1574 *mapping_data = md;
1575
1576 return (MXFMetadataFileDescriptor *) ret;
1577 }
1578
1579 static void
mxf_bwf_update_descriptor(MXFMetadataFileDescriptor * d,GstCaps * caps,gpointer mapping_data,GstBuffer * buf)1580 mxf_bwf_update_descriptor (MXFMetadataFileDescriptor * d, GstCaps * caps,
1581 gpointer mapping_data, GstBuffer * buf)
1582 {
1583 return;
1584 }
1585
1586 static void
mxf_bwf_get_edit_rate(MXFMetadataFileDescriptor * a,GstCaps * caps,gpointer mapping_data,GstBuffer * buf,MXFMetadataSourcePackage * package,MXFMetadataTimelineTrack * track,MXFFraction * edit_rate)1587 mxf_bwf_get_edit_rate (MXFMetadataFileDescriptor * a, GstCaps * caps,
1588 gpointer mapping_data, GstBuffer * buf, MXFMetadataSourcePackage * package,
1589 MXFMetadataTimelineTrack * track, MXFFraction * edit_rate)
1590 {
1591 guint i;
1592 gdouble min = G_MAXDOUBLE;
1593 BWFMappingData *md = mapping_data;
1594
1595 for (i = 0; i < package->parent.n_tracks; i++) {
1596 MXFMetadataTimelineTrack *tmp;
1597
1598 if (!MXF_IS_METADATA_TIMELINE_TRACK (package->parent.tracks[i]) ||
1599 package->parent.tracks[i] == (MXFMetadataTrack *) track)
1600 continue;
1601
1602 tmp = MXF_METADATA_TIMELINE_TRACK (package->parent.tracks[i]);
1603 if (((gdouble) tmp->edit_rate.n) / ((gdouble) tmp->edit_rate.d) < min) {
1604 min = ((gdouble) tmp->edit_rate.n) / ((gdouble) tmp->edit_rate.d);
1605 memcpy (edit_rate, &tmp->edit_rate, sizeof (MXFFraction));
1606 }
1607 }
1608
1609 if (min == G_MAXDOUBLE) {
1610 /* 100ms edit units */
1611 edit_rate->n = 10;
1612 edit_rate->d = 1;
1613 }
1614
1615 memcpy (&md->edit_rate, edit_rate, sizeof (MXFFraction));
1616 }
1617
1618 static guint32
mxf_bwf_get_track_number_template(MXFMetadataFileDescriptor * a,GstCaps * caps,gpointer mapping_data)1619 mxf_bwf_get_track_number_template (MXFMetadataFileDescriptor * a,
1620 GstCaps * caps, gpointer mapping_data)
1621 {
1622 return (0x16 << 24) | (0x01 << 8);
1623 }
1624
1625 static MXFEssenceElementWriter mxf_bwf_essence_element_writer = {
1626 mxf_bwf_get_descriptor,
1627 mxf_bwf_update_descriptor,
1628 mxf_bwf_get_edit_rate,
1629 mxf_bwf_get_track_number_template,
1630 NULL,
1631 {{0,}}
1632 };
1633
1634 #define BWF_CAPS \
1635 GST_AUDIO_CAPS_MAKE ("S32LE") "; " \
1636 GST_AUDIO_CAPS_MAKE ("S32BE") "; " \
1637 GST_AUDIO_CAPS_MAKE ("S24LE") "; " \
1638 GST_AUDIO_CAPS_MAKE ("S24BE") "; " \
1639 GST_AUDIO_CAPS_MAKE ("S16LE") "; " \
1640 GST_AUDIO_CAPS_MAKE ("S16BE") "; " \
1641 GST_AUDIO_CAPS_MAKE ("U8")
1642
1643 void
mxf_aes_bwf_init(void)1644 mxf_aes_bwf_init (void)
1645 {
1646 mxf_metadata_register (MXF_TYPE_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR);
1647 mxf_metadata_register (MXF_TYPE_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR);
1648
1649 mxf_essence_element_handler_register (&mxf_aes_bwf_essence_handler);
1650
1651 mxf_bwf_essence_element_writer.pad_template =
1652 gst_pad_template_new ("bwf_audio_sink_%u", GST_PAD_SINK, GST_PAD_REQUEST,
1653 gst_caps_from_string (BWF_CAPS));
1654 memcpy (&mxf_bwf_essence_element_writer.data_definition,
1655 mxf_metadata_track_identifier_get (MXF_METADATA_TRACK_SOUND_ESSENCE), 16);
1656 mxf_essence_element_writer_register (&mxf_bwf_essence_element_writer);
1657 }
1658