diff options
Diffstat (limited to 'libavcodec/aacdec.c')
-rw-r--r-- | libavcodec/aacdec.c | 89 |
1 files changed, 66 insertions, 23 deletions
diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index 3cf4a7f..b638e3b 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -7,20 +7,20 @@ * Copyright (c) 2008-2010 Paul Kendall <paul@kcbbs.gen.nz> * Copyright (c) 2010 Janne Grunau <janne-libav@jannau.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -112,7 +112,7 @@ static VLC vlc_scalefactors; static VLC vlc_spectral[11]; -static const char overread_err[] = "Input buffer exhausted before END element found\n"; +#define overread_err "Input buffer exhausted before END element found\n" static int count_channels(uint8_t (*layout)[3], int tags) { @@ -129,7 +129,7 @@ static int count_channels(uint8_t (*layout)[3], int tags) /** * Check for the channel element in the current channel position configuration. * If it exists, make sure the appropriate element is allocated and map the - * channel order to match the internal Libav channel layout. + * channel order to match the internal FFmpeg channel layout. * * @param che_pos current channel position configuration * @param type channel element type @@ -149,6 +149,10 @@ static av_cold int che_configure(AACContext *ac, ff_aac_sbr_ctx_init(ac, &ac->che[type][id]->sbr); } if (type != TYPE_CCE) { + if (*channels >= MAX_CHANNELS - (type == TYPE_CPE || (type == TYPE_SCE && ac->oc[1].m4ac.ps == 1))) { + av_log(ac->avctx, AV_LOG_ERROR, "Too many channels\n"); + return AVERROR_INVALIDDATA; + } ac->output_data[(*channels)++] = ac->che[type][id]->ch[0].ret; if (type == TYPE_CPE || (type == TYPE_SCE && ac->oc[1].m4ac.ps == 1)) { @@ -366,9 +370,11 @@ static void push_output_configuration(AACContext *ac) { */ static void pop_output_configuration(AACContext *ac) { if (ac->oc[1].status != OC_LOCKED) { - ac->oc[1] = ac->oc[0]; - ac->avctx->channels = ac->oc[1].channels; - ac->avctx->channel_layout = ac->oc[1].channels; + if (ac->oc[0].status == OC_LOCKED) { + ac->oc[1] = ac->oc[0]; + ac->avctx->channels = ac->oc[1].channels; + ac->avctx->channel_layout = ac->oc[1].channel_layout; + } } } @@ -413,13 +419,31 @@ static int output_configure(AACContext *ac, } memcpy(ac->tag_che_map, ac->che, 4 * MAX_ELEM_ID * sizeof(ac->che[0][0])); - avctx->channel_layout = ac->oc[1].channel_layout = layout; + if (layout) avctx->channel_layout = layout; + ac->oc[1].channel_layout = layout; avctx->channels = ac->oc[1].channels = channels; ac->oc[1].status = oc_type; return 0; } +static void flush(AVCodecContext *avctx) +{ + AACContext *ac= avctx->priv_data; + int type, i, j; + + for (type = 3; type >= 0; type--) { + for (i = 0; i < MAX_ELEM_ID; i++) { + ChannelElement *che = ac->che[type][i]; + if (che) { + for (j = 0; j <= 1; j++) { + memset(che->ch[j].saved, 0, sizeof(che->ch[j].saved)); + } + } + } + } +} + /** * Set up channel positions based on a default channel configuration * as specified in table 1.17. @@ -453,6 +477,8 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id) int layout_map_tags; push_output_configuration(ac); + av_log(ac->avctx, AV_LOG_DEBUG, "mono with CPE\n"); + if (set_default_channel_config(ac->avctx, layout_map, &layout_map_tags, 2) < 0) return NULL; @@ -469,6 +495,8 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id) int layout_map_tags; push_output_configuration(ac); + av_log(ac->avctx, AV_LOG_DEBUG, "stereo with SCE\n"); + if (set_default_channel_config(ac->avctx, layout_map, &layout_map_tags, 1) < 0) return NULL; @@ -547,6 +575,8 @@ static void decode_channel_map(uint8_t layout_map[][3], case AAC_CHANNEL_LFE: syn_ele = TYPE_LFE; break; + default: + av_assert0(0); } layout_map[0][0] = syn_ele; layout_map[0][1] = get_bits(gb, 4); @@ -589,6 +619,10 @@ static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac, if (get_bits1(gb)) skip_bits(gb, 3); // mixdown_coeff_index and pseudo_surround + if (get_bits_left(gb) < 4 * (num_front + num_side + num_back + num_lfe + num_assoc_data + num_cc)) { + av_log(avctx, AV_LOG_ERROR, "decode_pce: " overread_err); + return -1; + } decode_channel_map(layout_map , AAC_CHANNEL_FRONT, gb, num_front); tags = num_front; decode_channel_map(layout_map + tags, AAC_CHANNEL_SIDE, gb, num_side); @@ -608,7 +642,7 @@ static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac, /* comment field, first byte is length */ comment_len = get_bits(gb, 8) * 8; if (get_bits_left(gb) < comment_len) { - av_log(avctx, AV_LOG_ERROR, overread_err); + av_log(avctx, AV_LOG_ERROR, "decode_pce: " overread_err); return -1; } skip_bits_long(gb, comment_len); @@ -706,9 +740,9 @@ static int decode_audio_specific_config(AACContext *ac, GetBitContext gb; int i; - av_dlog(avctx, "extradata size %d\n", avctx->extradata_size); - for (i = 0; i < avctx->extradata_size; i++) - av_dlog(avctx, "%02x ", avctx->extradata[i]); + av_dlog(avctx, "audio specific config size %d\n", bit_size >> 3); + for (i = 0; i < bit_size >> 3; i++) + av_dlog(avctx, "%02x ", data[i]); av_dlog(avctx, "\n"); init_get_bits(&gb, data, bit_size); @@ -908,7 +942,7 @@ static int skip_data_stream_element(AACContext *ac, GetBitContext *gb) align_get_bits(gb); if (get_bits_left(gb) < 8 * count) { - av_log(ac->avctx, AV_LOG_ERROR, overread_err); + av_log(ac->avctx, AV_LOG_ERROR, "skip_data_stream_element: "overread_err); return -1; } skip_bits_long(gb, 8 * count); @@ -989,11 +1023,11 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics, if (ics->predictor_present) { if (ac->oc[1].m4ac.object_type == AOT_AAC_MAIN) { if (decode_prediction(ac, ics, gb)) { - return AVERROR_INVALIDDATA; + goto fail; } } else if (ac->oc[1].m4ac.object_type == AOT_AAC_LC) { av_log(ac->avctx, AV_LOG_ERROR, "Prediction is not allowed in AAC-LC.\n"); - return AVERROR_INVALIDDATA; + goto fail; } else { if ((ics->ltp.present = get_bits(gb, 1))) decode_ltp(ac, &ics->ltp, gb, ics->max_sfb); @@ -1005,10 +1039,13 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics, av_log(ac->avctx, AV_LOG_ERROR, "Number of scalefactor bands in group (%d) exceeds limit (%d).\n", ics->max_sfb, ics->num_swb); - return AVERROR_INVALIDDATA; + goto fail; } return 0; +fail: + ics->max_sfb = 0; + return AVERROR_INVALIDDATA; } /** @@ -1039,7 +1076,7 @@ static int decode_band_types(AACContext *ac, enum BandType band_type[120], sect_len_incr = get_bits(gb, bits); sect_end += sect_len_incr; if (get_bits_left(gb) < 0) { - av_log(ac->avctx, AV_LOG_ERROR, overread_err); + av_log(ac->avctx, AV_LOG_ERROR, "decode_band_types: "overread_err); return -1; } if (sect_end > ics->max_sfb) { @@ -2322,9 +2359,11 @@ static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb) size = avpriv_aac_parse_header(gb, &hdr_info); if (size > 0) { - if (hdr_info.num_aac_frames != 1) { + if (!ac->warned_num_aac_frames && hdr_info.num_aac_frames != 1) { + // This is 2 for "VLB " audio in NSV files. + // See samples/nsv/vlb_audio. av_log_missing_feature(ac->avctx, "More than one AAC RDB per ADTS frame is", 0); - return -1; + ac->warned_num_aac_frames = 1; } push_output_configuration(ac); if (hdr_info.chan_config) { @@ -2431,6 +2470,8 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, pop_output_configuration(ac); } else { err = output_configure(ac, layout_map, tags, 0, OC_TRIAL_PCE); + if (!err) + ac->oc[1].m4ac.chan_config = 0; pce_found = 1; } break; @@ -2440,7 +2481,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, if (elem_id == 15) elem_id += get_bits(gb, 8) - 1; if (get_bits_left(gb) < 8 * elem_id) { - av_log(avctx, AV_LOG_ERROR, overread_err); + av_log(avctx, AV_LOG_ERROR, "TYPE_FIL: "overread_err); err = -1; goto fail; } @@ -2521,7 +2562,7 @@ static int aac_decode_frame(AVCodecContext *avctx, void *data, AV_PKT_DATA_NEW_EXTRADATA, &new_extradata_size); - if (new_extradata) { + if (new_extradata && 0) { av_free(avctx->extradata); avctx->extradata = av_mallocz(new_extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); @@ -2852,6 +2893,7 @@ AVCodec ff_aac_decoder = { }, .capabilities = CODEC_CAP_CHANNEL_CONF | CODEC_CAP_DR1, .channel_layouts = aac_channel_layout, + .flush = flush, }; /* @@ -2873,4 +2915,5 @@ AVCodec ff_aac_latm_decoder = { }, .capabilities = CODEC_CAP_CHANNEL_CONF | CODEC_CAP_DR1, .channel_layouts = aac_channel_layout, + .flush = flush, }; |