Mercurial > libavcodec.hg
diff aac.c @ 8549:2cbfa4cd4670 libavcodec
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 )
author | superdump |
---|---|
date | Wed, 07 Jan 2009 22:09:21 +0000 |
parents | e6909fa99317 |
children | 7a463923ecd1 |
line wrap: on
line diff
--- a/aac.c Wed Jan 07 19:55:08 2009 +0000 +++ b/aac.c Wed Jan 07 22:09:21 2009 +0000 @@ -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 @@ 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 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 @@ 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);