[FFmpeg-devel] [PATCH 03/14] libavcodec/libavutil: Implementation of AAC_fixed_decoder (LC-module) [3/4]

Michael Niedermayer michaelni at gmx.at
Sat May 16 02:12:17 CEST 2015


On Thu, May 14, 2015 at 03:33:55PM +0200, Nedeljko Babic wrote:
> From: Djordje Pesut <djordje.pesut at imgtec.com>
> 
> Add fixed point implementation
> 
> Signed-off-by: Nedeljko Babic <nedeljko.babic at imgtec.com>
> ---
>  libavcodec/aac.h             | 101 ++++++++--
>  libavcodec/aacdec.c          |   5 +
>  libavcodec/aacdec_fixed.c    | 446 +++++++++++++++++++++++++++++++++++++++++++
>  libavcodec/aacdec_template.c | 433 ++++++++++++++++++++++++++++-------------
>  libavcodec/lpc.h             |  15 +-
>  libavcodec/mdct_template.c   |   5 +

>  libavutil/fixed_dsp.c        |  70 ++++++-
>  libavutil/fixed_dsp.h        |  53 +++++

the changes to libavutil should be split into a seperate patch


>  8 files changed, 965 insertions(+), 163 deletions(-)
>  create mode 100644 libavcodec/aacdec_fixed.c
> 
> diff --git a/libavcodec/aac.h b/libavcodec/aac.h
> index 23ec085..571f8b9 100644
> --- a/libavcodec/aac.h
> +++ b/libavcodec/aac.h
> @@ -30,9 +30,62 @@
>  #ifndef AVCODEC_AAC_H
>  #define AVCODEC_AAC_H
>  
> +#ifndef USE_FIXED
> +#define USE_FIXED 0
> +#endif
> +
> +#if USE_FIXED
> +
> +#define FFT_FLOAT    0
> +#define FFT_FIXED_32 1
> +
> +#define AAC_RENAME(x)       x ## _fixed
> +#define AAC_RENAME_32(x)    x ## _fixed_32
> +#define INTFLOAT int
> +#define SHORTFLOAT int16_t

> +#define AAC_FLOAT aac_float_t

i think *_t is reserved in POSIX to some extend

[...]


> +#include <assert.h>

we use av_assert*()


> +#include <errno.h>

is that really used ?


[...]
> +/**
> + * Apply dependent channel coupling (applied before IMDCT).
> + *
> + * @param   index   index into coupling gain array
> + */
> +static void apply_dependent_coupling_fixed(AACContext *ac,
> +                                     SingleChannelElement *target,
> +                                     ChannelElement *cce, int index)
> +{
> +    IndividualChannelStream *ics = &cce->ch[0].ics;
> +    const uint16_t *offsets = ics->swb_offset;
> +    int *dest = target->coeffs;
> +    const int *src = cce->ch[0].coeffs;
> +    int g, i, group, k, idx = 0;
> +    if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) {
> +        av_log(ac->avctx, AV_LOG_ERROR,
> +               "Dependent coupling is not supported together with LTP\n");
> +        return;
> +    }

> +    for (g = 0; g < ics->num_window_groups; g++) {
> +        for (i = 0; i < ics->max_sfb; i++, idx++) {
> +            if (cce->ch[0].band_type[idx] != ZERO_BT) {
> +                const int gain = cce->coup.gain[index][idx];
> +                int shift, round, c, tmp;
> +
> +                if (gain < 0) {
> +                    c = -cce_scale_fixed[-gain & 7];
> +                    shift = (-gain-1024) >> 3;
> +                }
> +                else {
> +                    c = cce_scale_fixed[gain & 7];
> +                    shift = (gain-1024) >> 3;
> +                }
> +
> +                if (shift < 0) {
> +                  shift = -shift;
> +                  round = 1 << (shift - 1);
> +
> +                  for (group = 0; group < ics->group_len[g]; group++) {
> +                      for (k = offsets[i]; k < offsets[i + 1]; k++) {
> +                          tmp = (int)(((int64_t)src[group * 128 + k] * c + \
> +                                       (int64_t)0x1000000000) >> 37);
> +                          dest[group * 128 + k] += (tmp + round) >> shift;
> +                      }
> +                  }
> +                }

there is something wrong with the indention level

[...]
>      memcpy(sce->ltp_state,      sce->ltp_state+1024, 1024 * sizeof(*sce->ltp_state));
> @@ -2341,22 +2472,27 @@ static void update_ltp(AACContext *ac, SingleChannelElement *sce)
>  static void imdct_and_windowing(AACContext *ac, SingleChannelElement *sce)
>  {
>      IndividualChannelStream *ics = &sce->ics;
> -    float *in    = sce->coeffs;
> -    float *out   = sce->ret;
> -    float *saved = sce->saved;
> -    const float *swindow      = ics->use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128;
> -    const float *lwindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_long_1024 : ff_sine_1024;
> -    const float *swindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_short_128 : ff_sine_128;
> -    float *buf  = ac->buf_mdct;
> -    float *temp = ac->temp;
> +    INTFLOAT *in    = sce->coeffs;
> +    INTFLOAT *out   = sce->ret;
> +    INTFLOAT *saved = sce->saved;
> +    const INTFLOAT *swindow      = ics->use_kb_window[0] ? AAC_RENAME(ff_aac_kbd_short_128) : AAC_RENAME(ff_sine_128);
> +    const INTFLOAT *lwindow_prev = ics->use_kb_window[1] ? AAC_RENAME(ff_aac_kbd_long_1024) : AAC_RENAME(ff_sine_1024);
> +    const INTFLOAT *swindow_prev = ics->use_kb_window[1] ? AAC_RENAME(ff_aac_kbd_short_128) : AAC_RENAME(ff_sine_128);
> +    INTFLOAT *buf  = ac->buf_mdct;
> +    INTFLOAT *temp = ac->temp;
>      int i;
>  
>      // imdct
>      if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
>          for (i = 0; i < 1024; i += 128)
>              ac->mdct_small.imdct_half(&ac->mdct_small, buf + i, in + i);
> -    } else
> +    } else {
>          ac->mdct.imdct_half(&ac->mdct, buf, in);
> +#if USE_FIXED
> +        for (i=0; i<1024; i++)
> +          buf[i] = (buf[i] + 4) >> 3;
> +#endif /* USE_FIXED */
> +    }
>  
>      /* window overlapping
>       * NOTE: To simplify the overlapping code, all 'meaningless' short to long
> @@ -2368,7 +2504,7 @@ static void imdct_and_windowing(AACContext *ac, SingleChannelElement *sce)
>              (ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) {
>          ac->fdsp->vector_fmul_window(    out,               saved,            buf,         lwindow_prev, 512);
>      } else {
> -        memcpy(                         out,               saved,            448 * sizeof(float));
> +        memcpy(                         out,               saved,            448 * sizeof(INTFLOAT));
>  
>          if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
>              ac->fdsp->vector_fmul_window(out + 448 + 0*128, saved + 448,      buf + 0*128, swindow_prev, 64);
> @@ -2376,65 +2512,71 @@ static void imdct_and_windowing(AACContext *ac, SingleChannelElement *sce)
>              ac->fdsp->vector_fmul_window(out + 448 + 2*128, buf + 1*128 + 64, buf + 2*128, swindow,      64);
>              ac->fdsp->vector_fmul_window(out + 448 + 3*128, buf + 2*128 + 64, buf + 3*128, swindow,      64);
>              ac->fdsp->vector_fmul_window(temp,              buf + 3*128 + 64, buf + 4*128, swindow,      64);
> -            memcpy(                     out + 448 + 4*128, temp, 64 * sizeof(float));
> +            memcpy(                     out + 448 + 4*128, temp, 64 * sizeof(INTFLOAT));
>          } else {
>              ac->fdsp->vector_fmul_window(out + 448,         saved + 448,      buf,         swindow_prev, 64);
> -            memcpy(                     out + 576,         buf + 64,         448 * sizeof(float));
> +            memcpy(                     out + 576,         buf + 64,         448 * sizeof(INTFLOAT));
>          }
>      }
>  

>      // buffer update
>      if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
> -        memcpy(                     saved,       temp + 64,         64 * sizeof(float));
> +        memcpy(                     saved,       temp + 64,         64 * sizeof(INTFLOAT));
>          ac->fdsp->vector_fmul_window(saved + 64,  buf + 4*128 + 64, buf + 5*128, swindow, 64);
>          ac->fdsp->vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 64);
>          ac->fdsp->vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 64);
> -        memcpy(                     saved + 448, buf + 7*128 + 64,  64 * sizeof(float));
> +        memcpy(                     saved + 448, buf + 7*128 + 64,  64 * sizeof(INTFLOAT));
>      } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
> -        memcpy(                     saved,       buf + 512,        448 * sizeof(float));
> -        memcpy(                     saved + 448, buf + 7*128 + 64,  64 * sizeof(float));
> +        memcpy(                     saved,       buf + 512,        448 * sizeof(INTFLOAT));
> +        memcpy(                     saved + 448, buf + 7*128 + 64,  64 * sizeof(INTFLOAT));
>      } else { // LONG_STOP or ONLY_LONG
> -        memcpy(                     saved,       buf + 512,        512 * sizeof(float));
> +        memcpy(                     saved,       buf + 512,        512 * sizeof(INTFLOAT));

these should use sizeof(*saved) or something not sizeof(INTFLOAT)
so as to make it more robust

[...]

> diff --git a/libavutil/fixed_dsp.h b/libavutil/fixed_dsp.h
> index ff6f365..73859c0 100644
> --- a/libavutil/fixed_dsp.h
> +++ b/libavutil/fixed_dsp.h
> @@ -54,6 +54,8 @@
>  #include "libavcodec/mathops.h"
>  
>  typedef struct AVFixedDSPContext {
> +    /* assume len is a multiple of 16, and arrays are 32-byte aligned */
> +
>      /**
>       * Overlap/add with window function.
>       * Used primarily by MDCT-based audio codecs.
> @@ -92,6 +94,57 @@ typedef struct AVFixedDSPContext {
>       */
>      void (*vector_fmul_window)(int32_t *dst, const int32_t *src0, const int32_t *src1, const int32_t *win, int len);
>  
> +    /**
> +     * Fixed-point multiplication that calculates the product of two vectors of
> +     * integers and stores the result in a vector of integers.
> +     *
> +     * @param dst  output vector
> +     *             constraints: 32-byte aligned
> +     * @param src0 first input vector
> +     *             constraints: 32-byte aligned
> +     * @param src1 second input vector
> +     *             constraints: 32-byte aligned
> +     * @param len  number of elements in the input
> +     *             constraints: multiple of 16
> +     */
> +    void (*vector_fmul)(int *dst, const int *src0, const int *src1,
> +                        int len);
> +
> +    void (*vector_fmul_reverse)(int *dst, const int *src0, const int *src1, int len);
> +    /**
> +     * Calculate the product of two vectors of integers, add a third vector of
> +     * integers and store the result in a vector of integers.
> +     *
> +     * @param dst  output vector
> +     *             constraints: 32-byte aligned
> +     * @param src0 first input vector
> +     *             constraints: 32-byte aligned
> +     * @param src1 second input vector
> +     *             constraints: 32-byte aligned
> +     * @param src1 third input vector
> +     *             constraints: 32-byte aligned
> +     * @param len  number of elements in the input
> +     *             constraints: multiple of 16
> +     */
> +    void (*vector_fmul_add)(int *dst, const int *src0, const int *src1,
> +                            const int *src2, int len);
> +
> +    /**
> +     * Calculate the scalar product of two vectors of integers.
> +     * @param v1  first vector, 16-byte aligned
> +     * @param v2  second vector, 16-byte aligned
> +     * @param len length of vectors, multiple of 4
> +     */
> +    int (*scalarproduct_fixed)(const int *v1, const int *v2, int len);
> +
> +    /**
> +     * Calculate the sum and difference of two vectors of integers.
> +     *
> +     * @param v1  first input vector, sum output, 16-byte aligned
> +     * @param v2  second input vector, difference output, 16-byte aligned
> +     * @param len length of vectors, multiple of 4
> +     */
> +    void (*butterflies_fixed)(int *av_restrict v1, int *av_restrict v2, int len);

these  ignore the 1.0 point / amount of shifting done
the documentation should be sufficient so that someone could write
a working implementation based on just the documentation


[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Concerning the gods, I have no means of knowing whether they exist or not
or of what sort they may be, because of the obscurity of the subject, and
the brevity of human life -- Protagoras
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20150516/69b7173d/attachment.asc>


More information about the ffmpeg-devel mailing list