From 7caee063a0b71a2b9bdd21f508bb39b6b7a83ceb Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Thu, 3 Jun 2010 02:17:49 +0000 Subject: [PATCH] aacdec: Work around illegal files with all elem_id tags set to the same value. Fixes issue 1882. Originally committed as revision 23439 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/aac.c | 17 +++++++++++++++++ libavcodec/aac.h | 1 + 2 files changed, 18 insertions(+) diff --git a/libavcodec/aac.c b/libavcodec/aac.c index bfe766c..d510fcf 100644 --- a/libavcodec/aac.c +++ b/libavcodec/aac.c @@ -113,6 +113,22 @@ static const char overread_err[] = "Input buffer exhausted before END element fo static ChannelElement *get_che(AACContext *ac, int type, int elem_id) { + /* Some buggy encoders appear to set all elem_ids to zero and rely on + channels always occurring in the same order. This is expressly forbidden + by the spec but we will try to work around it. + */ + int err_printed = 0; + while (ac->tags_seen_this_frame[type][elem_id] && elem_id < MAX_ELEM_ID) { + if (ac->output_configured < OC_LOCKED && !err_printed) { + av_log(ac->avccontext, AV_LOG_WARNING, "Duplicate channel tag found, attempting to remap.\n"); + err_printed = 1; + } + elem_id++; + } + if (elem_id == MAX_ELEM_ID) + return NULL; + ac->tags_seen_this_frame[type][elem_id] = 1; + if (ac->tag_che_map[type][elem_id]) { return ac->tag_che_map[type][elem_id]; } @@ -1969,6 +1985,7 @@ static int aac_decode_frame(AVCodecContext *avccontext, void *data, } } + memset(ac->tags_seen_this_frame, 0, sizeof(ac->tags_seen_this_frame)); // parse while ((elem_type = get_bits(&gb, 3)) != TYPE_END) { elem_id = get_bits(&gb, 4); diff --git a/libavcodec/aac.h b/libavcodec/aac.h index 1a8aa6c..3f3f783 100644 --- a/libavcodec/aac.h +++ b/libavcodec/aac.h @@ -257,6 +257,7 @@ typedef struct { */ ChannelElement * che[4][MAX_ELEM_ID]; ChannelElement * tag_che_map[4][MAX_ELEM_ID]; + uint8_t tags_seen_this_frame[4][MAX_ELEM_ID]; int tags_mapped; /** @} */ -- 2.7.4