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

Reply via email to