From a32877125f0f70d74554d10a7a909f5b4e72f8e1 Mon Sep 17 00:00:00 2001 From: Akihiro Tsukada Date: Fri, 22 Feb 2013 21:02:19 +0900 Subject: [PATCH] audio: add support for AAC pass-through https://bugzilla.gnome.org/show_bug.cgi?id=694443 --- gst-libs/gst/audio/gstaudioiec61937.c | 42 +++++++++++++++++++++++++ gst-libs/gst/audio/gstaudioringbuffer.c | 15 ++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/audio/gstaudioiec61937.c b/gst-libs/gst/audio/gstaudioiec61937.c index ebd0d3317f..b1ad046980 100644 --- a/gst-libs/gst/audio/gstaudioiec61937.c +++ b/gst-libs/gst/audio/gstaudioiec61937.c @@ -40,6 +40,7 @@ #define IEC61937_HEADER_SIZE 8 #define IEC61937_PAYLOAD_SIZE_AC3 (1536 * 4) #define IEC61937_PAYLOAD_SIZE_EAC3 (6144 * 4) +#define IEC61937_PAYLOAD_SIZE_AAC (1024 * 4) static gint caps_get_int_field (const GstCaps * caps, const gchar * field) @@ -123,6 +124,12 @@ gst_audio_iec61937_frame_size (const GstAudioRingBufferSpec * spec) return frames * 4; } + case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG2_AAC: + case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG4_AAC: + { + return IEC61937_PAYLOAD_SIZE_AAC; + } + default: return 0; } @@ -287,6 +294,41 @@ gst_audio_iec61937_payload (const guint8 * src, guint src_n, guint8 * dst, break; } + case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG2_AAC: + /* HACK. disguising MPEG4 AAC as MPEG2 AAC seems to work. */ + /* TODO: set the right Pc,Pd for MPEG4 in accordance with IEC61937-6 */ + case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG4_AAC: + { + int num_rd_blks; + + g_return_val_if_fail (src_n >= 7, FALSE); + num_rd_blks = (src[6] & 0x03) + 1; + + /* Pc: bit 13-15 - stream number (0) + * bit 11-12 - reserved (0) + * bit 8-10 - reserved? (0) */ + dst[four] = 0; + /* Pc: bit 7 - error bit (0) + * bit 5-6 - reserved (0) + * bit 0-4 - data type (07 = MPEG2 AAC ADTS + * 19 = MPEG2 AAC ADTS half-rate LSF + * 51 = MPEG2 AAC ADTS quater-rate LSF */ + if (num_rd_blks == 1) + dst[five] = 0x07; + else if (num_rd_blks == 2) + dst[five] = 0x13; + else if (num_rd_blks == 4) + dst[five] = 0x33; + else + g_return_val_if_reached (FALSE); + + /* Pd: bit 15-0 - frame size in bits */ + tmp = GST_ROUND_UP_2 (src_n) * 8; + dst[six] = (guint8) (tmp >> 8); + dst[seven] = (guint8) (tmp & 0xff); + break; + } + default: return FALSE; } diff --git a/gst-libs/gst/audio/gstaudioringbuffer.c b/gst-libs/gst/audio/gstaudioringbuffer.c index 3c7884e215..8f7e5980af 100644 --- a/gst-libs/gst/audio/gstaudioringbuffer.c +++ b/gst-libs/gst/audio/gstaudioringbuffer.c @@ -124,7 +124,9 @@ static const gchar *format_type_names[] = { "iec958", "ac3", "eac3", - "dts" + "dts", + "aac mpeg2", + "aac mpeg4" }; #endif @@ -263,6 +265,17 @@ gst_audio_ring_buffer_parse_caps (GstAudioRingBufferSpec * spec, GstCaps * caps) spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG; info.bpf = 4; + } else if (g_str_equal (mimetype, "audio/mpeg") && + gst_structure_get_int (structure, "mpegversion", &i) && + (i == 2 || i == 4) && + !g_strcmp0 (gst_structure_get_string (structure, "stream-format"), + "adts")) { + /* MPEG-2 AAC or MPEG-4 AAC */ + if (!(gst_structure_get_int (structure, "rate", &info.rate))) + goto parse_error; + spec->type = (i == 2) ? GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG2_AAC : + GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG4_AAC; + info.bpf = 4; } else { goto parse_error; }