On Mon, Sep 16, 2013 at 04:02:08PM -0700, Alex Converse wrote:
> ---
> Changelog | 1 +
> libavcodec/aac.h | 1 +
> libavcodec/aacdec.c | 66
> ++++++++++++++++++++++++++++++++++++++++++++++++++---
> libavcodec/aactab.c | 36 +++++++++++++++++++++++++++++
> libavcodec/aactab.h | 3 +++
> 5 files changed, 104 insertions(+), 3 deletions(-)
>
> diff --git a/Changelog b/Changelog
> index 5261c18..4e818ce 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -34,6 +34,7 @@ version 10:
> data read from an input file
> - incomplete Voxware MetaSound decoder
> - Error Resiliant AAC syntax (ER AAC LC) decoding
> +- Low Delay AAC (ER AAC LD) decoding
unrelated: object type 39 should've been named ER_EEC_ELD
>
>
> version 9:
> diff --git a/libavcodec/aac.h b/libavcodec/aac.h
> index a7c9995..40e8dfb 100644
> --- a/libavcodec/aac.h
> +++ b/libavcodec/aac.h
> @@ -289,6 +289,7 @@ typedef struct AACContext {
> */
> FFTContext mdct;
> FFTContext mdct_small;
> + FFTContext mdct_ld;
> FFTContext mdct_ltp;
> FmtConvertContext fmt_conv;
> AVFloatDSPContext fdsp;
> diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c
> index 4a18946..7b28239 100644
> --- a/libavcodec/aacdec.c
> +++ b/libavcodec/aacdec.c
> @@ -817,6 +817,13 @@ static int decode_audio_specific_config(AACContext *ac,
> m4ac->sampling_index);
> return AVERROR_INVALIDDATA;
> }
> + if (m4ac->object_type == AOT_ER_AAC_LD &&
> + m4ac->sampling_index < 3 || m4ac->sampling_index > 7) {
> + av_log(avctx, AV_LOG_ERROR,
> + "invalid low delay sampling rate index %d\n",
> + m4ac->sampling_index);
> + return AVERROR_INVALIDDATA;
> + }
>
> skip_bits_long(&gb, i);
>
> @@ -825,6 +832,7 @@ static int decode_audio_specific_config(AACContext *ac,
> case AOT_AAC_LC:
> case AOT_AAC_LTP:
> case AOT_ER_AAC_LC:
> + case AOT_ER_AAC_LD:
> if ((ret = decode_ga_specific_config(ac, avctx, &gb,
> m4ac, m4ac->chan_config)) < 0)
> return ret;
> @@ -985,12 +993,15 @@ static av_cold int aac_decode_init(AVCodecContext
> *avctx)
> 352);
>
> ff_mdct_init(&ac->mdct, 11, 1, 1.0 / (32768.0 * 1024.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_ltp, 11, 0, -2.0 * 32768.0);
> // window initialization
> ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024);
> + ff_kbd_window_init(ff_aac_kbd_long_512, 4.0, 512);
> ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128);
> ff_init_ff_sine_windows(10);
> + ff_init_ff_sine_windows( 9);
> ff_init_ff_sine_windows( 7);
>
> cbrt_tableinit();
> @@ -1063,6 +1074,14 @@ static int decode_ics_info(AACContext *ac,
> IndividualChannelStream *ics,
> }
> ics->window_sequence[1] = ics->window_sequence[0];
> ics->window_sequence[0] = get_bits(gb, 2);
> + if (ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD &&
> + ics->window_sequence[0] != ONLY_LONG_SEQUENCE) {
> + av_log(ac->avctx, AV_LOG_ERROR,
> + "AAC LD is only defined for ONLY_LONG_SEQUENCE but "
> + "window sequence %d found.\n", ics->window_sequence[0]);
> + ics->window_sequence[0] = ONLY_LONG_SEQUENCE;
> + return AVERROR_INVALIDDATA;
> + }
> ics->use_kb_window[1] = ics->use_kb_window[0];
> ics->use_kb_window[0] = get_bits1(gb);
> ics->num_window_groups = 1;
> @@ -1086,8 +1105,15 @@ static int decode_ics_info(AACContext *ac,
> IndividualChannelStream *ics,
> } else {
> ics->max_sfb = get_bits(gb, 6);
> ics->num_windows = 1;
> - ics->swb_offset =
> ff_swb_offset_1024[ac->oc[1].m4ac.sampling_index];
> - ics->num_swb =
> ff_aac_num_swb_1024[ac->oc[1].m4ac.sampling_index];
> + if (ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD) {
> + ics->swb_offset =
> ff_swb_offset_512[ac->oc[1].m4ac.sampling_index];
> + ics->num_swb =
> ff_aac_num_swb_512[ac->oc[1].m4ac.sampling_index];
> + if (!ics->num_swb || !ics->swb_offset)
> + return AVERROR_BUG;
> + } else {
> + ics->swb_offset =
> ff_swb_offset_1024[ac->oc[1].m4ac.sampling_index];
> + ics->num_swb =
> ff_aac_num_swb_1024[ac->oc[1].m4ac.sampling_index];
> + }
> ics->tns_max_bands =
> ff_tns_max_bands_1024[ac->oc[1].m4ac.sampling_index];
> ics->predictor_present = get_bits1(gb);
> ics->predictor_reset_group = 0;
> @@ -1102,6 +1128,11 @@ static int decode_ics_info(AACContext *ac,
> IndividualChannelStream *ics,
> "Prediction is not allowed in AAC-LC.\n");
> return AVERROR_INVALIDDATA;
> } else {
> + if (ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD) {
> + av_log(ac->avctx, AV_LOG_ERROR,
> + "LTP in ER AAC LD not yet implemented.\n");
> + return AVERROR_PATCHWELCOME;
> + }
> if ((ics->ltp.present = get_bits(gb, 1)))
> decode_ltp(&ics->ltp, gb, ics->max_sfb);
> }
> @@ -2254,7 +2285,7 @@ static void update_ltp(AACContext *ac,
> SingleChannelElement *sce)
> /**
> * Conduct IMDCT and windowing.
> */
> -static void imdct_and_windowing(AACContext *ac, SingleChannelElement *sce)
> +static void imdct_and_windowing_classic(AACContext *ac, SingleChannelElement
> *sce)
nit: maybe leave it as it was? It's still the default.
> {
> IndividualChannelStream *ics = &sce->ics;
> float *in = sce->coeffs;
> @@ -2314,6 +2345,25 @@ static void imdct_and_windowing(AACContext *ac,
> SingleChannelElement *sce)
> }
> }
>
> +static void imdct_and_windowing_ld(AACContext *ac, SingleChannelElement *sce)
> +{
> + IndividualChannelStream *ics = &sce->ics;
> + float *in = sce->coeffs;
> + float *out = sce->ret;
> + float *saved = sce->saved;
> + const float *lwindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_long_512
> : ff_sine_512;
> + float *buf = ac->buf_mdct;
> +
> + // imdct
> + ac->mdct.imdct_half(&ac->mdct_ld, buf, in);
> +
> + /* window overlapping */
> + ac->fdsp.vector_fmul_window( out, saved,
> buf, lwindow_prev, 256);
> +
> + // buffer update
> + memcpy( saved, buf + 256, 256 *
> sizeof(float));
remove those spaces, it's ugly and there's no valign to justify them
> +}
> +
> /**
> * Apply dependent channel coupling (applied before IMDCT).
> *
> @@ -2410,6 +2460,12 @@ static void apply_channel_coupling(AACContext *ac,
> ChannelElement *cc,
> static void spectral_to_sample(AACContext *ac)
> {
> int i, type;
> + void (*imdct_and_windowing)(AACContext *ac, SingleChannelElement *sce);
> + if (ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD) {
> + imdct_and_windowing = imdct_and_windowing_ld;
> + } else {
> + imdct_and_windowing = imdct_and_windowing_classic;
> + }
> for (type = 3; type >= 0; type--) {
> for (i = 0; i < MAX_ELEM_ID; i++) {
> ChannelElement *che = ac->che[type][i];
> @@ -2503,6 +2559,9 @@ static int aac_decode_er_frame(AVCodecContext *avctx,
> void *data,
> int samples = 1024;
> int chan_config = ac->oc[1].m4ac.chan_config;
>
> + if (ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD)
> + samples >>= 1;
> +
> ac->frame = data;
>
> if ((err = frame_configure_elements(avctx)) < 0)
> @@ -2761,6 +2820,7 @@ static av_cold int aac_decode_close(AVCodecContext
> *avctx)
>
> ff_mdct_end(&ac->mdct);
> ff_mdct_end(&ac->mdct_small);
> + ff_mdct_end(&ac->mdct_ld);
> ff_mdct_end(&ac->mdct_ltp);
> return 0;
> }
> diff --git a/libavcodec/aactab.c b/libavcodec/aactab.c
> index 9176e37..b96a7d5 100644
> --- a/libavcodec/aactab.c
> +++ b/libavcodec/aactab.c
> @@ -34,12 +34,17 @@
> #include <stdint.h>
>
> DECLARE_ALIGNED(32, float, ff_aac_kbd_long_1024)[1024];
> +DECLARE_ALIGNED(32, float, ff_aac_kbd_long_512 )[512];
> DECLARE_ALIGNED(32, float, ff_aac_kbd_short_128)[128];
>
> const uint8_t ff_aac_num_swb_1024[] = {
> 41, 41, 47, 49, 49, 51, 47, 47, 43, 43, 43, 40, 40
> };
>
> +const uint8_t ff_aac_num_swb_512[] = {
> + 0, 0, 0, 36, 36, 37, 31, 31, 0, 0, 0, 0, 0
> +};
> +
> const uint8_t ff_aac_num_swb_128[] = {
> 12, 12, 12, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15
> };
> @@ -1114,6 +1119,14 @@ static const uint16_t swb_offset_1024_48[] = {
> 928, 1024
> };
>
> +static const uint16_t swb_offset_512_48[] = {
> + 0, 4, 8, 12, 16, 20, 24, 28,
> + 32, 36, 40, 44, 48, 52, 56, 60,
> + 68, 76, 84, 92, 100, 112, 124, 136,
> + 148, 164, 184, 208, 236, 268, 300, 332,
> + 364, 396, 428, 460, 512
> +};
> +
> static const uint16_t swb_offset_128_48[] = {
> 0, 4, 8, 12, 16, 20, 28, 36,
> 44, 56, 68, 80, 96, 112, 128
> @@ -1129,6 +1142,14 @@ static const uint16_t swb_offset_1024_32[] = {
> 928, 960, 992, 1024
> };
>
> +static const uint16_t swb_offset_512_32[] = {
> + 0, 4, 8, 12, 16, 20, 24, 28,
> + 32, 36, 40, 44, 48, 52, 56, 64,
> + 72, 80, 88, 96, 108, 120, 132, 144,
> + 160, 176, 192, 212, 236, 260, 288, 320,
> + 352, 384, 416, 448, 480, 512
> +};
> +
> static const uint16_t swb_offset_1024_24[] = {
> 0, 4, 8, 12, 16, 20, 24, 28,
> 32, 36, 40, 44, 52, 60, 68, 76,
> @@ -1138,6 +1159,13 @@ static const uint16_t swb_offset_1024_24[] = {
> 600, 652, 704, 768, 832, 896, 960, 1024
> };
>
> +static const uint16_t swb_offset_512_24[] = {
> + 0, 4, 8, 12, 16, 20, 24, 28,
> + 32, 36, 40, 44, 52, 60, 68, 80,
> + 92, 104, 120, 140, 164, 192, 224, 256,
> + 288, 320, 352, 384, 416, 448, 480, 512,
> +};
> +
> static const uint16_t swb_offset_128_24[] = {
> 0, 4, 8, 12, 16, 20, 24, 28,
> 36, 44, 52, 64, 76, 92, 108, 128
> @@ -1179,6 +1207,14 @@ const uint16_t * const ff_swb_offset_1024[] = {
> swb_offset_1024_8
> };
>
> +const uint16_t * const ff_swb_offset_512[] = {
> + NULL, NULL, NULL,
> + swb_offset_512_48, swb_offset_512_48, swb_offset_512_32,
> + swb_offset_512_24, swb_offset_512_24, NULL,
> + NULL, NULL, NULL,
> + NULL
> +};
> +
> const uint16_t * const ff_swb_offset_128[] = {
> /* The last entry on the following row is swb_offset_128_64 but is a
> duplicate of swb_offset_128_96. */
> diff --git a/libavcodec/aactab.h b/libavcodec/aactab.h
> index 56e5796..bf1576e 100644
> --- a/libavcodec/aactab.h
> +++ b/libavcodec/aactab.h
> @@ -45,6 +45,7 @@
> * @{
> */
> DECLARE_ALIGNED(32, extern float, ff_aac_kbd_long_1024)[1024];
> +DECLARE_ALIGNED(32, extern float, ff_aac_kbd_long_512 )[512];
> DECLARE_ALIGNED(32, extern float, ff_aac_kbd_short_128)[128];
> // @}
>
> @@ -52,6 +53,7 @@ DECLARE_ALIGNED(32, extern float,
> ff_aac_kbd_short_128)[128];
> * @{
> */
> extern const uint8_t ff_aac_num_swb_1024[];
> +extern const uint8_t ff_aac_num_swb_512 [];
> extern const uint8_t ff_aac_num_swb_128 [];
> // @}
>
> @@ -69,6 +71,7 @@ extern const float *ff_aac_codebook_vector_vals[];
> extern const uint16_t *ff_aac_codebook_vector_idx[];
>
> extern const uint16_t * const ff_swb_offset_1024[13];
> +extern const uint16_t * const ff_swb_offset_512 [13];
> extern const uint16_t * const ff_swb_offset_128 [13];
>
> extern const uint8_t ff_tns_max_bands_1024[13];
> --
in general LGTM
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel