diff options
author | Robert Swain <robert.swain@gmail.com> | 2009-01-07 22:09:21 +0000 |
---|---|---|
committer | Robert Swain <robert.swain@gmail.com> | 2009-01-07 22:09:21 +0000 |
commit | 158b39126d59f07069e0da07e0658111967c6179 (patch) | |
tree | 68f586f46acb0a2c012362cc72a2ab0fab8b1ac4 /libavcodec/aac.c | |
parent | 600a331c2718a5aed9506e395d6cf18956a28b55 (diff) | |
download | ffmpeg-158b39126d59f07069e0da07e0658111967c6179.tar.gz |
Support ADTS AAC files in the ffaac decoder (limited to streams containing one
raw_data_block() per ADTS frame)
Patch by Alex Converse ( alex converse gmail com) based on a patch by Robert
Swain ( robert swain gmail com )
Originally committed as revision 16485 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/aac.c')
-rw-r--r-- | libavcodec/aac.c | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/libavcodec/aac.c b/libavcodec/aac.c index e815041618..545f1254dd 100644 --- a/libavcodec/aac.c +++ b/libavcodec/aac.c @@ -86,6 +86,7 @@ #include "aactab.h" #include "aacdectab.h" #include "mpeg4audio.h" +#include "aac_parser.h" #include <assert.h> #include <errno.h> @@ -384,12 +385,24 @@ static av_cold int aac_decode_init(AVCodecContext * avccontext) { ac->avccontext = avccontext; - if (avccontext->extradata_size <= 0 || - decode_audio_specific_config(ac, avccontext->extradata, avccontext->extradata_size)) + if (avccontext->extradata_size > 0) { + if(decode_audio_specific_config(ac, avccontext->extradata, avccontext->extradata_size)) + return -1; + avccontext->sample_rate = ac->m4ac.sample_rate; + } else if (avccontext->channels > 0) { + enum ChannelPosition new_che_pos[4][MAX_ELEM_ID]; + memset(new_che_pos, 0, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0])); + if(set_default_channel_config(ac, new_che_pos, avccontext->channels - (avccontext->channels == 8))) + return -1; + if(output_configure(ac, ac->che_pos, new_che_pos)) + return -1; + ac->m4ac.sample_rate = avccontext->sample_rate; + } else { + ff_log_missing_feature(ac->avccontext, "Implicit channel configuration is", 0); return -1; + } avccontext->sample_fmt = SAMPLE_FMT_S16; - avccontext->sample_rate = ac->m4ac.sample_rate; avccontext->frame_size = 1024; AAC_INIT_VLC_STATIC( 0, 144); @@ -1506,6 +1519,29 @@ static void spectral_to_sample(AACContext * ac) { } } +static int parse_adts_frame_header(AACContext * ac, GetBitContext * gb) { + + int size; + AACADTSHeaderInfo hdr_info; + + size = ff_aac_parse_header(gb, &hdr_info); + if (size > 0) { + if (hdr_info.chan_config) + ac->m4ac.chan_config = hdr_info.chan_config; + ac->m4ac.sample_rate = hdr_info.sample_rate; + ac->m4ac.sampling_index = hdr_info.sampling_index; + ac->m4ac.object_type = hdr_info.object_type; + } + if (hdr_info.num_aac_frames == 1) { + if (!hdr_info.crc_absent) + skip_bits(gb, 16); + } else { + ff_log_missing_feature(ac->avccontext, "More than one AAC RDB per ADTS frame is", 0); + return -1; + } + return size; +} + static int aac_decode_frame(AVCodecContext * avccontext, void * data, int * data_size, const uint8_t * buf, int buf_size) { AACContext * ac = avccontext->priv_data; GetBitContext gb; @@ -1514,6 +1550,13 @@ static int aac_decode_frame(AVCodecContext * avccontext, void * data, int * data init_get_bits(&gb, buf, buf_size*8); + if (show_bits(&gb, 12) == 0xfff) { + if ((err = parse_adts_frame_header(ac, &gb)) < 0) { + av_log(avccontext, AV_LOG_ERROR, "Error decoding AAC frame header.\n"); + return -1; + } + } + // parse while ((elem_type = get_bits(&gb, 3)) != TYPE_END) { elem_id = get_bits(&gb, 4); |