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