aacdec: Support for ER AAC ELD 480.

Based in part on work from Niel van der Westhuizen <espes@pequalsnp.com>.
pull/111/head
Alex Converse 10 years ago
parent 7640c4a371
commit d615187f74
  1. 2
      configure
  2. 2
      libavcodec/aac.h
  3. 30
      libavcodec/aacdec.c
  4. 1
      libavcodec/mpeg4audio.h

2
configure vendored

@ -1755,7 +1755,7 @@ mpegvideo_select="blockdsp hpeldsp idctdsp me_cmp videodsp"
mpegvideoenc_select="me_cmp mpegvideo pixblockdsp qpeldsp" mpegvideoenc_select="me_cmp mpegvideo pixblockdsp qpeldsp"
# decoders / encoders # decoders / encoders
aac_decoder_select="mdct sinewin" aac_decoder_select="imdct15 mdct sinewin"
aac_encoder_select="audio_frame_queue iirfilter mdct sinewin" aac_encoder_select="audio_frame_queue iirfilter mdct sinewin"
aac_latm_decoder_select="aac_decoder aac_latm_parser" aac_latm_decoder_select="aac_decoder aac_latm_parser"
ac3_decoder_select="ac3_parser ac3dsp bswapdsp mdct" ac3_decoder_select="ac3_parser ac3dsp bswapdsp mdct"

@ -32,6 +32,7 @@
#include "libavutil/float_dsp.h" #include "libavutil/float_dsp.h"
#include "avcodec.h" #include "avcodec.h"
#include "imdct15.h"
#include "fft.h" #include "fft.h"
#include "mpeg4audio.h" #include "mpeg4audio.h"
#include "sbr.h" #include "sbr.h"
@ -291,6 +292,7 @@ typedef struct AACContext {
FFTContext mdct_small; FFTContext mdct_small;
FFTContext mdct_ld; FFTContext mdct_ld;
FFTContext mdct_ltp; FFTContext mdct_ltp;
IMDCT15Context *mdct480;
FmtConvertContext fmt_conv; FmtConvertContext fmt_conv;
AVFloatDSPContext fdsp; AVFloatDSPContext fdsp;
int random_state; int random_state;

@ -85,6 +85,7 @@
#include "internal.h" #include "internal.h"
#include "get_bits.h" #include "get_bits.h"
#include "fft.h" #include "fft.h"
#include "imdct15.h"
#include "fmtconvert.h" #include "fmtconvert.h"
#include "lpc.h" #include "lpc.h"
#include "kbdwin.h" #include "kbdwin.h"
@ -719,6 +720,7 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx,
avpriv_request_sample(avctx, "960/120 MDCT window"); avpriv_request_sample(avctx, "960/120 MDCT window");
return AVERROR_PATCHWELCOME; return AVERROR_PATCHWELCOME;
} }
m4ac->frame_length_short = 0;
if (get_bits1(gb)) // dependsOnCoreCoder if (get_bits1(gb)) // dependsOnCoreCoder
skip_bits(gb, 14); // coreCoderDelay skip_bits(gb, 14); // coreCoderDelay
@ -796,11 +798,7 @@ static int decode_eld_specific_config(AACContext *ac, AVCodecContext *avctx,
m4ac->ps = 0; m4ac->ps = 0;
m4ac->sbr = 0; m4ac->sbr = 0;
if (get_bits1(gb)) { // frameLengthFlag m4ac->frame_length_short = get_bits1(gb);
avpriv_request_sample(avctx, "960/120 MDCT window");
return AVERROR_PATCHWELCOME;
}
res_flags = get_bits(gb, 3); res_flags = get_bits(gb, 3);
if (res_flags) { if (res_flags) {
avpriv_report_missing_feature(avctx, avpriv_report_missing_feature(avctx,
@ -1066,6 +1064,10 @@ static av_cold int aac_decode_init(AVCodecContext *avctx)
ff_mdct_init(&ac->mdct_ld, 10, 1, 1.0 / (32768.0 * 512.0)); ff_mdct_init(&ac->mdct_ld, 10, 1, 1.0 / (32768.0 * 512.0));
ff_mdct_init(&ac->mdct_small, 8, 1, 1.0 / (32768.0 * 128.0)); ff_mdct_init(&ac->mdct_small, 8, 1, 1.0 / (32768.0 * 128.0));
ff_mdct_init(&ac->mdct_ltp, 11, 0, -2.0 * 32768.0); ff_mdct_init(&ac->mdct_ltp, 11, 0, -2.0 * 32768.0);
ret = ff_imdct15_init(&ac->mdct480, 5);
if (ret < 0)
return ret;
// window initialization // window initialization
ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024); ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024);
ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128); ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128);
@ -1180,9 +1182,15 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics,
ics->max_sfb = get_bits(gb, 6); ics->max_sfb = get_bits(gb, 6);
ics->num_windows = 1; ics->num_windows = 1;
if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD) { if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD) {
if (m4ac->frame_length_short) {
ics->swb_offset = ff_swb_offset_480[sampling_index];
ics->num_swb = ff_aac_num_swb_480[sampling_index];
ics->tns_max_bands = ff_tns_max_bands_480[sampling_index];
} else {
ics->swb_offset = ff_swb_offset_512[sampling_index]; ics->swb_offset = ff_swb_offset_512[sampling_index];
ics->num_swb = ff_aac_num_swb_512[sampling_index]; ics->num_swb = ff_aac_num_swb_512[sampling_index];
ics->tns_max_bands = ff_tns_max_bands_512[sampling_index]; ics->tns_max_bands = ff_tns_max_bands_512[sampling_index];
}
if (!ics->num_swb || !ics->swb_offset) if (!ics->num_swb || !ics->swb_offset)
return AVERROR_BUG; return AVERROR_BUG;
} else { } else {
@ -2457,12 +2465,13 @@ static void imdct_and_windowing_eld(AACContext *ac, SingleChannelElement *sce)
float *in = sce->coeffs; float *in = sce->coeffs;
float *out = sce->ret; float *out = sce->ret;
float *saved = sce->saved; float *saved = sce->saved;
const float *const window = ff_aac_eld_window_512;
float *buf = ac->buf_mdct; float *buf = ac->buf_mdct;
int i; int i;
const int n = 512; const int n = ac->oc[1].m4ac.frame_length_short ? 480 : 512;
const int n2 = n >> 1; const int n2 = n >> 1;
const int n4 = n >> 2; const int n4 = n >> 2;
const float *const window = n == 480 ? ff_aac_eld_window_480 :
ff_aac_eld_window_512;
// Inverse transform, mapped to the conventional IMDCT by // Inverse transform, mapped to the conventional IMDCT by
// Chivukula, R.K.; Reznik, Y.A.; Devarajan, V., // Chivukula, R.K.; Reznik, Y.A.; Devarajan, V.,
@ -2474,6 +2483,9 @@ static void imdct_and_windowing_eld(AACContext *ac, SingleChannelElement *sce)
temp = in[i ]; in[i ] = -in[n - 1 - i]; in[n - 1 - i] = temp; temp = in[i ]; in[i ] = -in[n - 1 - i]; in[n - 1 - i] = temp;
temp = -in[i + 1]; in[i + 1] = in[n - 2 - i]; in[n - 2 - i] = temp; temp = -in[i + 1]; in[i + 1] = in[n - 2 - i]; in[n - 2 - i] = temp;
} }
if (n == 480)
ac->mdct480->imdct_half(ac->mdct480, buf, in, 1, -1.f/(16*1024*960));
else
ac->mdct.imdct_half(&ac->mdct_ld, buf, in); ac->mdct.imdct_half(&ac->mdct_ld, buf, in);
for (i = 0; i < n; i+=2) { for (i = 0; i < n; i+=2) {
buf[i] = -buf[i]; buf[i] = -buf[i];
@ -2687,6 +2699,7 @@ static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb)
ac->oc[1].m4ac.sample_rate = hdr_info.sample_rate; ac->oc[1].m4ac.sample_rate = hdr_info.sample_rate;
ac->oc[1].m4ac.sampling_index = hdr_info.sampling_index; ac->oc[1].m4ac.sampling_index = hdr_info.sampling_index;
ac->oc[1].m4ac.object_type = hdr_info.object_type; ac->oc[1].m4ac.object_type = hdr_info.object_type;
ac->oc[1].m4ac.frame_length_short = 0;
if (ac->oc[0].status != OC_LOCKED || if (ac->oc[0].status != OC_LOCKED ||
ac->oc[0].m4ac.chan_config != hdr_info.chan_config || ac->oc[0].m4ac.chan_config != hdr_info.chan_config ||
ac->oc[0].m4ac.sample_rate != hdr_info.sample_rate) { ac->oc[0].m4ac.sample_rate != hdr_info.sample_rate) {
@ -2706,7 +2719,7 @@ static int aac_decode_er_frame(AVCodecContext *avctx, void *data,
const MPEG4AudioConfig *const m4ac = &ac->oc[1].m4ac; const MPEG4AudioConfig *const m4ac = &ac->oc[1].m4ac;
ChannelElement *che; ChannelElement *che;
int err, i; int err, i;
int samples = 1024; int samples = m4ac->frame_length_short ? 960 : 1024;
int chan_config = m4ac->chan_config; int chan_config = m4ac->chan_config;
int aot = m4ac->object_type; int aot = m4ac->object_type;
@ -2982,6 +2995,7 @@ static av_cold int aac_decode_close(AVCodecContext *avctx)
ff_mdct_end(&ac->mdct_small); ff_mdct_end(&ac->mdct_small);
ff_mdct_end(&ac->mdct_ld); ff_mdct_end(&ac->mdct_ld);
ff_mdct_end(&ac->mdct_ltp); ff_mdct_end(&ac->mdct_ltp);
ff_imdct15_uninit(&ac->mdct480);
return 0; return 0;
} }

@ -38,6 +38,7 @@ typedef struct MPEG4AudioConfig {
int ext_chan_config; int ext_chan_config;
int channels; int channels;
int ps; ///< -1 implicit, 1 presence int ps; ///< -1 implicit, 1 presence
int frame_length_short;
} MPEG4AudioConfig; } MPEG4AudioConfig;
extern av_export const int avpriv_mpeg4audio_sample_rates[16]; extern av_export const int avpriv_mpeg4audio_sample_rates[16];

Loading…
Cancel
Save