aacdec: fully detemplate decoder core
This commit is contained in:
parent
2f90d83981
commit
e93793bf3c
@ -184,7 +184,7 @@ OBJS-$(CONFIG_AAC_DECODER) += aacdec.o aactab.o \
|
||||
aacsbr.o aacps_common.o aacps_float.o \
|
||||
kbdwin.o \
|
||||
sbrdsp.o aacpsdsp_float.o cbrt_data.o
|
||||
OBJS-$(CONFIG_AAC_FIXED_DECODER) += aacdec_fixed.o aactab.o \
|
||||
OBJS-$(CONFIG_AAC_FIXED_DECODER) += aactab.o \
|
||||
aacsbr_fixed.o aacps_common.o aacps_fixed.o \
|
||||
kbdwin.o \
|
||||
sbrdsp_fixed.o aacpsdsp_fixed.o cbrt_data_fixed.o
|
||||
|
@ -385,7 +385,7 @@ static int AAC_RENAME(decode_cce)(AACDecContext *ac, GetBitContext *gb, ChannelE
|
||||
scale = cce_scale[get_bits(gb, 2)];
|
||||
#endif
|
||||
|
||||
if ((ret = AAC_RENAME(ff_aac_decode_ics)(ac, sce, gb, 0, 0)))
|
||||
if ((ret = ff_aac_decode_ics(ac, sce, gb, 0, 0)))
|
||||
return ret;
|
||||
|
||||
for (c = 0; c < num_gain; c++) {
|
||||
|
@ -32,7 +32,7 @@
|
||||
* @author Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
*/
|
||||
|
||||
#define USE_FIXED 0
|
||||
#define USE_FIXED 1 // aacsbr.h breaks without this
|
||||
|
||||
#include "libavutil/float_dsp.h"
|
||||
#include "avcodec.h"
|
||||
@ -399,3 +399,23 @@ const FFCodec ff_aac_latm_decoder = {
|
||||
.flush = flush,
|
||||
.p.profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
|
||||
};
|
||||
|
||||
const FFCodec ff_aac_fixed_decoder = {
|
||||
.p.name = "aac_fixed",
|
||||
CODEC_LONG_NAME("AAC (Advanced Audio Coding)"),
|
||||
.p.type = AVMEDIA_TYPE_AUDIO,
|
||||
.p.id = AV_CODEC_ID_AAC,
|
||||
.p.priv_class = &ff_aac_decoder_class,
|
||||
.priv_data_size = sizeof(AACDecContext),
|
||||
.init = aac_decode_init_fixed,
|
||||
.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
|
||||
},
|
||||
.p.capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
|
||||
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
|
||||
.p.ch_layouts = ff_aac_ch_layout,
|
||||
.p.profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
|
||||
.flush = flush,
|
||||
};
|
||||
|
@ -348,7 +348,5 @@ void ff_aacdec_init_mips(AACDecContext *c);
|
||||
|
||||
int ff_aac_decode_ics(AACDecContext *ac, SingleChannelElement *sce,
|
||||
GetBitContext *gb, int common_window, int scale_flag);
|
||||
int ff_aac_decode_ics_fixed(AACDecContext *ac, SingleChannelElement *sce,
|
||||
GetBitContext *gb, int common_window, int scale_flag);
|
||||
|
||||
#endif /* AVCODEC_AACDEC_H */
|
||||
|
@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* AAC decoder fixed-point implementation
|
||||
*
|
||||
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
|
||||
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* AAC decoder
|
||||
* @author Oded Shimon ( ods15 ods15 dyndns org )
|
||||
* @author Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
*
|
||||
* Fixed point implementation
|
||||
* @author Stanislav Ocovaj ( stanislav.ocovaj imgtec com )
|
||||
*/
|
||||
|
||||
#define USE_FIXED 1
|
||||
|
||||
#include "libavutil/fixed_dsp.h"
|
||||
#include "avcodec.h"
|
||||
#include "codec_internal.h"
|
||||
#include "get_bits.h"
|
||||
|
||||
#include "aac.h"
|
||||
#include "aacdec.h"
|
||||
#include "aactab.h"
|
||||
#include "aac/aacdec_tab.h"
|
||||
#include "adts_header.h"
|
||||
#include "cbrt_data.h"
|
||||
#include "aacsbr.h"
|
||||
#include "mpeg4audio.h"
|
||||
#include "profiles.h"
|
||||
#include "libavutil/intfloat.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "aacdec_template.c"
|
||||
|
||||
const FFCodec ff_aac_fixed_decoder = {
|
||||
.p.name = "aac_fixed",
|
||||
CODEC_LONG_NAME("AAC (Advanced Audio Coding)"),
|
||||
.p.type = AVMEDIA_TYPE_AUDIO,
|
||||
.p.id = AV_CODEC_ID_AAC,
|
||||
.p.priv_class = &ff_aac_decoder_class,
|
||||
.priv_data_size = sizeof(AACDecContext),
|
||||
.init = aac_decode_init,
|
||||
.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
|
||||
},
|
||||
.p.capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
|
||||
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
|
||||
.p.ch_layouts = ff_aac_ch_layout,
|
||||
.p.profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
|
||||
.flush = flush,
|
||||
};
|
@ -134,7 +134,11 @@ static av_cold int che_configure(AACDecContext *ac,
|
||||
return AVERROR_INVALIDDATA;
|
||||
if (che_pos) {
|
||||
if (!ac->che[type][id]) {
|
||||
int ret = AAC_RENAME(ff_aac_sbr_ctx_alloc_init)(ac, &ac->che[type][id], type);
|
||||
int ret;
|
||||
if (ac->is_fixed)
|
||||
ret = ff_aac_sbr_ctx_alloc_init_fixed(ac, &ac->che[type][id], type);
|
||||
else
|
||||
ret = ff_aac_sbr_ctx_alloc_init(ac, &ac->che[type][id], type);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
@ -150,8 +154,12 @@ static av_cold int che_configure(AACDecContext *ac,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ac->che[type][id])
|
||||
AAC_RENAME(ff_aac_sbr_ctx_close)(ac->che[type][id]);
|
||||
if (ac->che[type][id]) {
|
||||
if (ac->is_fixed)
|
||||
ff_aac_sbr_ctx_close_fixed(ac->che[type][id]);
|
||||
else
|
||||
ff_aac_sbr_ctx_close(ac->che[type][id]);
|
||||
}
|
||||
av_freep(&ac->che[type][id]);
|
||||
}
|
||||
return 0;
|
||||
@ -1090,20 +1098,19 @@ static int sample_rate_idx (int rate)
|
||||
|
||||
static av_cold void aac_static_table_init(void)
|
||||
{
|
||||
AAC_RENAME(ff_aac_sbr_init)();
|
||||
ff_aac_sbr_init();
|
||||
ff_aac_sbr_init_fixed();
|
||||
|
||||
ff_aacdec_common_init_once();
|
||||
}
|
||||
|
||||
static AVOnce aac_table_init = AV_ONCE_INIT;
|
||||
|
||||
static av_cold int aac_decode_init(AVCodecContext *avctx)
|
||||
static av_cold int aac_decode_init_internal(AVCodecContext *avctx)
|
||||
{
|
||||
AACDecContext *ac = avctx->priv_data;
|
||||
int ret;
|
||||
|
||||
ac->is_fixed = USE_FIXED;
|
||||
|
||||
if (avctx->sample_rate > 96000)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
@ -1158,6 +1165,20 @@ static av_cold int aac_decode_init(AVCodecContext *avctx)
|
||||
return ff_aac_decode_init_common(avctx);
|
||||
}
|
||||
|
||||
static av_cold int aac_decode_init(AVCodecContext *avctx)
|
||||
{
|
||||
AACDecContext *ac = avctx->priv_data;
|
||||
ac->is_fixed = 0;
|
||||
return aac_decode_init_internal(avctx);
|
||||
}
|
||||
|
||||
static av_cold int aac_decode_init_fixed(AVCodecContext *avctx)
|
||||
{
|
||||
AACDecContext *ac = avctx->priv_data;
|
||||
ac->is_fixed = 1;
|
||||
return aac_decode_init_internal(avctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip data_stream_element; reference: table 4.10.
|
||||
*/
|
||||
@ -1516,8 +1537,12 @@ static int decode_tns(AACDecContext *ac, TemporalNoiseShaping *tns,
|
||||
coef_len = coef_res + 3 - coef_compress;
|
||||
tmp2_idx = 2 * coef_compress + coef_res;
|
||||
|
||||
for (i = 0; i < tns->order[w][filt]; i++)
|
||||
tns->AAC_RENAME(coef)[w][filt][i] = Q31(ff_tns_tmp2_map[tmp2_idx][get_bits(gb, coef_len)]);
|
||||
for (i = 0; i < tns->order[w][filt]; i++) {
|
||||
if (ac->is_fixed)
|
||||
tns->coef_fixed[w][filt][i] = Q31(ff_tns_tmp2_map[tmp2_idx][get_bits(gb, coef_len)]);
|
||||
else
|
||||
tns->coef[w][filt][i] = ff_tns_tmp2_map[tmp2_idx][get_bits(gb, coef_len)];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1580,8 +1605,8 @@ static void decode_gain_control(SingleChannelElement * sce, GetBitContext * gb)
|
||||
*
|
||||
* @return Returns error status. 0 - OK, !0 - error
|
||||
*/
|
||||
int AAC_RENAME(ff_aac_decode_ics)(AACDecContext *ac, SingleChannelElement *sce,
|
||||
GetBitContext *gb, int common_window, int scale_flag)
|
||||
int ff_aac_decode_ics(AACDecContext *ac, SingleChannelElement *sce,
|
||||
GetBitContext *gb, int common_window, int scale_flag)
|
||||
{
|
||||
Pulse pulse;
|
||||
TemporalNoiseShaping *tns = &sce->tns;
|
||||
@ -1698,9 +1723,9 @@ static int decode_cpe(AACDecContext *ac, GetBitContext *gb, ChannelElement *cpe)
|
||||
} else if (ms_present)
|
||||
decode_mid_side_stereo(cpe, gb, ms_present);
|
||||
}
|
||||
if ((ret = AAC_RENAME(ff_aac_decode_ics)(ac, &cpe->ch[0], gb, common_window, 0)))
|
||||
if ((ret = ff_aac_decode_ics(ac, &cpe->ch[0], gb, common_window, 0)))
|
||||
return ret;
|
||||
if ((ret = AAC_RENAME(ff_aac_decode_ics)(ac, &cpe->ch[1], gb, common_window, 0)))
|
||||
if ((ret = ff_aac_decode_ics(ac, &cpe->ch[1], gb, common_window, 0)))
|
||||
return ret;
|
||||
|
||||
if (common_window) {
|
||||
@ -1863,7 +1888,13 @@ static int decode_extension_payload(AACDecContext *ac, GetBitContext *gb, int cn
|
||||
ac->oc[1].m4ac.sbr = 1;
|
||||
ac->avctx->profile = AV_PROFILE_AAC_HE;
|
||||
}
|
||||
res = AAC_RENAME(ff_aac_sbr_decode_extension)(ac, che, gb, crc_flag, cnt, elem_type);
|
||||
|
||||
if (ac->is_fixed)
|
||||
res = ff_aac_sbr_decode_extension_fixed(ac, che, gb, crc_flag, cnt, elem_type);
|
||||
else
|
||||
res = ff_aac_sbr_decode_extension(ac, che, gb, crc_flag, cnt, elem_type);
|
||||
|
||||
|
||||
if (ac->oc[1].m4ac.ps == 1 && !ac->warned_he_aac_mono) {
|
||||
av_log(ac->avctx, AV_LOG_VERBOSE, "Treating HE-AAC mono as stereo.\n");
|
||||
ac->warned_he_aac_mono = 1;
|
||||
@ -1971,9 +2002,14 @@ static void spectral_to_sample(AACDecContext *ac, int samples)
|
||||
ac->dsp.update_ltp(ac, &che->ch[1]);
|
||||
}
|
||||
if (ac->oc[1].m4ac.sbr > 0) {
|
||||
AAC_RENAME(ff_aac_sbr_apply)(ac, che, type,
|
||||
che->ch[0].AAC_RENAME(output),
|
||||
che->ch[1].AAC_RENAME(output));
|
||||
if (ac->is_fixed)
|
||||
ff_aac_sbr_apply_fixed(ac, che, type,
|
||||
che->ch[0].AAC_RENAME(output),
|
||||
che->ch[1].AAC_RENAME(output));
|
||||
else
|
||||
ff_aac_sbr_apply(ac, che, type,
|
||||
che->ch[0].AAC_RENAME(output),
|
||||
che->ch[1].AAC_RENAME(output));
|
||||
}
|
||||
}
|
||||
if (type <= TYPE_CCE)
|
||||
@ -2093,13 +2129,13 @@ static int aac_decode_er_frame(AVCodecContext *avctx, AVFrame *frame,
|
||||
skip_bits(gb, 4);
|
||||
switch (elem_type) {
|
||||
case TYPE_SCE:
|
||||
err = AAC_RENAME(ff_aac_decode_ics)(ac, &che->ch[0], gb, 0, 0);
|
||||
err = ff_aac_decode_ics(ac, &che->ch[0], gb, 0, 0);
|
||||
break;
|
||||
case TYPE_CPE:
|
||||
err = decode_cpe(ac, gb, che);
|
||||
break;
|
||||
case TYPE_LFE:
|
||||
err = AAC_RENAME(ff_aac_decode_ics)(ac, &che->ch[0], gb, 0, 0);
|
||||
err = ff_aac_decode_ics(ac, &che->ch[0], gb, 0, 0);
|
||||
break;
|
||||
}
|
||||
if (err < 0)
|
||||
@ -2194,7 +2230,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
|
||||
switch (elem_type) {
|
||||
|
||||
case TYPE_SCE:
|
||||
err = AAC_RENAME(ff_aac_decode_ics)(ac, &che->ch[0], gb, 0, 0);
|
||||
err = ff_aac_decode_ics(ac, &che->ch[0], gb, 0, 0);
|
||||
audio_found = 1;
|
||||
sce_count++;
|
||||
break;
|
||||
@ -2209,7 +2245,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
|
||||
break;
|
||||
|
||||
case TYPE_LFE:
|
||||
err = AAC_RENAME(ff_aac_decode_ics)(ac, &che->ch[0], gb, 0, 0);
|
||||
err = ff_aac_decode_ics(ac, &che->ch[0], gb, 0, 0);
|
||||
audio_found = 1;
|
||||
break;
|
||||
|
||||
|
@ -70,23 +70,31 @@ enum {
|
||||
|
||||
FF_VISIBILITY_PUSH_HIDDEN
|
||||
/** Initialize SBR. */
|
||||
void AAC_RENAME(ff_aac_sbr_init)(void);
|
||||
void ff_aac_sbr_init(void);
|
||||
void ff_aac_sbr_init_fixed(void);
|
||||
/**
|
||||
* Allocate an ExtChannelElement (if necessary) and
|
||||
* initialize the SBR context contained in it.
|
||||
*/
|
||||
int AAC_RENAME(ff_aac_sbr_ctx_alloc_init)(AACDecContext *ac, ChannelElement **che, int id_aac);
|
||||
int ff_aac_sbr_ctx_alloc_init(AACDecContext *ac, ChannelElement **che, int id_aac);
|
||||
int ff_aac_sbr_ctx_alloc_init_fixed(AACDecContext *ac, ChannelElement **che, int id_aac);
|
||||
|
||||
/** 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);
|
||||
void ff_aac_sbr_ctx_close_fixed(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);
|
||||
int ff_aac_sbr_decode_extension(AACDecContext *ac, ChannelElement *che,
|
||||
GetBitContext *gb, int crc, int cnt, int id_aac);
|
||||
int ff_aac_sbr_decode_extension_fixed(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);
|
||||
void ff_aac_sbr_apply(AACDecContext *ac, ChannelElement *che,
|
||||
int id_aac, INTFLOAT* L, INTFLOAT* R);
|
||||
void ff_aac_sbr_apply_fixed(AACDecContext *ac, ChannelElement *che,
|
||||
int id_aac, INTFLOAT* L, INTFLOAT* R);
|
||||
|
||||
FF_VISIBILITY_POP_HIDDEN
|
||||
|
||||
#endif /* AVCODEC_AACSBR_H */
|
||||
|
Loading…
x
Reference in New Issue
Block a user