mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
gst/mxf/: Add support for AES3 audio (SMPTE 382M).
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.
This commit is contained in:
parent
bc1fdfd0bd
commit
7f61ced7e6
5 changed files with 472 additions and 6 deletions
19
ChangeLog
19
ChangeLog
|
@ -1,3 +1,22 @@
|
||||||
|
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>
|
2008-12-03 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||||
|
|
||||||
* gst/mxf/mxfdemux.c:
|
* gst/mxf/mxfdemux.c:
|
||||||
|
|
|
@ -184,6 +184,272 @@ void mxf_metadata_wave_audio_essence_descriptor_reset
|
||||||
MXFMetadataGenericSoundEssenceDescriptor);
|
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
|
gboolean
|
||||||
mxf_is_aes_bwf_essence_track (const MXFMetadataTrack * track)
|
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;
|
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 */
|
/* SMPTE RP224 */
|
||||||
static const MXFUL mxf_sound_essence_compression_uncompressed =
|
static const MXFUL mxf_sound_essence_compression_uncompressed =
|
||||||
{ {0x06, 0x0E, 0x2B, 0x34, 0x04, 0x01, 0x01, 0x01, 0x04, 0x02, 0x02, 0x01,
|
{ {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)
|
MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR)
|
||||||
wa_descriptor = (MXFMetadataWaveAudioEssenceDescriptor *) descriptor;
|
wa_descriptor = (MXFMetadataWaveAudioEssenceDescriptor *) descriptor;
|
||||||
|
|
||||||
/* TODO: set caps for avg bitrate, audio codec, ...... */
|
|
||||||
/* TODO: Handle width=!depth, needs shifting of samples */
|
/* TODO: Handle width=!depth, needs shifting of samples */
|
||||||
|
|
||||||
/* FIXME: set a channel layout */
|
/* FIXME: set a channel layout */
|
||||||
|
@ -281,7 +567,7 @@ mxf_bwf_create_caps (MXFMetadataGenericPackage * package,
|
||||||
GST_ERROR ("Invalid descriptor");
|
GST_ERROR ("Invalid descriptor");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (wa_descriptor)
|
if (wa_descriptor && wa_descriptor->block_align != 0)
|
||||||
block_align = wa_descriptor->block_align;
|
block_align = wa_descriptor->block_align;
|
||||||
else
|
else
|
||||||
block_align = GST_ROUND_UP_8 (descriptor->quantization_bits) / 8;
|
block_align = GST_ROUND_UP_8 (descriptor->quantization_bits) / 8;
|
||||||
|
@ -310,7 +596,7 @@ mxf_bwf_create_caps (MXFMetadataGenericPackage * package,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wa_descriptor)
|
if (wa_descriptor && wa_descriptor->block_align != 0)
|
||||||
block_align = wa_descriptor->block_align;
|
block_align = wa_descriptor->block_align;
|
||||||
else
|
else
|
||||||
block_align = GST_ROUND_UP_8 (descriptor->quantization_bits) / 8;
|
block_align = GST_ROUND_UP_8 (descriptor->quantization_bits) / 8;
|
||||||
|
@ -364,12 +650,69 @@ mxf_bwf_create_caps (MXFMetadataGenericPackage * package,
|
||||||
return ret;
|
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 *
|
GstCaps *
|
||||||
mxf_aes_bwf_create_caps (MXFMetadataGenericPackage * package,
|
mxf_aes_bwf_create_caps (MXFMetadataGenericPackage * package,
|
||||||
MXFMetadataTrack * track, GstTagList ** tags,
|
MXFMetadataTrack * track, GstTagList ** tags,
|
||||||
MXFEssenceElementHandler * handler, gpointer * mapping_data)
|
MXFEssenceElementHandler * handler, gpointer * mapping_data)
|
||||||
{
|
{
|
||||||
MXFMetadataGenericSoundEssenceDescriptor *s = NULL;
|
MXFMetadataGenericSoundEssenceDescriptor *s = NULL;
|
||||||
|
gboolean bwf = FALSE;
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
g_return_val_if_fail (package != NULL, NULL);
|
g_return_val_if_fail (package != NULL, NULL);
|
||||||
|
@ -380,8 +723,6 @@ mxf_aes_bwf_create_caps (MXFMetadataGenericPackage * package,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: handle AES3 audio */
|
|
||||||
|
|
||||||
for (i = 0; i < track->n_descriptor; i++) {
|
for (i = 0; i < track->n_descriptor; i++) {
|
||||||
if ((track->descriptor[i]->parent.type ==
|
if ((track->descriptor[i]->parent.type ==
|
||||||
MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR
|
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] == 0x02
|
||||||
|| track->descriptor[i]->essence_container.u[14] == 0x08)) {
|
|| track->descriptor[i]->essence_container.u[14] == 0x08)) {
|
||||||
s = (MXFMetadataGenericSoundEssenceDescriptor *) track->descriptor[i];
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -398,8 +753,11 @@ mxf_aes_bwf_create_caps (MXFMetadataGenericPackage * package,
|
||||||
if (!s) {
|
if (!s) {
|
||||||
GST_ERROR ("No descriptor found for this track");
|
GST_ERROR ("No descriptor found for this track");
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (s) {
|
} else if (bwf) {
|
||||||
return mxf_bwf_create_caps (package, track, s, tags, handler, mapping_data);
|
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;
|
return NULL;
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
|
|
||||||
/* SMPTE 382M Annex 1 */
|
/* SMPTE 382M Annex 1 */
|
||||||
#define MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR 0x0148
|
#define MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR 0x0148
|
||||||
|
/* SMPTE 382M Annex 2 */
|
||||||
|
#define MXF_METADATA_AES3_AUDIO_ESSENCE_DESCRIPTOR 0x0147
|
||||||
|
|
||||||
/* SMPTE 382M Annex 1 */
|
/* SMPTE 382M Annex 1 */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -55,10 +57,38 @@ typedef struct {
|
||||||
guint16 peak_envelope_data_length;
|
guint16 peak_envelope_data_length;
|
||||||
} MXFMetadataWaveAudioEssenceDescriptor;
|
} 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,
|
gboolean mxf_metadata_wave_audio_essence_descriptor_handle_tag (MXFMetadataGenericDescriptor *descriptor,
|
||||||
const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size);
|
const MXFPrimerPack *primer, guint16 tag, const guint8 *tag_data, guint16 tag_size);
|
||||||
void mxf_metadata_wave_audio_essence_descriptor_reset (MXFMetadataWaveAudioEssenceDescriptor *descriptor);
|
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);
|
gboolean mxf_is_aes_bwf_essence_track (const MXFMetadataTrack *track);
|
||||||
|
|
||||||
GstCaps *
|
GstCaps *
|
||||||
|
|
|
@ -346,6 +346,15 @@ gst_mxf_demux_reset_metadata (GstMXFDemux * demux)
|
||||||
demux->wave_audio_essence_descriptor = NULL;
|
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) {
|
if (demux->descriptor) {
|
||||||
g_ptr_array_free (demux->descriptor, TRUE);
|
g_ptr_array_free (demux->descriptor, TRUE);
|
||||||
demux->descriptor = NULL;
|
demux->descriptor = NULL;
|
||||||
|
@ -1080,6 +1089,43 @@ gst_mxf_demux_handle_metadata_wave_audio_essence_descriptor (GstMXFDemux *
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static GstFlowReturn
|
||||||
gst_mxf_demux_handle_metadata_locator (GstMXFDemux * demux,
|
gst_mxf_demux_handle_metadata_locator (GstMXFDemux * demux,
|
||||||
const MXFUL * key, guint16 type, GstBuffer * buffer)
|
const MXFUL * key, guint16 type, GstBuffer * buffer)
|
||||||
|
@ -1174,6 +1220,13 @@ gst_mxf_demux_handle_header_metadata_resolve_references (GstMXFDemux * demux)
|
||||||
MXFMetadataWaveAudioEssenceDescriptor, i));
|
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) {
|
if (demux->multiple_descriptor) {
|
||||||
for (i = 0; i < demux->multiple_descriptor->len; i++) {
|
for (i = 0; i < demux->multiple_descriptor->len; i++) {
|
||||||
g_ptr_array_add (demux->descriptor,
|
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,
|
gst_mxf_demux_handle_metadata_wave_audio_essence_descriptor (demux,
|
||||||
key, type, buffer);
|
key, type, buffer);
|
||||||
break;
|
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_NETWORK_LOCATOR:
|
||||||
case MXF_METADATA_TEXT_LOCATOR:
|
case MXF_METADATA_TEXT_LOCATOR:
|
||||||
ret = gst_mxf_demux_handle_metadata_locator (demux, key, type, buffer);
|
ret = gst_mxf_demux_handle_metadata_locator (demux, key, type, buffer);
|
||||||
|
|
|
@ -95,6 +95,7 @@ struct _GstMXFDemux
|
||||||
GArray *rgba_picture_essence_descriptor;
|
GArray *rgba_picture_essence_descriptor;
|
||||||
GArray *mpeg_video_descriptor;
|
GArray *mpeg_video_descriptor;
|
||||||
GArray *wave_audio_essence_descriptor;
|
GArray *wave_audio_essence_descriptor;
|
||||||
|
GArray *aes3_audio_essence_descriptor;
|
||||||
GArray *multiple_descriptor;
|
GArray *multiple_descriptor;
|
||||||
|
|
||||||
MXFUMID current_package_uid;
|
MXFUMID current_package_uid;
|
||||||
|
|
Loading…
Reference in a new issue