gst/mxf/: Add support for AES3 audio (SMPTE 382M).
authorSebastian Dröge <slomo@circular-chaos.org>
Wed, 3 Dec 2008 16:08:28 +0000 (16:08 +0000)
committerSebastian Dröge <slomo@circular-chaos.org>
Wed, 3 Dec 2008 16:08:28 +0000 (16:08 +0000)
Original commit message from CVS:
* gst/mxf/mxfaes-bwf.c:
(mxf_metadata_aes3_audio_essence_descriptor_handle_tag),
(mxf_metadata_aes3_audio_essence_descriptor_reset),
(mxf_aes3_handle_essence_element), (mxf_bwf_create_caps),
(mxf_aes3_create_caps), (mxf_aes_bwf_create_caps):
* gst/mxf/mxfaes-bwf.h:
* gst/mxf/mxfdemux.c: (gst_mxf_demux_reset_metadata),
(gst_mxf_demux_handle_metadata_aes3_audio_essence_descriptor),
(gst_mxf_demux_handle_header_metadata_resolve_references),
(gst_mxf_demux_handle_metadata):
* gst/mxf/mxfdemux.h:
Add support for AES3 audio (SMPTE 382M).
* gst/mxf/mxfdv-dif.c: (mxf_dv_dif_create_caps):
* gst/mxf/mxfjpeg2000.c: (mxf_jpeg2000_create_caps):
Fix coding style.

ChangeLog
gst/mxf/mxfaes-bwf.c
gst/mxf/mxfaes-bwf.h
gst/mxf/mxfdemux.c
gst/mxf/mxfdemux.h

index ab8fd9c..329b903 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
 2008-12-03  Sebastian Dröge  <sebastian.droege@collabora.co.uk>
 
+       * gst/mxf/mxfaes-bwf.c:
+       (mxf_metadata_aes3_audio_essence_descriptor_handle_tag),
+       (mxf_metadata_aes3_audio_essence_descriptor_reset),
+       (mxf_aes3_handle_essence_element), (mxf_bwf_create_caps),
+       (mxf_aes3_create_caps), (mxf_aes_bwf_create_caps):
+       * gst/mxf/mxfaes-bwf.h:
+       * gst/mxf/mxfdemux.c: (gst_mxf_demux_reset_metadata),
+       (gst_mxf_demux_handle_metadata_aes3_audio_essence_descriptor),
+       (gst_mxf_demux_handle_header_metadata_resolve_references),
+       (gst_mxf_demux_handle_metadata):
+       * gst/mxf/mxfdemux.h:
+       Add support for AES3 audio (SMPTE 382M).
+
+       * gst/mxf/mxfdv-dif.c: (mxf_dv_dif_create_caps):
+       * gst/mxf/mxfjpeg2000.c: (mxf_jpeg2000_create_caps):
+       Fix coding style.
+
+2008-12-03  Sebastian Dröge  <sebastian.droege@collabora.co.uk>
+
        * gst/mxf/mxfdemux.c:
        (gst_mxf_demux_handle_generic_container_essence_element):
        Improve debugging a bit.
index 0b6d9eb..ce4bbf5 100644 (file)
@@ -184,6 +184,272 @@ void mxf_metadata_wave_audio_essence_descriptor_reset
       MXFMetadataGenericSoundEssenceDescriptor);
 }
 
+/* SMPTE 382M Annex 2 */
+gboolean
+    mxf_metadata_aes3_audio_essence_descriptor_handle_tag
+    (MXFMetadataGenericDescriptor * d, const MXFPrimerPack * primer,
+    guint16 tag, const guint8 * tag_data, guint16 tag_size)
+{
+  MXFMetadataAES3AudioEssenceDescriptor *descriptor =
+      (MXFMetadataAES3AudioEssenceDescriptor *) d;
+  gboolean ret = FALSE;
+
+  switch (tag) {
+    case 0x3d0d:
+      if (tag_size != 1)
+        goto error;
+      descriptor->emphasis = GST_READ_UINT8 (tag_data);
+      GST_DEBUG ("  emphasis = %u", descriptor->emphasis);
+      ret = TRUE;
+      break;
+    case 0x3d0f:
+      if (tag_size != 2)
+        goto error;
+      descriptor->block_start_offset = GST_READ_UINT16_BE (tag_data);
+      GST_DEBUG ("  block start offset = %u", descriptor->block_start_offset);
+      ret = TRUE;
+      break;
+    case 0x3d08:
+      if (tag_size != 1)
+        goto error;
+      descriptor->auxiliary_bits_mode = GST_READ_UINT8 (tag_data);
+      GST_DEBUG ("  auxiliary bits mode = %u", descriptor->auxiliary_bits_mode);
+      ret = TRUE;
+      break;
+    case 0x3d10:{
+      guint32 len;
+      guint i;
+
+      if (tag_size < 8)
+        goto error;
+      len = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  number of channel status mode = %u", len);
+      descriptor->n_channel_status_mode = len;
+      if (len == 0)
+        return TRUE;
+
+      if (GST_READ_UINT32_BE (tag_data + 4) != 1)
+        goto error;
+
+      tag_data += 8;
+      tag_size -= 8;
+
+      if (tag_size != len)
+        goto error;
+
+      descriptor->channel_status_mode = g_new0 (guint8, len);
+
+      for (i = 0; i < len; i++) {
+        descriptor->channel_status_mode[i] = GST_READ_UINT8 (tag_data);
+        GST_DEBUG ("    channel status mode %u = %u", i,
+            descriptor->channel_status_mode[i]);
+        tag_data++;
+        tag_size--;
+      }
+
+      ret = TRUE;
+      break;
+    }
+    case 0x3d11:{
+      guint32 len;
+      guint i;
+
+      if (tag_size < 8)
+        goto error;
+      len = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  number of fixed channel status data = %u", len);
+      descriptor->n_fixed_channel_status_data = len;
+      if (len == 0)
+        return TRUE;
+
+      if (GST_READ_UINT32_BE (tag_data + 4) != 24)
+        goto error;
+
+      tag_data += 8;
+      tag_size -= 8;
+
+      if (tag_size != len * 24)
+        goto error;
+
+      descriptor->fixed_channel_status_data =
+          g_malloc0 (len * sizeof (guint8 *) + len * 24);
+
+      for (i = 0; i < len; i++) {
+        descriptor->fixed_channel_status_data[i] =
+            ((guint8 *) descriptor->fixed_channel_status_data) +
+            len * sizeof (guint8 *) + i * 24;
+
+        memcpy (descriptor->fixed_channel_status_data[i], tag_data, 24);
+        GST_DEBUG
+            ("    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",
+            i, descriptor->fixed_channel_status_data[i][0],
+            descriptor->fixed_channel_status_data[i][1],
+            descriptor->fixed_channel_status_data[i][2],
+            descriptor->fixed_channel_status_data[i][3],
+            descriptor->fixed_channel_status_data[i][4],
+            descriptor->fixed_channel_status_data[i][5],
+            descriptor->fixed_channel_status_data[i][6],
+            descriptor->fixed_channel_status_data[i][7],
+            descriptor->fixed_channel_status_data[i][8],
+            descriptor->fixed_channel_status_data[i][9],
+            descriptor->fixed_channel_status_data[i][10],
+            descriptor->fixed_channel_status_data[i][11],
+            descriptor->fixed_channel_status_data[i][12],
+            descriptor->fixed_channel_status_data[i][13],
+            descriptor->fixed_channel_status_data[i][14],
+            descriptor->fixed_channel_status_data[i][15],
+            descriptor->fixed_channel_status_data[i][16],
+            descriptor->fixed_channel_status_data[i][17],
+            descriptor->fixed_channel_status_data[i][18],
+            descriptor->fixed_channel_status_data[i][19],
+            descriptor->fixed_channel_status_data[i][20],
+            descriptor->fixed_channel_status_data[i][21],
+            descriptor->fixed_channel_status_data[i][22],
+            descriptor->fixed_channel_status_data[i][23]
+            );
+        tag_data += 24;
+        tag_size -= 24;
+      }
+
+      ret = TRUE;
+      break;
+    }
+    case 0x3d12:{
+      guint32 len;
+      guint i;
+
+      if (tag_size < 8)
+        goto error;
+      len = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  number of user data mode = %u", len);
+      descriptor->n_user_data_mode = len;
+      if (len == 0)
+        return TRUE;
+
+      if (GST_READ_UINT32_BE (tag_data + 4) != 1)
+        goto error;
+
+      tag_data += 8;
+      tag_size -= 8;
+
+      if (tag_size != len)
+        goto error;
+
+      descriptor->user_data_mode = g_new0 (guint8, len);
+
+      for (i = 0; i < len; i++) {
+        descriptor->user_data_mode[i] = GST_READ_UINT8 (tag_data);
+        GST_DEBUG ("    user data mode %u = %u", i,
+            descriptor->user_data_mode[i]);
+        tag_data++;
+        tag_size--;
+      }
+
+      ret = TRUE;
+      break;
+    }
+    case 0x3d13:{
+      guint32 len;
+      guint i;
+
+      if (tag_size < 8)
+        goto error;
+      len = GST_READ_UINT32_BE (tag_data);
+      GST_DEBUG ("  number of fixed user data = %u", len);
+      descriptor->n_fixed_user_data = len;
+      if (len == 0)
+        return TRUE;
+
+      if (GST_READ_UINT32_BE (tag_data + 4) != 24)
+        goto error;
+
+      tag_data += 8;
+      tag_size -= 8;
+
+      if (tag_size != len * 24)
+        goto error;
+
+      descriptor->fixed_user_data =
+          g_malloc0 (len * sizeof (guint8 *) + len * 24);
+
+      for (i = 0; i < len; i++) {
+        descriptor->fixed_user_data[i] =
+            ((guint8 *) descriptor->fixed_user_data) + len * sizeof (guint8 *) +
+            i * 24;
+
+        memcpy (descriptor->fixed_user_data[i], tag_data, 24);
+        GST_DEBUG
+            ("    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",
+            i, descriptor->fixed_user_data[i][0],
+            descriptor->fixed_user_data[i][1],
+            descriptor->fixed_user_data[i][2],
+            descriptor->fixed_user_data[i][3],
+            descriptor->fixed_user_data[i][4],
+            descriptor->fixed_user_data[i][5],
+            descriptor->fixed_user_data[i][6],
+            descriptor->fixed_user_data[i][7],
+            descriptor->fixed_user_data[i][8],
+            descriptor->fixed_user_data[i][9],
+            descriptor->fixed_user_data[i][10],
+            descriptor->fixed_user_data[i][11],
+            descriptor->fixed_user_data[i][12],
+            descriptor->fixed_user_data[i][13],
+            descriptor->fixed_user_data[i][14],
+            descriptor->fixed_user_data[i][15],
+            descriptor->fixed_user_data[i][16],
+            descriptor->fixed_user_data[i][17],
+            descriptor->fixed_user_data[i][18],
+            descriptor->fixed_user_data[i][19],
+            descriptor->fixed_user_data[i][20],
+            descriptor->fixed_user_data[i][21],
+            descriptor->fixed_user_data[i][22],
+            descriptor->fixed_user_data[i][23]
+            );
+        tag_data += 24;
+        tag_size -= 24;
+      }
+
+      ret = TRUE;
+      break;
+    }
+      /* TODO: linked timecode track / data_stream_number parsing, see
+       * SMPTE 382M Annex 2 */
+    default:
+      ret =
+          mxf_metadata_wave_audio_essence_descriptor_handle_tag (d, primer,
+          tag, tag_data, tag_size);
+      break;
+  }
+
+  return ret;
+
+error:
+  GST_ERROR ("Invalid AES3 audio essence descriptor tag 0x%04x of size %u", tag,
+      tag_size);
+
+  return TRUE;
+}
+
+void mxf_metadata_aes3_audio_essence_descriptor_reset
+    (MXFMetadataAES3AudioEssenceDescriptor * descriptor)
+{
+  g_return_if_fail (descriptor != NULL);
+
+  mxf_metadata_wave_audio_essence_descriptor_reset (
+      (MXFMetadataWaveAudioEssenceDescriptor *) descriptor);
+
+  g_free (descriptor->channel_status_mode);
+  g_free (descriptor->fixed_channel_status_data);
+  g_free (descriptor->user_data_mode);
+  g_free (descriptor->fixed_user_data);
+
+  MXF_METADATA_DESCRIPTOR_CLEAR (descriptor,
+      MXFMetadataAES3AudioEssenceDescriptor,
+      MXFMetadataWaveAudioEssenceDescriptor);
+}
+
+
+
 gboolean
 mxf_is_aes_bwf_essence_track (const MXFMetadataTrack * track)
 {
@@ -233,6 +499,27 @@ mxf_bwf_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
   return GST_FLOW_OK;
 }
 
+static GstFlowReturn
+mxf_aes3_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
+    GstCaps * caps, MXFMetadataGenericPackage * package,
+    MXFMetadataTrack * track, MXFMetadataStructuralComponent * component,
+    gpointer mapping_data, GstBuffer ** outbuf)
+{
+  *outbuf = buffer;
+
+  /* SMPTE 382M Table 1: Check if this is some kind of Wave element */
+  if (key->u[12] != 0x16 || (key->u[14] != 0x03 && key->u[14] != 0x04
+          && key->u[14] != 0x0c)) {
+    GST_ERROR ("Invalid AES3 essence element");
+    return GST_FLOW_ERROR;
+  }
+
+  /* FIXME: check if the size is a multiply of the unit size, ... */
+  return GST_FLOW_OK;
+}
+
+
+
 /* SMPTE RP224 */
 static const MXFUL mxf_sound_essence_compression_uncompressed =
     { {0x06, 0x0E, 0x2B, 0x34, 0x04, 0x01, 0x01, 0x01, 0x04, 0x02, 0x02, 0x01,
@@ -264,7 +551,6 @@ mxf_bwf_create_caps (MXFMetadataGenericPackage * package,
       MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR)
     wa_descriptor = (MXFMetadataWaveAudioEssenceDescriptor *) descriptor;
 
-  /* TODO: set caps for avg bitrate, audio codec, ...... */
   /* TODO: Handle width=!depth, needs shifting of samples */
 
   /* FIXME: set a channel layout */
@@ -281,7 +567,7 @@ mxf_bwf_create_caps (MXFMetadataGenericPackage * package,
       GST_ERROR ("Invalid descriptor");
       return NULL;
     }
-    if (wa_descriptor)
+    if (wa_descriptor && wa_descriptor->block_align != 0)
       block_align = wa_descriptor->block_align;
     else
       block_align = GST_ROUND_UP_8 (descriptor->quantization_bits) / 8;
@@ -310,7 +596,7 @@ mxf_bwf_create_caps (MXFMetadataGenericPackage * package,
       return NULL;
     }
 
-    if (wa_descriptor)
+    if (wa_descriptor && wa_descriptor->block_align != 0)
       block_align = wa_descriptor->block_align;
     else
       block_align = GST_ROUND_UP_8 (descriptor->quantization_bits) / 8;
@@ -364,12 +650,69 @@ mxf_bwf_create_caps (MXFMetadataGenericPackage * package,
   return ret;
 }
 
+static GstCaps *
+mxf_aes3_create_caps (MXFMetadataGenericPackage * package,
+    MXFMetadataTrack * track,
+    MXFMetadataGenericSoundEssenceDescriptor * descriptor, GstTagList ** tags,
+    MXFEssenceElementHandler * handler, gpointer * mapping_data)
+{
+  GstCaps *ret = NULL;
+  MXFMetadataWaveAudioEssenceDescriptor *wa_descriptor = NULL;
+  gchar *codec_name = NULL;
+  guint block_align;
+
+  if (((MXFMetadataGenericDescriptor *) descriptor)->type ==
+      MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR ||
+      ((MXFMetadataGenericDescriptor *) descriptor)->type ==
+      MXF_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR)
+    wa_descriptor = (MXFMetadataWaveAudioEssenceDescriptor *) descriptor;
+
+  /* FIXME: set a channel layout */
+
+  if (descriptor->channel_count == 0 ||
+      descriptor->quantization_bits == 0 ||
+      descriptor->audio_sampling_rate.n == 0 ||
+      descriptor->audio_sampling_rate.d == 0) {
+    GST_ERROR ("Invalid descriptor");
+    return NULL;
+  }
+  if (wa_descriptor && wa_descriptor->block_align != 0)
+    block_align = wa_descriptor->block_align;
+  else
+    block_align = GST_ROUND_UP_8 (descriptor->quantization_bits) / 8;
+
+  ret = gst_caps_new_simple ("audio/x-raw-int",
+      "rate", G_TYPE_INT,
+      (gint) (((gdouble) descriptor->audio_sampling_rate.n) /
+          ((gdouble) descriptor->audio_sampling_rate.d) + 0.5), "channels",
+      G_TYPE_INT, descriptor->channel_count, "signed", G_TYPE_BOOLEAN,
+      (block_align != 1), "endianness", G_TYPE_INT, G_LITTLE_ENDIAN, "depth",
+      G_TYPE_INT, (block_align / descriptor->channel_count) * 8, "width",
+      G_TYPE_INT, (block_align / descriptor->channel_count) * 8, NULL);
+
+  codec_name =
+      g_strdup_printf ("Uncompressed %u-bit AES3 audio",
+      (block_align / descriptor->channel_count) * 8);
+
+  if (!*tags)
+    *tags = gst_tag_list_new ();
+
+  gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_AUDIO_CODEC,
+      codec_name, GST_TAG_BITRATE, block_align * 8, NULL);
+  g_free (codec_name);
+
+  *handler = mxf_aes3_handle_essence_element;
+
+  return ret;
+}
+
 GstCaps *
 mxf_aes_bwf_create_caps (MXFMetadataGenericPackage * package,
     MXFMetadataTrack * track, GstTagList ** tags,
     MXFEssenceElementHandler * handler, gpointer * mapping_data)
 {
   MXFMetadataGenericSoundEssenceDescriptor *s = NULL;
+  gboolean bwf = FALSE;
   guint i;
 
   g_return_val_if_fail (package != NULL, NULL);
@@ -380,8 +723,6 @@ mxf_aes_bwf_create_caps (MXFMetadataGenericPackage * package,
     return NULL;
   }
 
-  /* TODO: handle AES3 audio */
-
   for (i = 0; i < track->n_descriptor; i++) {
     if ((track->descriptor[i]->parent.type ==
             MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR
@@ -391,6 +732,20 @@ mxf_aes_bwf_create_caps (MXFMetadataGenericPackage * package,
             || track->descriptor[i]->essence_container.u[14] == 0x02
             || track->descriptor[i]->essence_container.u[14] == 0x08)) {
       s = (MXFMetadataGenericSoundEssenceDescriptor *) track->descriptor[i];
+      bwf = TRUE;
+      break;
+    } else if ((track->descriptor[i]->parent.type ==
+            MXF_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR
+            || track->descriptor[i]->parent.type ==
+            MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR
+            || track->descriptor[i]->parent.type ==
+            MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR)
+        && (track->descriptor[i]->essence_container.u[14] == 0x03
+            || track->descriptor[i]->essence_container.u[14] == 0x04
+            || track->descriptor[i]->essence_container.u[14] == 0x09)) {
+
+      s = (MXFMetadataGenericSoundEssenceDescriptor *) track->descriptor[i];
+      bwf = FALSE;
       break;
     }
   }
@@ -398,8 +753,11 @@ mxf_aes_bwf_create_caps (MXFMetadataGenericPackage * package,
   if (!s) {
     GST_ERROR ("No descriptor found for this track");
     return NULL;
-  } else if (s) {
+  } else if (bwf) {
     return mxf_bwf_create_caps (package, track, s, tags, handler, mapping_data);
+  } else {
+    return mxf_aes3_create_caps (package, track, s, tags, handler,
+        mapping_data);
   }
 
   return NULL;
index d7887e5..e158a8b 100644 (file)
@@ -30,6 +30,8 @@
 
 /* SMPTE 382M Annex 1 */
 #define MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR 0x0148
+/* SMPTE 382M Annex 2 */
+#define MXF_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR 0x0147
 
 /* SMPTE 382M Annex 1 */
 typedef struct {
@@ -55,10 +57,38 @@ typedef struct {
   guint16 peak_envelope_data_length;
 } MXFMetadataWaveAudioEssenceDescriptor;
 
+/* SMPTE 382M Annex 2 */
+typedef struct {
+  MXFMetadataWaveAudioEssenceDescriptor parent;
+
+  guint8 emphasis;
+  guint16 block_start_offset;
+  guint8 auxiliary_bits_mode;
+
+  guint32 n_channel_status_mode;
+  guint8 *channel_status_mode;
+
+  guint32 n_fixed_channel_status_data;
+  guint8 **fixed_channel_status_data;
+
+  guint32 n_user_data_mode;
+  guint8 *user_data_mode;
+
+  guint32 n_fixed_user_data;
+  guint8 **fixed_user_data;
+
+  guint32 linked_timecode_track_id;
+  guint8 stream_number;
+} MXFMetadataAES3AudioEssenceDescriptor;
+
 gboolean mxf_metadata_wave_audio_essence_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor,
     const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size);
 void mxf_metadata_wave_audio_essence_descriptor_reset (MXFMetadataWaveAudioEssenceDescriptor *descriptor);
 
+gboolean mxf_metadata_aes3_audio_essence_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor,
+    const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size);
+void mxf_metadata_aes3_audio_essence_descriptor_reset (MXFMetadataAES3AudioEssenceDescriptor *descriptor);
+
 gboolean mxf_is_aes_bwf_essence_track (const MXFMetadataTrack *track);
 
 GstCaps *
index fba453e..4b80314 100644 (file)
@@ -346,6 +346,15 @@ gst_mxf_demux_reset_metadata (GstMXFDemux * demux)
     demux->wave_audio_essence_descriptor = NULL;
   }
 
+  if (demux->aes3_audio_essence_descriptor) {
+    for (i = 0; i < demux->aes3_audio_essence_descriptor->len; i++)
+      mxf_metadata_aes3_audio_essence_descriptor_reset (&g_array_index
+          (demux->aes3_audio_essence_descriptor,
+              MXFMetadataAES3AudioEssenceDescriptor, i));
+    g_array_free (demux->aes3_audio_essence_descriptor, TRUE);
+    demux->aes3_audio_essence_descriptor = NULL;
+  }
+
   if (demux->descriptor) {
     g_ptr_array_free (demux->descriptor, TRUE);
     demux->descriptor = NULL;
@@ -1081,6 +1090,43 @@ gst_mxf_demux_handle_metadata_wave_audio_essence_descriptor (GstMXFDemux *
 }
 
 static GstFlowReturn
+gst_mxf_demux_handle_metadata_aes3_audio_essence_descriptor (GstMXFDemux *
+    demux, const MXFUL * key, guint16 type, GstBuffer * buffer)
+{
+  MXFMetadataAES3AudioEssenceDescriptor descriptor;
+
+  memset (&descriptor, 0, sizeof (descriptor));
+
+  GST_DEBUG_OBJECT (demux,
+      "Handling metadata AES3 audio essence descriptor of size %u"
+      " at offset %" G_GUINT64_FORMAT " with type 0x%04d",
+      GST_BUFFER_SIZE (buffer), demux->offset, type);
+
+  if (!mxf_metadata_descriptor_parse (key,
+          (MXFMetadataGenericDescriptor *) & descriptor, &demux->primer,
+          type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer),
+          (MXFMetadataDescriptorHandleTag)
+          mxf_metadata_aes3_audio_essence_descriptor_handle_tag,
+          (MXFMetadataDescriptorReset)
+          mxf_metadata_aes3_audio_essence_descriptor_reset)) {
+    GST_ERROR_OBJECT (demux,
+        "Parsing metadata AES3 audio essence descriptor failed");
+    return GST_FLOW_ERROR;
+  }
+
+  if (!demux->aes3_audio_essence_descriptor)
+    demux->aes3_audio_essence_descriptor =
+        g_array_new (FALSE, FALSE,
+        sizeof (MXFMetadataAES3AudioEssenceDescriptor));
+
+  g_array_append_val (demux->aes3_audio_essence_descriptor, descriptor);
+
+  return GST_FLOW_OK;
+}
+
+
+
+static GstFlowReturn
 gst_mxf_demux_handle_metadata_locator (GstMXFDemux * demux,
     const MXFUL * key, guint16 type, GstBuffer * buffer)
 {
@@ -1174,6 +1220,13 @@ gst_mxf_demux_handle_header_metadata_resolve_references (GstMXFDemux * demux)
               MXFMetadataWaveAudioEssenceDescriptor, i));
     }
   }
+  if (demux->aes3_audio_essence_descriptor) {
+    for (i = 0; i < demux->aes3_audio_essence_descriptor->len; i++) {
+      g_ptr_array_add (demux->descriptor,
+          &g_array_index (demux->aes3_audio_essence_descriptor,
+              MXFMetadataAES3AudioEssenceDescriptor, i));
+    }
+  }
   if (demux->multiple_descriptor) {
     for (i = 0; i < demux->multiple_descriptor->len; i++) {
       g_ptr_array_add (demux->descriptor,
@@ -2032,6 +2085,11 @@ gst_mxf_demux_handle_metadata (GstMXFDemux * demux, const MXFUL * key,
           gst_mxf_demux_handle_metadata_wave_audio_essence_descriptor (demux,
           key, type, buffer);
       break;
+    case MXF_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR:
+      ret =
+          gst_mxf_demux_handle_metadata_aes3_audio_essence_descriptor (demux,
+          key, type, buffer);
+      break;
     case MXF_METADATA_NETWORK_LOCATOR:
     case MXF_METADATA_TEXT_LOCATOR:
       ret = gst_mxf_demux_handle_metadata_locator (demux, key, type, buffer);
index 7b35d19..a00eb94 100644 (file)
@@ -95,6 +95,7 @@ struct _GstMXFDemux
   GArray *rgba_picture_essence_descriptor;
   GArray *mpeg_video_descriptor;
   GArray *wave_audio_essence_descriptor;
+  GArray *aes3_audio_essence_descriptor;
   GArray *multiple_descriptor;
   
   MXFUMID current_package_uid;