diff --git a/libavcodec/aac/Makefile b/libavcodec/aac/Makefile index 52facdf4cf..29e0ef0a2c 100644 --- a/libavcodec/aac/Makefile +++ b/libavcodec/aac/Makefile @@ -1,5 +1,5 @@ clean:: $(RM) $(CLEANSUFFIXES:%=libavcodec/aac/%) -OBJS-$(CONFIG_AAC_DECODER) += aac/aacdec_tab.o -OBJS-$(CONFIG_AAC_FIXED_DECODER) += aac/aacdec_tab.o +OBJS-$(CONFIG_AAC_DECODER) += aac/aacdec.o aac/aacdec_tab.o +OBJS-$(CONFIG_AAC_FIXED_DECODER) += aac/aacdec.o aac/aacdec_tab.o diff --git a/libavcodec/aac/aacdec.c b/libavcodec/aac/aacdec.c new file mode 100644 index 0000000000..021f94e1e5 --- /dev/null +++ b/libavcodec/aac/aacdec.c @@ -0,0 +1,71 @@ +/* + * Common parts of the AAC decoders + * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) + * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) + * Copyright (c) 2008-2013 Alex Converse + * + * AAC LATM decoder + * Copyright (c) 2008-2010 Paul Kendall + * Copyright (c) 2010 Janne Grunau + * + * AAC decoder fixed-point implementation + * Copyright (c) 2013 + * MIPS Technologies, Inc., California. + * + * This file is part of FFmpeg. + * + * 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. + * + * 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavcodec/aacsbr.h" +#include "libavcodec/aacdec.h" +#include "libavcodec/avcodec.h" +#include "libavutil/attributes.h" +#include "libavutil/macros.h" +#include "libavutil/mem.h" +#include "libavutil/tx.h" + +av_cold int ff_aac_decode_close(AVCodecContext *avctx) +{ + AACDecContext *ac = avctx->priv_data; + int is_fixed = ac->is_fixed; + void (*sbr_close)(ChannelElement *che) = is_fixed ? RENAME_FIXED(ff_aac_sbr_ctx_close) + : ff_aac_sbr_ctx_close; + + for (int type = 0; type < FF_ARRAY_ELEMS(ac->che); type++) { + for (int i = 0; i < MAX_ELEM_ID; i++) { + if (ac->che[type][i]) { + sbr_close(ac->che[type][i]); + av_freep(&ac->che[type][i]); + } + } + } + + av_tx_uninit(&ac->mdct120); + av_tx_uninit(&ac->mdct128); + av_tx_uninit(&ac->mdct480); + av_tx_uninit(&ac->mdct512); + av_tx_uninit(&ac->mdct960); + av_tx_uninit(&ac->mdct1024); + av_tx_uninit(&ac->mdct_ltp); + + // Compiler will optimize this branch away. + if (is_fixed) + av_freep(&ac->RENAME_FIXED(fdsp)); + else + av_freep(&ac->fdsp); + + return 0; +} diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index 17931cfd1c..7db17ffbb1 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -557,7 +557,7 @@ const FFCodec ff_aac_decoder = { .p.id = AV_CODEC_ID_AAC, .priv_data_size = sizeof(AACDecContext), .init = aac_decode_init, - .close = aac_decode_close, + .close = ff_aac_decode_close, FF_CODEC_DECODE_CB(aac_decode_frame), .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE @@ -582,7 +582,7 @@ const FFCodec ff_aac_latm_decoder = { .p.id = AV_CODEC_ID_AAC_LATM, .priv_data_size = sizeof(struct LATMContext), .init = latm_decode_init, - .close = aac_decode_close, + .close = ff_aac_decode_close, FF_CODEC_DECODE_CB(latm_decode_frame), .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE diff --git a/libavcodec/aacdec.h b/libavcodec/aacdec.h index fbdf688487..cb9d1637b3 100644 --- a/libavcodec/aacdec.h +++ b/libavcodec/aacdec.h @@ -278,6 +278,8 @@ typedef struct AACDecContext { int warned_gain_control; int warned_he_aac_mono; + int is_fixed; + /* aacdec functions pointers */ void (*imdct_and_windowing)(struct AACDecContext *ac, SingleChannelElement *sce); void (*apply_ltp)(struct AACDecContext *ac, SingleChannelElement *sce); @@ -302,6 +304,8 @@ typedef struct AACDecContext { #define fdsp RENAME_FIXED(fdsp) #endif +int ff_aac_decode_close(struct AVCodecContext *avctx); + void ff_aacdec_init_mips(AACDecContext *c); #endif /* AVCODEC_AACDEC_H */ diff --git a/libavcodec/aacdec_fixed.c b/libavcodec/aacdec_fixed.c index 5efb259665..4a5f678bca 100644 --- a/libavcodec/aacdec_fixed.c +++ b/libavcodec/aacdec_fixed.c @@ -500,7 +500,7 @@ const FFCodec ff_aac_fixed_decoder = { .p.id = AV_CODEC_ID_AAC, .priv_data_size = sizeof(AACDecContext), .init = aac_decode_init, - .close = aac_decode_close, + .close = ff_aac_decode_close, FF_CODEC_DECODE_CB(aac_decode_frame), .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P, AV_SAMPLE_FMT_NONE diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c index 5cbf9b3340..adcd51436c 100644 --- a/libavcodec/aacdec_template.c +++ b/libavcodec/aacdec_template.c @@ -1149,6 +1149,8 @@ static av_cold int aac_decode_init(AVCodecContext *avctx) AACDecContext *ac = avctx->priv_data; int ret; + ac->is_fixed = USE_FIXED; + if (avctx->sample_rate > 96000) return AVERROR_INVALIDDATA; @@ -3381,31 +3383,6 @@ static int aac_decode_frame(AVCodecContext *avctx, AVFrame *frame, return buf_size > buf_offset ? buf_consumed : buf_size; } -static av_cold int aac_decode_close(AVCodecContext *avctx) -{ - AACDecContext *ac = avctx->priv_data; - int i, type; - - for (i = 0; i < MAX_ELEM_ID; i++) { - for (type = 0; type < 4; type++) { - if (ac->che[type][i]) - AAC_RENAME(ff_aac_sbr_ctx_close)(ac->che[type][i]); - av_freep(&ac->che[type][i]); - } - } - - av_tx_uninit(&ac->mdct120); - av_tx_uninit(&ac->mdct128); - av_tx_uninit(&ac->mdct480); - av_tx_uninit(&ac->mdct512); - av_tx_uninit(&ac->mdct960); - av_tx_uninit(&ac->mdct1024); - av_tx_uninit(&ac->mdct_ltp); - - av_freep(&ac->fdsp); - return 0; -} - static void aacdec_init(AACDecContext *c) { c->imdct_and_windowing = imdct_and_windowing; diff --git a/libavcodec/aacsbr.h b/libavcodec/aacsbr.h index 855885ce87..4ace1e04d4 100644 --- a/libavcodec/aacsbr.h +++ b/libavcodec/aacsbr.h @@ -33,6 +33,8 @@ #include "aacdec.h" #include "aac_defines.h" +#include "libavutil/attributes_internal.h" + #define ENVELOPE_ADJUSTMENT_OFFSET 2 #define NOISE_FLOOR_OFFSET 6 @@ -66,6 +68,7 @@ enum { EXTENSION_ID_PS = 2, }; +FF_VISIBILITY_PUSH_HIDDEN /** Initialize SBR. */ void AAC_RENAME(ff_aac_sbr_init)(void); /** @@ -73,13 +76,17 @@ void AAC_RENAME(ff_aac_sbr_init)(void); * initialize the SBR context contained in it. */ int AAC_RENAME(ff_aac_sbr_ctx_alloc_init)(AACDecContext *ac, ChannelElement **che, int id_aac); -/** Close one SBR context. */ -void AAC_RENAME(ff_aac_sbr_ctx_close)(ChannelElement *che); + +/** Close the SBR context implicitly contained in a ChannelElement. */ +void RENAME_FIXED(ff_aac_sbr_ctx_close)(ChannelElement *che); +void ff_aac_sbr_ctx_close(ChannelElement *che); + /** Decode one SBR element. */ int AAC_RENAME(ff_aac_sbr_decode_extension)(AACDecContext *ac, ChannelElement *che, GetBitContext *gb, int crc, int cnt, int id_aac); /** Apply one SBR element to one AAC element. */ void AAC_RENAME(ff_aac_sbr_apply)(AACDecContext *ac, ChannelElement *che, int id_aac, INTFLOAT* L, INTFLOAT* R); +FF_VISIBILITY_POP_HIDDEN #endif /* AVCODEC_AACSBR_H */