diff options
author | Alex Converse <alex.converse@gmail.com> | 2015-01-21 21:51:54 -0800 |
---|---|---|
committer | Alex Converse <alex.converse@gmail.com> | 2015-02-03 20:32:16 -0800 |
commit | d615187f74ddf3413778a8b5b7ae17255b0df88e (patch) | |
tree | 8976e4353bcdc3e9d18b6d9fd42eea4ded8c2c20 | |
parent | 7640c4a371a97899dfb443d980fd0bf8ac587754 (diff) | |
download | ffmpeg-d615187f74ddf3413778a8b5b7ae17255b0df88e.tar.gz |
aacdec: Support for ER AAC ELD 480.
Based in part on work from Niel van der Westhuizen <espes@pequalsnp.com>.
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | libavcodec/aac.h | 2 | ||||
-rw-r--r-- | libavcodec/aacdec.c | 38 | ||||
-rw-r--r-- | libavcodec/mpeg4audio.h | 1 |
4 files changed, 30 insertions, 13 deletions
@@ -1755,7 +1755,7 @@ mpegvideo_select="blockdsp hpeldsp idctdsp me_cmp videodsp" mpegvideoenc_select="me_cmp mpegvideo pixblockdsp qpeldsp" # decoders / encoders -aac_decoder_select="mdct sinewin" +aac_decoder_select="imdct15 mdct sinewin" aac_encoder_select="audio_frame_queue iirfilter mdct sinewin" aac_latm_decoder_select="aac_decoder aac_latm_parser" ac3_decoder_select="ac3_parser ac3dsp bswapdsp mdct" diff --git a/libavcodec/aac.h b/libavcodec/aac.h index 375e6b1717..b71e8b607f 100644 --- a/libavcodec/aac.h +++ b/libavcodec/aac.h @@ -32,6 +32,7 @@ #include "libavutil/float_dsp.h" #include "avcodec.h" +#include "imdct15.h" #include "fft.h" #include "mpeg4audio.h" #include "sbr.h" @@ -291,6 +292,7 @@ typedef struct AACContext { FFTContext mdct_small; FFTContext mdct_ld; FFTContext mdct_ltp; + IMDCT15Context *mdct480; FmtConvertContext fmt_conv; AVFloatDSPContext fdsp; int random_state; diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index f868b7f94e..9a931824e8 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -85,6 +85,7 @@ #include "internal.h" #include "get_bits.h" #include "fft.h" +#include "imdct15.h" #include "fmtconvert.h" #include "lpc.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"); return AVERROR_PATCHWELCOME; } + m4ac->frame_length_short = 0; if (get_bits1(gb)) // dependsOnCoreCoder skip_bits(gb, 14); // coreCoderDelay @@ -796,11 +798,7 @@ static int decode_eld_specific_config(AACContext *ac, AVCodecContext *avctx, m4ac->ps = 0; m4ac->sbr = 0; - if (get_bits1(gb)) { // frameLengthFlag - avpriv_request_sample(avctx, "960/120 MDCT window"); - return AVERROR_PATCHWELCOME; - } - + m4ac->frame_length_short = get_bits1(gb); res_flags = get_bits(gb, 3); if (res_flags) { 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_small, 8, 1, 1.0 / (32768.0 * 128.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 ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024); 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->num_windows = 1; if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD) { - ics->swb_offset = ff_swb_offset_512[sampling_index]; - ics->num_swb = ff_aac_num_swb_512[sampling_index]; - ics->tns_max_bands = ff_tns_max_bands_512[sampling_index]; + 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->num_swb = ff_aac_num_swb_512[sampling_index]; + ics->tns_max_bands = ff_tns_max_bands_512[sampling_index]; + } if (!ics->num_swb || !ics->swb_offset) return AVERROR_BUG; } else { @@ -2457,12 +2465,13 @@ static void imdct_and_windowing_eld(AACContext *ac, SingleChannelElement *sce) float *in = sce->coeffs; float *out = sce->ret; float *saved = sce->saved; - const float *const window = ff_aac_eld_window_512; float *buf = ac->buf_mdct; 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 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 // Chivukula, R.K.; Reznik, Y.A.; Devarajan, V., @@ -2474,7 +2483,10 @@ 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 + 1]; in[i + 1] = in[n - 2 - i]; in[n - 2 - i] = temp; } - ac->mdct.imdct_half(&ac->mdct_ld, buf, in); + 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); for (i = 0; i < n; i+=2) { 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.sampling_index = hdr_info.sampling_index; 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 || ac->oc[0].m4ac.chan_config != hdr_info.chan_config || 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; ChannelElement *che; int err, i; - int samples = 1024; + int samples = m4ac->frame_length_short ? 960 : 1024; int chan_config = m4ac->chan_config; 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_ld); ff_mdct_end(&ac->mdct_ltp); + ff_imdct15_uninit(&ac->mdct480); return 0; } diff --git a/libavcodec/mpeg4audio.h b/libavcodec/mpeg4audio.h index e71122d0d3..2eef2205bd 100644 --- a/libavcodec/mpeg4audio.h +++ b/libavcodec/mpeg4audio.h @@ -38,6 +38,7 @@ typedef struct MPEG4AudioConfig { int ext_chan_config; int channels; int ps; ///< -1 implicit, 1 presence + int frame_length_short; } MPEG4AudioConfig; extern av_export const int avpriv_mpeg4audio_sample_rates[16]; |