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_memdup (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_memdup (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 return TRUE;
1127 }
1128
1129
1130 return FALSE;
1131 }
1132
1133 static MXFEssenceWrapping
mxf_aes_bwf_get_track_wrapping(const MXFMetadataTimelineTrack * track)1134 mxf_aes_bwf_get_track_wrapping (const MXFMetadataTimelineTrack * track)
1135 {
1136 guint i;
1137
1138 g_return_val_if_fail (track != NULL, MXF_ESSENCE_WRAPPING_CUSTOM_WRAPPING);
1139
1140 if (track->parent.descriptor == NULL) {
1141 GST_ERROR ("No descriptor found for this track");
1142 return MXF_ESSENCE_WRAPPING_CUSTOM_WRAPPING;
1143 }
1144
1145 for (i = 0; i < track->parent.n_descriptor; i++) {
1146 if (!track->parent.descriptor[i])
1147 continue;
1148 if (!MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->
1149 parent.descriptor[i]))
1150 continue;
1151
1152 switch (track->parent.descriptor[i]->essence_container.u[14]) {
1153 case 0x01:
1154 case 0x03:
1155 return MXF_ESSENCE_WRAPPING_FRAME_WRAPPING;
1156 break;
1157 case 0x02:
1158 case 0x04:
1159 return MXF_ESSENCE_WRAPPING_CLIP_WRAPPING;
1160 break;
1161 case 0x08:
1162 case 0x09:
1163 default:
1164 return MXF_ESSENCE_WRAPPING_CUSTOM_WRAPPING;
1165 break;
1166 }
1167 }
1168
1169 return MXF_ESSENCE_WRAPPING_CUSTOM_WRAPPING;
1170 }
1171
1172 static GstFlowReturn
mxf_bwf_handle_essence_element(const MXFUL * key,GstBuffer * buffer,GstCaps * caps,MXFMetadataTimelineTrack * track,gpointer mapping_data,GstBuffer ** outbuf)1173 mxf_bwf_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
1174 GstCaps * caps,
1175 MXFMetadataTimelineTrack * track,
1176 gpointer mapping_data, GstBuffer ** outbuf)
1177 {
1178 *outbuf = buffer;
1179
1180 /* SMPTE 382M Table 1: Check if this is some kind of Wave element */
1181 if (key->u[12] != 0x16 || (key->u[14] != 0x01 && key->u[14] != 0x02
1182 && key->u[14] != 0x0b)) {
1183 GST_ERROR ("Invalid BWF essence element");
1184 return GST_FLOW_ERROR;
1185 }
1186
1187 /* FIXME: check if the size is a multiply of the unit size, ... */
1188 return GST_FLOW_OK;
1189 }
1190
1191 static GstFlowReturn
mxf_aes3_handle_essence_element(const MXFUL * key,GstBuffer * buffer,GstCaps * caps,MXFMetadataTimelineTrack * track,gpointer mapping_data,GstBuffer ** outbuf)1192 mxf_aes3_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
1193 GstCaps * caps, MXFMetadataTimelineTrack * track,
1194 gpointer mapping_data, GstBuffer ** outbuf)
1195 {
1196 *outbuf = buffer;
1197
1198 /* SMPTE 382M Table 1: Check if this is some kind of Wave element */
1199 if (key->u[12] != 0x16 || (key->u[14] != 0x03 && key->u[14] != 0x04
1200 && key->u[14] != 0x0c)) {
1201 GST_ERROR ("Invalid AES3 essence element");
1202 return GST_FLOW_ERROR;
1203 }
1204
1205 /* FIXME: check if the size is a multiply of the unit size, ... */
1206 return GST_FLOW_OK;
1207 }
1208
1209
1210
1211 /* SMPTE RP224 */
1212 static const MXFUL mxf_sound_essence_compression_uncompressed =
1213 { {0x06, 0x0E, 0x2B, 0x34, 0x04, 0x01, 0x01, 0x01, 0x04, 0x02, 0x02, 0x01,
1214 0x7F, 0x00, 0x00, 0x00}
1215 };
1216
1217 /* Also seems to be uncompressed */
1218 static const MXFUL mxf_sound_essence_compression_s24le =
1219 { {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0a, 0x04, 0x02, 0x02, 0x01,
1220 0x01, 0x00, 0x00, 0x00}
1221 };
1222
1223 static const MXFUL mxf_sound_essence_compression_aiff =
1224 { {0x06, 0x0E, 0x2B, 0x34, 0x04, 0x01, 0x01, 0x07, 0x04, 0x02, 0x02, 0x01,
1225 0x7E, 0x00, 0x00, 0x00}
1226 };
1227
1228 static const MXFUL mxf_sound_essence_compression_alaw =
1229 { {0x06, 0x0E, 0x2B, 0x34, 0x04, 0x01, 0x01, 0x03, 0x04, 0x02, 0x02, 0x02,
1230 0x03, 0x01, 0x01, 0x00}
1231 };
1232
1233 static GstCaps *
mxf_bwf_create_caps(MXFMetadataTimelineTrack * track,MXFMetadataGenericSoundEssenceDescriptor * descriptor,GstTagList ** tags,gboolean * intra_only,MXFEssenceElementHandleFunc * handler,gpointer * mapping_data)1234 mxf_bwf_create_caps (MXFMetadataTimelineTrack * track,
1235 MXFMetadataGenericSoundEssenceDescriptor * descriptor, GstTagList ** tags,
1236 gboolean * intra_only,
1237 MXFEssenceElementHandleFunc * handler, gpointer * mapping_data)
1238 {
1239 GstCaps *ret = NULL;
1240 MXFMetadataWaveAudioEssenceDescriptor *wa_descriptor = NULL;
1241 #ifndef GST_DISABLE_GST_DEBUG
1242 gchar str[48];
1243 #endif
1244 gchar *codec_name = NULL;
1245
1246 if (MXF_IS_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR (descriptor))
1247 wa_descriptor = (MXFMetadataWaveAudioEssenceDescriptor *) descriptor;
1248
1249 /* TODO: Handle width=!depth, needs shifting of samples */
1250
1251 /* FIXME: set a channel layout */
1252
1253 if (mxf_ul_is_zero (&descriptor->sound_essence_compression) ||
1254 mxf_ul_is_subclass (&mxf_sound_essence_compression_uncompressed,
1255 &descriptor->sound_essence_compression) ||
1256 mxf_ul_is_subclass (&mxf_sound_essence_compression_s24le,
1257 &descriptor->sound_essence_compression)) {
1258 guint block_align;
1259 GstAudioFormat audio_format;
1260
1261 if (descriptor->channel_count == 0 ||
1262 descriptor->quantization_bits == 0 ||
1263 descriptor->audio_sampling_rate.n == 0 ||
1264 descriptor->audio_sampling_rate.d == 0) {
1265 GST_ERROR ("Invalid descriptor");
1266 return NULL;
1267 }
1268 if (wa_descriptor && wa_descriptor->block_align != 0)
1269 block_align = wa_descriptor->block_align;
1270 else
1271 block_align =
1272 (GST_ROUND_UP_8 (descriptor->quantization_bits) *
1273 descriptor->channel_count) / 8;
1274
1275 audio_format =
1276 gst_audio_format_build_integer (block_align !=
1277 descriptor->channel_count, G_LITTLE_ENDIAN,
1278 (block_align / descriptor->channel_count) * 8,
1279 (block_align / descriptor->channel_count) * 8);
1280 ret =
1281 mxf_metadata_generic_sound_essence_descriptor_create_caps (descriptor,
1282 &audio_format);
1283
1284 codec_name =
1285 g_strdup_printf ("Uncompressed %u-bit little endian integer PCM audio",
1286 (block_align / descriptor->channel_count) * 8);
1287 } else if (mxf_ul_is_subclass (&mxf_sound_essence_compression_aiff,
1288 &descriptor->sound_essence_compression)) {
1289 guint block_align;
1290 GstAudioFormat audio_format;
1291
1292 if (descriptor->channel_count == 0 ||
1293 descriptor->quantization_bits == 0 ||
1294 descriptor->audio_sampling_rate.n == 0 ||
1295 descriptor->audio_sampling_rate.d == 0) {
1296 GST_ERROR ("Invalid descriptor");
1297 return NULL;
1298 }
1299
1300 if (wa_descriptor && wa_descriptor->block_align != 0)
1301 block_align = wa_descriptor->block_align;
1302 else
1303 block_align =
1304 (GST_ROUND_UP_8 (descriptor->quantization_bits) *
1305 descriptor->channel_count) / 8;
1306
1307 audio_format =
1308 gst_audio_format_build_integer (block_align !=
1309 descriptor->channel_count, G_BIG_ENDIAN,
1310 (block_align / descriptor->channel_count) * 8,
1311 (block_align / descriptor->channel_count) * 8);
1312 ret =
1313 mxf_metadata_generic_sound_essence_descriptor_create_caps (descriptor,
1314 &audio_format);
1315
1316 codec_name =
1317 g_strdup_printf ("Uncompressed %u-bit big endian integer PCM audio",
1318 (block_align / descriptor->channel_count) * 8);
1319 } else if (mxf_ul_is_subclass (&mxf_sound_essence_compression_alaw,
1320 &descriptor->sound_essence_compression)) {
1321
1322 if (descriptor->audio_sampling_rate.n != 0 ||
1323 descriptor->audio_sampling_rate.d != 0 ||
1324 descriptor->channel_count != 0) {
1325 GST_ERROR ("Invalid descriptor");
1326 return NULL;
1327 }
1328 ret = gst_caps_new_empty_simple ("audio/x-alaw");
1329 mxf_metadata_generic_sound_essence_descriptor_set_caps (descriptor, ret);
1330
1331 codec_name = g_strdup ("A-law encoded audio");
1332 } else {
1333 GST_ERROR ("Unsupported sound essence compression: %s",
1334 mxf_ul_to_string (&descriptor->sound_essence_compression, str));
1335 }
1336
1337 *handler = mxf_bwf_handle_essence_element;
1338
1339 if (!*tags)
1340 *tags = gst_tag_list_new_empty ();
1341
1342 if (codec_name) {
1343 gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_AUDIO_CODEC,
1344 codec_name, NULL);
1345 g_free (codec_name);
1346 }
1347
1348 if (wa_descriptor && wa_descriptor->avg_bps)
1349 gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_BITRATE,
1350 wa_descriptor->avg_bps * 8, NULL);
1351
1352 *intra_only = TRUE;
1353
1354 return ret;
1355 }
1356
1357 static GstCaps *
mxf_aes3_create_caps(MXFMetadataTimelineTrack * track,MXFMetadataGenericSoundEssenceDescriptor * descriptor,GstTagList ** tags,gboolean * intra_only,MXFEssenceElementHandleFunc * handler,gpointer * mapping_data)1358 mxf_aes3_create_caps (MXFMetadataTimelineTrack * track,
1359 MXFMetadataGenericSoundEssenceDescriptor * descriptor, GstTagList ** tags,
1360 gboolean * intra_only, MXFEssenceElementHandleFunc * handler,
1361 gpointer * mapping_data)
1362 {
1363 GstCaps *ret = NULL;
1364 MXFMetadataWaveAudioEssenceDescriptor *wa_descriptor = NULL;
1365 gchar *codec_name = NULL;
1366 GstAudioFormat audio_format;
1367 guint block_align;
1368
1369 if (MXF_IS_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR (descriptor))
1370 wa_descriptor = (MXFMetadataWaveAudioEssenceDescriptor *) descriptor;
1371
1372 /* FIXME: set a channel layout */
1373
1374 if (descriptor->channel_count == 0 ||
1375 descriptor->quantization_bits == 0 ||
1376 descriptor->audio_sampling_rate.n == 0 ||
1377 descriptor->audio_sampling_rate.d == 0) {
1378 GST_ERROR ("Invalid descriptor");
1379 return NULL;
1380 }
1381 if (wa_descriptor && wa_descriptor->block_align != 0)
1382 block_align = wa_descriptor->block_align;
1383 else
1384 block_align =
1385 (GST_ROUND_UP_8 (descriptor->quantization_bits) *
1386 descriptor->channel_count) / 8;
1387
1388 audio_format =
1389 gst_audio_format_build_integer (block_align != descriptor->channel_count,
1390 G_LITTLE_ENDIAN, (block_align / descriptor->channel_count) * 8,
1391 (block_align / descriptor->channel_count) * 8);
1392 ret =
1393 mxf_metadata_generic_sound_essence_descriptor_create_caps (descriptor,
1394 &audio_format);
1395
1396 codec_name =
1397 g_strdup_printf ("Uncompressed %u-bit AES3 audio",
1398 (block_align / descriptor->channel_count) * 8);
1399
1400 if (!*tags)
1401 *tags = gst_tag_list_new_empty ();
1402
1403 gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_AUDIO_CODEC,
1404 codec_name, GST_TAG_BITRATE,
1405 (gint) (block_align * 8 *
1406 mxf_fraction_to_double (&descriptor->audio_sampling_rate)) /
1407 (descriptor->channel_count), NULL);
1408 g_free (codec_name);
1409
1410 *handler = mxf_aes3_handle_essence_element;
1411 *intra_only = TRUE;
1412
1413 return ret;
1414 }
1415
1416 static GstCaps *
mxf_aes_bwf_create_caps(MXFMetadataTimelineTrack * track,GstTagList ** tags,gboolean * intra_only,MXFEssenceElementHandleFunc * handler,gpointer * mapping_data)1417 mxf_aes_bwf_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
1418 gboolean * intra_only, MXFEssenceElementHandleFunc * handler,
1419 gpointer * mapping_data)
1420 {
1421 MXFMetadataGenericSoundEssenceDescriptor *s = NULL;
1422 gboolean bwf = FALSE;
1423 guint i;
1424
1425 g_return_val_if_fail (track != NULL, NULL);
1426
1427 if (track->parent.descriptor == NULL) {
1428 GST_ERROR ("No descriptor found for this track");
1429 return NULL;
1430 }
1431
1432 for (i = 0; i < track->parent.n_descriptor; i++) {
1433 if (!track->parent.descriptor[i])
1434 continue;
1435
1436 if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->parent.
1437 descriptor[i])
1438 && (track->parent.descriptor[i]->essence_container.u[14] == 0x01
1439 || track->parent.descriptor[i]->essence_container.u[14] == 0x02
1440 || track->parent.descriptor[i]->essence_container.u[14] == 0x08)) {
1441 s = (MXFMetadataGenericSoundEssenceDescriptor *) track->parent.
1442 descriptor[i];
1443 bwf = TRUE;
1444 break;
1445 } else
1446 if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->parent.
1447 descriptor[i])
1448 && (track->parent.descriptor[i]->essence_container.u[14] == 0x03
1449 || track->parent.descriptor[i]->essence_container.u[14] == 0x04
1450 || track->parent.descriptor[i]->essence_container.u[14] == 0x09)) {
1451
1452 s = (MXFMetadataGenericSoundEssenceDescriptor *) track->parent.
1453 descriptor[i];
1454 bwf = FALSE;
1455 break;
1456 }
1457 }
1458
1459 if (!s) {
1460 GST_ERROR ("No descriptor found for this track");
1461 return NULL;
1462 } else if (bwf) {
1463 return mxf_bwf_create_caps (track, s, tags, intra_only, handler,
1464 mapping_data);
1465 } else {
1466 return mxf_aes3_create_caps (track, s, tags, intra_only, handler,
1467 mapping_data);
1468 }
1469
1470 return NULL;
1471 }
1472
1473 static const MXFEssenceElementHandler mxf_aes_bwf_essence_handler = {
1474 mxf_is_aes_bwf_essence_track,
1475 mxf_aes_bwf_get_track_wrapping,
1476 mxf_aes_bwf_create_caps
1477 };
1478
1479 typedef struct
1480 {
1481 guint64 error;
1482 gint width, rate, channels;
1483 MXFFraction edit_rate;
1484 } BWFMappingData;
1485
1486 static GstFlowReturn
mxf_bwf_write_func(GstBuffer * buffer,gpointer mapping_data,GstAdapter * adapter,GstBuffer ** outbuf,gboolean flush)1487 mxf_bwf_write_func (GstBuffer * buffer, gpointer mapping_data,
1488 GstAdapter * adapter, GstBuffer ** outbuf, gboolean flush)
1489 {
1490 BWFMappingData *md = mapping_data;
1491 guint bytes;
1492 guint64 speu =
1493 gst_util_uint64_scale (md->rate, md->edit_rate.d, md->edit_rate.n);
1494
1495 md->error += (md->edit_rate.d * md->rate) % (md->edit_rate.n);
1496 if (md->error >= md->edit_rate.n) {
1497 md->error = 0;
1498 speu += 1;
1499 }
1500
1501 bytes = (speu * md->channels * md->width) / 8;
1502
1503 if (buffer)
1504 gst_adapter_push (adapter, buffer);
1505
1506 if (gst_adapter_available (adapter) == 0)
1507 return GST_FLOW_OK;
1508
1509 if (flush)
1510 bytes = MIN (gst_adapter_available (adapter), bytes);
1511
1512 if (gst_adapter_available (adapter) >= bytes) {
1513 *outbuf = gst_adapter_take_buffer (adapter, bytes);
1514 }
1515
1516 if (gst_adapter_available (adapter) >= bytes)
1517 return GST_FLOW_CUSTOM_SUCCESS;
1518 else
1519 return GST_FLOW_OK;
1520 }
1521
1522 static const guint8 bwf_essence_container_ul[] = {
1523 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01,
1524 0x0d, 0x01, 0x03, 0x01, 0x02, 0x06, 0x01, 0x00
1525 };
1526
1527 static MXFMetadataFileDescriptor *
mxf_bwf_get_descriptor(GstPadTemplate * tmpl,GstCaps * caps,MXFEssenceElementWriteFunc * handler,gpointer * mapping_data)1528 mxf_bwf_get_descriptor (GstPadTemplate * tmpl, GstCaps * caps,
1529 MXFEssenceElementWriteFunc * handler, gpointer * mapping_data)
1530 {
1531 MXFMetadataWaveAudioEssenceDescriptor *ret;
1532 BWFMappingData *md;
1533 GstAudioInfo info;
1534
1535 if (!gst_audio_info_from_caps (&info, caps)) {
1536 GST_ERROR ("Invalid caps %" GST_PTR_FORMAT, caps);
1537 return NULL;
1538 }
1539
1540 ret = (MXFMetadataWaveAudioEssenceDescriptor *)
1541 g_object_new (MXF_TYPE_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR, NULL);
1542
1543 memcpy (&ret->parent.parent.essence_container, &bwf_essence_container_ul, 16);
1544 if (info.finfo->endianness == G_LITTLE_ENDIAN)
1545 memcpy (&ret->parent.sound_essence_compression,
1546 &mxf_sound_essence_compression_uncompressed, 16);
1547 else
1548 memcpy (&ret->parent.sound_essence_compression,
1549 &mxf_sound_essence_compression_aiff, 16);
1550
1551 ret->block_align = (info.finfo->width / 8) * info.channels;
1552 ret->parent.quantization_bits = info.finfo->width;
1553 ret->avg_bps = ret->block_align * info.rate;
1554
1555 if (!mxf_metadata_generic_sound_essence_descriptor_from_caps (&ret->parent,
1556 caps)) {
1557 g_object_unref (ret);
1558 return NULL;
1559 }
1560
1561 *handler = mxf_bwf_write_func;
1562
1563 md = g_new0 (BWFMappingData, 1);
1564 md->width = info.finfo->width;
1565 md->rate = info.rate;
1566 md->channels = info.channels;
1567 *mapping_data = md;
1568
1569 return (MXFMetadataFileDescriptor *) ret;
1570 }
1571
1572 static void
mxf_bwf_update_descriptor(MXFMetadataFileDescriptor * d,GstCaps * caps,gpointer mapping_data,GstBuffer * buf)1573 mxf_bwf_update_descriptor (MXFMetadataFileDescriptor * d, GstCaps * caps,
1574 gpointer mapping_data, GstBuffer * buf)
1575 {
1576 return;
1577 }
1578
1579 static void
mxf_bwf_get_edit_rate(MXFMetadataFileDescriptor * a,GstCaps * caps,gpointer mapping_data,GstBuffer * buf,MXFMetadataSourcePackage * package,MXFMetadataTimelineTrack * track,MXFFraction * edit_rate)1580 mxf_bwf_get_edit_rate (MXFMetadataFileDescriptor * a, GstCaps * caps,
1581 gpointer mapping_data, GstBuffer * buf, MXFMetadataSourcePackage * package,
1582 MXFMetadataTimelineTrack * track, MXFFraction * edit_rate)
1583 {
1584 guint i;
1585 gdouble min = G_MAXDOUBLE;
1586 BWFMappingData *md = mapping_data;
1587
1588 for (i = 0; i < package->parent.n_tracks; i++) {
1589 MXFMetadataTimelineTrack *tmp;
1590
1591 if (!MXF_IS_METADATA_TIMELINE_TRACK (package->parent.tracks[i]) ||
1592 package->parent.tracks[i] == (MXFMetadataTrack *) track)
1593 continue;
1594
1595 tmp = MXF_METADATA_TIMELINE_TRACK (package->parent.tracks[i]);
1596 if (((gdouble) tmp->edit_rate.n) / ((gdouble) tmp->edit_rate.d) < min) {
1597 min = ((gdouble) tmp->edit_rate.n) / ((gdouble) tmp->edit_rate.d);
1598 memcpy (edit_rate, &tmp->edit_rate, sizeof (MXFFraction));
1599 }
1600 }
1601
1602 if (min == G_MAXDOUBLE) {
1603 /* 100ms edit units */
1604 edit_rate->n = 10;
1605 edit_rate->d = 1;
1606 }
1607
1608 memcpy (&md->edit_rate, edit_rate, sizeof (MXFFraction));
1609 }
1610
1611 static guint32
mxf_bwf_get_track_number_template(MXFMetadataFileDescriptor * a,GstCaps * caps,gpointer mapping_data)1612 mxf_bwf_get_track_number_template (MXFMetadataFileDescriptor * a,
1613 GstCaps * caps, gpointer mapping_data)
1614 {
1615 return (0x16 << 24) | (0x01 << 8);
1616 }
1617
1618 static MXFEssenceElementWriter mxf_bwf_essence_element_writer = {
1619 mxf_bwf_get_descriptor,
1620 mxf_bwf_update_descriptor,
1621 mxf_bwf_get_edit_rate,
1622 mxf_bwf_get_track_number_template,
1623 NULL,
1624 {{0,}}
1625 };
1626
1627 #define BWF_CAPS \
1628 GST_AUDIO_CAPS_MAKE ("S32LE") "; " \
1629 GST_AUDIO_CAPS_MAKE ("S32BE") "; " \
1630 GST_AUDIO_CAPS_MAKE ("S24LE") "; " \
1631 GST_AUDIO_CAPS_MAKE ("S24BE") "; " \
1632 GST_AUDIO_CAPS_MAKE ("S16LE") "; " \
1633 GST_AUDIO_CAPS_MAKE ("S16BE") "; " \
1634 GST_AUDIO_CAPS_MAKE ("U8")
1635
1636 void
mxf_aes_bwf_init(void)1637 mxf_aes_bwf_init (void)
1638 {
1639 mxf_metadata_register (MXF_TYPE_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR);
1640 mxf_metadata_register (MXF_TYPE_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR);
1641
1642 mxf_essence_element_handler_register (&mxf_aes_bwf_essence_handler);
1643
1644 mxf_bwf_essence_element_writer.pad_template =
1645 gst_pad_template_new ("bwf_audio_sink_%u", GST_PAD_SINK, GST_PAD_REQUEST,
1646 gst_caps_from_string (BWF_CAPS));
1647 memcpy (&mxf_bwf_essence_element_writer.data_definition,
1648 mxf_metadata_track_identifier_get (MXF_METADATA_TRACK_SOUND_ESSENCE), 16);
1649 mxf_essence_element_writer_register (&mxf_bwf_essence_element_writer);
1650 }
1651