From ff9dd4e204c467a29aafac50944a2bbc30f5963f Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Mon, 19 May 2003 20:51:12 +0000 Subject: [PATCH] Proper AAC support by stripping the ADTS headers. --- ChangeLog | 5 +++++ aac_common.cpp | 4 +++- aac_common.h | 4 ++-- matroska.h | 7 +++++- p_aac.cpp | 58 ++++++++++++++++++++++++++++++++++++++++---------- p_aac.h | 8 +++---- r_aac.cpp | 6 +++--- 7 files changed, 70 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index cfb975fb7..c634ddccc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2003-05-19 Moritz Bunkus + + * ADTS headers are stripped from the AAC streams. This is what I'd + call 'proper AAC support'. + 2003-05-18 Moritz Bunkus * Better support for DTS streams in general and for DTS-in-WAV in diff --git a/aac_common.cpp b/aac_common.cpp index bc4389541..7251e2202 100644 --- a/aac_common.cpp +++ b/aac_common.cpp @@ -13,7 +13,7 @@ /*! \file - \version \$Id: aac_common.cpp,v 1.4 2003/05/19 18:24:52 mosu Exp $ + \version \$Id: aac_common.cpp,v 1.5 2003/05/19 20:51:12 mosu Exp $ \brief helper function for AAC data \author Moritz Bunkus */ @@ -159,6 +159,8 @@ static int is_adts_header(unsigned char *buf, int size, int bpos, if (!protection_absent) aac_header->header_bit_size += 16; aac_header->header_byte_size = (aac_header->header_bit_size + 7) / 8; + aac_header->data_byte_size = aac_header->bytes - + aac_header->header_bit_size / 8; return 1; } diff --git a/aac_common.h b/aac_common.h index 5bae04d72..df315daa3 100644 --- a/aac_common.h +++ b/aac_common.h @@ -13,7 +13,7 @@ /*! \file - \version \$Id: aac_common.h,v 1.3 2003/05/18 20:57:07 mosu Exp $ + \version \$Id: aac_common.h,v 1.4 2003/05/19 20:51:12 mosu Exp $ \brief definitions and helper functions for AAC data \author Moritz Bunkus */ @@ -28,7 +28,7 @@ typedef struct { int bytes; int id; // 0 = MPEG-4, 1 = MPEG-2 int profile; - int header_bit_size, header_byte_size; + int header_bit_size, header_byte_size, data_byte_size; } aac_header_t; int parse_aac_adif_header(unsigned char *buf, int size, diff --git a/matroska.h b/matroska.h index b91d2a891..9f8268da3 100644 --- a/matroska.h +++ b/matroska.h @@ -13,7 +13,7 @@ /*! \file - \version \$Id: matroska.h,v 1.12 2003/05/18 20:57:07 mosu Exp $ + \version \$Id: matroska.h,v 1.13 2003/05/19 20:51:12 mosu Exp $ \brief Definitions for the various Codec IDs \author Moritz Bunkus */ @@ -23,8 +23,13 @@ // see http://cvs.corecodec.org/cgi-bin/cvsweb.cgi/~checkout~/matroska/doc/website/specs/codex.html?rev=HEAD&content-type=text/html +#define MKV_A_AAC_2MAIN "A_AAC/MPEG2/MAIN" #define MKV_A_AAC_2LC "A_AAC/MPEG2/LC" +#define MKV_A_AAC_2SSR "A_AAC/MPEG2/SSR" +#define MKV_A_AAC_4MAIN "A_AAC/MPEG4/MAIN" #define MKV_A_AAC_4LC "A_AAC/MPEG4/LC" +#define MKV_A_AAC_4SSR "A_AAC/MPEG4/SSR" +#define MKV_A_AAC_4LTP "A_AAC/MPEG4/LTP" #define MKV_A_AAC_4SBR "A_AAC/MPEG4/SBR" #define MKV_A_AC3 "A_AC3" #define MKV_A_DTS "A_DTS" diff --git a/p_aac.cpp b/p_aac.cpp index 576b3fa9d..451cac945 100644 --- a/p_aac.cpp +++ b/p_aac.cpp @@ -13,7 +13,7 @@ /*! \file - \version \$Id: p_aac.cpp,v 1.3 2003/05/18 20:57:07 mosu Exp $ + \version \$Id: p_aac.cpp,v 1.4 2003/05/19 20:51:12 mosu Exp $ \brief AAC output module \author Moritz Bunkus */ @@ -31,8 +31,9 @@ using namespace LIBMATROSKA_NAMESPACE; aac_packetizer_c::aac_packetizer_c(generic_reader_c *nreader, int nid, + int nprofile, unsigned long nsamples_per_sec, - int nchannels, int adif, track_info_t *nti) + int nchannels, track_info_t *nti) throw (error_c): generic_packetizer_c(nreader, nti) { packetno = 0; bytes_output = 0; @@ -41,7 +42,7 @@ aac_packetizer_c::aac_packetizer_c(generic_reader_c *nreader, int nid, samples_per_sec = nsamples_per_sec; channels = nchannels; id = nid; - is_adif = adif; + profile = nprofile; set_track_type(track_audio); duplicate_data_on_add(false); @@ -92,8 +93,8 @@ void aac_packetizer_c::remove_aac_packet(int pos, int framesize) { unsigned char *aac_packetizer_c::get_aac_packet(unsigned long *header, aac_header_t *aacheader) { - int pos; - unsigned char *buf; + int pos, i, up_shift, down_shift; + unsigned char *buf, *src; double pims; if (packet_buffer == NULL) @@ -125,7 +126,25 @@ unsigned char *aac_packetizer_c::get_aac_packet(unsigned long *header, fprintf(stdout, "aac_packetizer: skipping %d bytes (no valid AAC header " "found). This might make audio/video go out of sync, but this " "stream is damaged.\n", pos); - buf = (unsigned char *)safememdup(packet_buffer + pos, aacheader->bytes); + if ((aacheader->header_bit_size % 8) == 0) + buf = (unsigned char *)safememdup(packet_buffer + pos + + aacheader->header_byte_size, + aacheader->data_byte_size); + else { + // Header is not byte aligned, i.e. MPEG-4 ADTS + // This code is from mpeg4ip/server/mp4creator/aac.cpp + up_shift = aacheader->header_bit_size % 8; + down_shift = 8 - up_shift; + src = packet_buffer + pos + aacheader->header_bit_size / 8; + + buf = (unsigned char *)safemalloc(aacheader->data_byte_size); + + buf[0] = src[0] << up_shift; + for (i = 1; i < aacheader->data_byte_size; i++) { + buf[i - 1] |= (src[i] >> down_shift); + buf[i] = (src[i] << up_shift); + } + } if (ti->async.displacement > 0) { /* @@ -148,10 +167,27 @@ unsigned char *aac_packetizer_c::get_aac_packet(unsigned long *header, } void aac_packetizer_c::set_headers() { - if (id == 0) - set_codec_id(MKV_A_AAC_4LC); - else - set_codec_id(MKV_A_AAC_2LC); + if (id == 0) { + if (profile == 0) + set_codec_id(MKV_A_AAC_4MAIN); + else if (profile == 1) + set_codec_id(MKV_A_AAC_4LC); + else if (profile == 2) + set_codec_id(MKV_A_AAC_4SSR); + else if (profile == 3) + set_codec_id(MKV_A_AAC_4LTP); + else + die("aac_packetizer: Unknown AAC MPEG-4 object type..."); + } else { + if (profile == 0) + set_codec_id(MKV_A_AAC_2MAIN); + else if (profile == 1) + set_codec_id(MKV_A_AAC_2LC); + else if (profile == 2) + set_codec_id(MKV_A_AAC_2SSR); + else + die("aac_packetizer: Unknown AAC MPEG-2 profile..."); + } set_audio_sampling_freq((float)samples_per_sec); set_audio_channels(channels); @@ -174,7 +210,7 @@ int aac_packetizer_c::process(unsigned char *buf, int size, my_timecode = (int64_t)(1000.0 * packetno * 1024 * ti->async.linear / samples_per_sec); - add_packet(packet, aacheader.bytes, my_timecode, + add_packet(packet, aacheader.data_byte_size, my_timecode, (int64_t)(1000.0 * 1024 * ti->async.linear / samples_per_sec)); packetno++; } diff --git a/p_aac.h b/p_aac.h index 5b87e4a86..5b87b861d 100644 --- a/p_aac.h +++ b/p_aac.h @@ -13,7 +13,7 @@ /*! \file - \version \$Id: p_aac.h,v 1.3 2003/05/18 20:57:07 mosu Exp $ + \version \$Id: p_aac.h,v 1.4 2003/05/19 20:51:12 mosu Exp $ \brief class definition for the AAC output module \author Moritz Bunkus */ @@ -29,12 +29,12 @@ class aac_packetizer_c: public generic_packetizer_c { private: int64_t bytes_output, packetno; unsigned long samples_per_sec; - int channels, buffer_size, id, is_adif; + int channels, buffer_size, id, profile; unsigned char *packet_buffer; public: - aac_packetizer_c(generic_reader_c *nreader, int nid, - unsigned long nsamples_per_sec, int nchannels, int adif, + aac_packetizer_c(generic_reader_c *nreader, int nid, int nprofile, + unsigned long nsamples_per_sec, int nchannels, track_info_t *nti) throw (error_c); virtual ~aac_packetizer_c(); diff --git a/r_aac.cpp b/r_aac.cpp index d1ca3b55b..e1c6f73f4 100644 --- a/r_aac.cpp +++ b/r_aac.cpp @@ -13,7 +13,7 @@ /*! \file - \version \$Id: r_aac.cpp,v 1.3 2003/05/18 20:57:07 mosu Exp $ + \version \$Id: r_aac.cpp,v 1.4 2003/05/19 20:51:12 mosu Exp $ \brief AAC demultiplexer module \author Moritz Bunkus */ @@ -77,9 +77,9 @@ aac_reader_c::aac_reader_c(track_info_t *nti) throw (error_c): else adif = 0; bytes_processed = 0; - aacpacketizer = new aac_packetizer_c(this, aacheader.id, + aacpacketizer = new aac_packetizer_c(this, aacheader.id, aacheader.profile, aacheader.sample_rate, - aacheader.channels, adif, ti); + aacheader.channels, ti); if (verbose) fprintf(stdout, "Using AAC demultiplexer for %s.\n+-> Using " \ "AAC output module for audio stream.\n", ti->fname);