aacdec: fully detemplate decoder core

release/7.1
Lynne 8 months ago
parent 2f90d83981
commit e93793bf3c
No known key found for this signature in database
GPG Key ID: A2FEA5F03F034464
  1. 2
      libavcodec/Makefile
  2. 2
      libavcodec/aac/aacdec_proc_template.c
  3. 22
      libavcodec/aacdec.c
  4. 2
      libavcodec/aacdec.h
  5. 102
      libavcodec/aacdec_fixed.c
  6. 78
      libavcodec/aacdec_template.c
  7. 22
      libavcodec/aacsbr.h

@ -184,7 +184,7 @@ OBJS-$(CONFIG_AAC_DECODER) += aacdec.o aactab.o \
aacsbr.o aacps_common.o aacps_float.o \ aacsbr.o aacps_common.o aacps_float.o \
kbdwin.o \ kbdwin.o \
sbrdsp.o aacpsdsp_float.o cbrt_data.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 \ aacsbr_fixed.o aacps_common.o aacps_fixed.o \
kbdwin.o \ kbdwin.o \
sbrdsp_fixed.o aacpsdsp_fixed.o cbrt_data_fixed.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)]; scale = cce_scale[get_bits(gb, 2)];
#endif #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; return ret;
for (c = 0; c < num_gain; c++) { for (c = 0; c < num_gain; c++) {

@ -32,7 +32,7 @@
* @author Maxim Gavrilov ( maxim.gavrilov gmail com ) * @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 "libavutil/float_dsp.h"
#include "avcodec.h" #include "avcodec.h"
@ -399,3 +399,23 @@ const FFCodec ff_aac_latm_decoder = {
.flush = flush, .flush = flush,
.p.profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles), .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, int ff_aac_decode_ics(AACDecContext *ac, SingleChannelElement *sce,
GetBitContext *gb, int common_window, int scale_flag); 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 */ #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; return AVERROR_INVALIDDATA;
if (che_pos) { if (che_pos) {
if (!ac->che[type][id]) { 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) if (ret < 0)
return ret; return ret;
} }
@ -150,8 +154,12 @@ static av_cold int che_configure(AACDecContext *ac,
} }
} }
} else { } else {
if (ac->che[type][id]) if (ac->che[type][id]) {
AAC_RENAME(ff_aac_sbr_ctx_close)(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]); av_freep(&ac->che[type][id]);
} }
return 0; return 0;
@ -1090,20 +1098,19 @@ static int sample_rate_idx (int rate)
static av_cold void aac_static_table_init(void) 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(); ff_aacdec_common_init_once();
} }
static AVOnce aac_table_init = AV_ONCE_INIT; 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; AACDecContext *ac = avctx->priv_data;
int ret; int ret;
ac->is_fixed = USE_FIXED;
if (avctx->sample_rate > 96000) if (avctx->sample_rate > 96000)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
@ -1158,6 +1165,20 @@ static av_cold int aac_decode_init(AVCodecContext *avctx)
return ff_aac_decode_init_common(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. * 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; coef_len = coef_res + 3 - coef_compress;
tmp2_idx = 2 * coef_compress + coef_res; tmp2_idx = 2 * coef_compress + coef_res;
for (i = 0; i < tns->order[w][filt]; i++) 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)]); 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 * @return Returns error status. 0 - OK, !0 - error
*/ */
int AAC_RENAME(ff_aac_decode_ics)(AACDecContext *ac, SingleChannelElement *sce, int ff_aac_decode_ics(AACDecContext *ac, SingleChannelElement *sce,
GetBitContext *gb, int common_window, int scale_flag) GetBitContext *gb, int common_window, int scale_flag)
{ {
Pulse pulse; Pulse pulse;
TemporalNoiseShaping *tns = &sce->tns; TemporalNoiseShaping *tns = &sce->tns;
@ -1698,9 +1723,9 @@ static int decode_cpe(AACDecContext *ac, GetBitContext *gb, ChannelElement *cpe)
} else if (ms_present) } else if (ms_present)
decode_mid_side_stereo(cpe, gb, 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; 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; return ret;
if (common_window) { 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->oc[1].m4ac.sbr = 1;
ac->avctx->profile = AV_PROFILE_AAC_HE; 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) { 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"); av_log(ac->avctx, AV_LOG_VERBOSE, "Treating HE-AAC mono as stereo.\n");
ac->warned_he_aac_mono = 1; 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]); ac->dsp.update_ltp(ac, &che->ch[1]);
} }
if (ac->oc[1].m4ac.sbr > 0) { if (ac->oc[1].m4ac.sbr > 0) {
AAC_RENAME(ff_aac_sbr_apply)(ac, che, type, if (ac->is_fixed)
che->ch[0].AAC_RENAME(output), ff_aac_sbr_apply_fixed(ac, che, type,
che->ch[1].AAC_RENAME(output)); 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) if (type <= TYPE_CCE)
@ -2093,13 +2129,13 @@ static int aac_decode_er_frame(AVCodecContext *avctx, AVFrame *frame,
skip_bits(gb, 4); skip_bits(gb, 4);
switch (elem_type) { switch (elem_type) {
case TYPE_SCE: 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; break;
case TYPE_CPE: case TYPE_CPE:
err = decode_cpe(ac, gb, che); err = decode_cpe(ac, gb, che);
break; break;
case TYPE_LFE: 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; break;
} }
if (err < 0) if (err < 0)
@ -2194,7 +2230,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
switch (elem_type) { switch (elem_type) {
case TYPE_SCE: 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; audio_found = 1;
sce_count++; sce_count++;
break; break;
@ -2209,7 +2245,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
break; break;
case TYPE_LFE: 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; audio_found = 1;
break; break;

@ -70,23 +70,31 @@ enum {
FF_VISIBILITY_PUSH_HIDDEN FF_VISIBILITY_PUSH_HIDDEN
/** Initialize SBR. */ /** 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 * Allocate an ExtChannelElement (if necessary) and
* initialize the SBR context contained in it. * 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. */ /** 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(ChannelElement *che);
void ff_aac_sbr_ctx_close_fixed(ChannelElement *che);
/** Decode one SBR element. */ /** Decode one SBR element. */
int AAC_RENAME(ff_aac_sbr_decode_extension)(AACDecContext *ac, ChannelElement *che, int ff_aac_sbr_decode_extension(AACDecContext *ac, ChannelElement *che,
GetBitContext *gb, int crc, int cnt, int id_aac); 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. */ /** Apply one SBR element to one AAC element. */
void AAC_RENAME(ff_aac_sbr_apply)(AACDecContext *ac, ChannelElement *che, void ff_aac_sbr_apply(AACDecContext *ac, ChannelElement *che,
int id_aac, INTFLOAT* L, INTFLOAT* R); 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 FF_VISIBILITY_POP_HIDDEN
#endif /* AVCODEC_AACSBR_H */ #endif /* AVCODEC_AACSBR_H */

Loading…
Cancel
Save