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