[FFmpeg-devel] AAC decoder round 9

Michael Niedermayer michaelni
Mon Aug 18 23:19:44 CEST 2008


On Mon, Aug 18, 2008 at 08:42:53PM +0100, Robert Swain wrote:
> $subj
> 
> Will this be the last...? :)

No, not yet :)


> 
> Rob

> Index: libavcodec/aac.c
> ===================================================================
> --- libavcodec/aac.c	(revision 14828)
> +++ libavcodec/aac.c	(working copy)
> @@ -94,6 +94,17 @@
>  static VLC vlc_spectral[11];
>  
>  
> +// TODO: Maybe add to dsputil?!
> +#if 0
> +static void vector_fmul_add_add_add(DSPContext * dsp, float * dst, const float * src0, const float * src1,
> +        const float * src2, const float * src3, float src4, int len) {
> +    int i;
> +    dsp->vector_fmul_add_add(dst, src0, src1, src2, src4, len, 1);
> +    for (i = 0; i < len; i++)
> +        dst[i] += src3[i];
> +}
> +#endif
> +
>  /**
>   * Configure output channel order based on the current program configuration element.
>   *

ohh well, if you want this #if 0 code so be it
ok, but please remove the "// TODO: Maybe add to dsputil?!" we do not want
to move this there unless we find out that it is actually needed for these
windows ...


> @@ -605,6 +616,44 @@
>  }
>  
>  /**
> + * Decode Temporal Noise Shaping data; reference: table 4.48.
> + *
> + * @return  Returns error status. 0 - OK, !0 - error
> + */
> +static int decode_tns(AACContext * ac, TemporalNoiseShaping * tns,
> +        GetBitContext * gb, const IndividualChannelStream * ics) {
> +    int w, filt, i, coef_len, coef_res, coef_compress;
> +    const int is8 = ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE;
> +    const int tns_max_order = is8 ? 7 : ac->m4ac.object_type == AOT_AAC_MAIN ? 20 : 12;
> +    for (w = 0; w < ics->num_windows; w++) {
> +        tns->n_filt[w] = get_bits(gb, 2 - is8);
> +
> +        if (tns->n_filt[w])
> +            coef_res = get_bits1(gb);
> +
> +        for (filt = 0; filt < tns->n_filt[w]; filt++) {
> +            int tmp2_idx;
> +            tns->length[w][filt] = get_bits(gb, 6 - 2*is8);
> +
> +            if ((tns->order[w][filt] = get_bits(gb, 5 - 2*is8)) > tns_max_order) {
> +                av_log(ac->avccontext, AV_LOG_ERROR, "TNS filter order %d is greater than maximum %d.",
> +                       tns->order[w][filt], tns_max_order);
> +                tns->order[w][filt] = 0;
> +                return -1;
> +            }
> +            tns->direction[w][filt] = get_bits1(gb);
> +            coef_compress = get_bits1(gb);
> +            coef_len = coef_res + 3 - coef_compress;
> +            tmp2_idx = 2*coef_compress + coef_res;
> +
> +            for (i = 0; i < tns->order[w][filt]; i++)
> +                tns->coef[w][filt][i] = tns_tmp2_map[tmp2_idx][get_bits(gb, coef_len)];
> +        }
> +    }
> +    return 0;
> +}
> +
> +/**

ok


>   * Decode Mid/Side data; reference: table 4.54.
>   *
>   * @param   ms_present  Indicates mid/side stereo presence. [0] mask is all 0s;
> @@ -1067,6 +1116,57 @@
>  }
>  
>  /**
> + * Decode Temporal Noise Shaping filter coefficients and apply all-pole filters; reference: 4.6.9.3.
> + *
> + * @param   decode  1 if tool is used normally, 0 if tool is used in LTP.
> + * @param   coef    spectral coefficients
> + */
> +static void apply_tns(float coef[1024], TemporalNoiseShaping * tns, IndividualChannelStream * ics, int decode) {
> +    const int mmm = FFMIN(ics->tns_max_bands,  ics->max_sfb);
> +    int w, filt, m, i, ib;
> +    int bottom, top, order, start, end, size, inc;
> +    float tmp;
> +    float lpc[TNS_MAX_ORDER + 1], b[TNS_MAX_ORDER + 1];
> +
> +    for (w = 0; w < ics->num_windows; w++) {
> +        bottom = ics->num_swb;
> +        for (filt = 0; filt < tns->n_filt[w]; filt++) {
> +            top    = bottom;
> +            bottom = FFMAX(0, top - tns->length[w][filt]);
> +            order  = tns->order[w][filt];
> +            if (order == 0)
> +                continue;
> +

> +            // tns_decode_coef
> +            lpc[0] = 1;
> +            for (m = 1; m <= order; m++) {
> +                lpc[m] = tns->coef[w][filt][m - 1];
> +                for (i = 1; i < m; i++)
> +                    b[i] = lpc[i] + lpc[m] * lpc[m-i];
> +                for (i = 1; i < m; i++)
> +                    lpc[i] = b[i];
> +            }

This loop looks oddly similar to the end of compute_lpc_coefs()
and eval_lpc_coeffs() can something be factored out here?



> +
> +            start = ics->swb_offset[FFMIN(bottom, mmm)];
> +            end   = ics->swb_offset[FFMIN(   top, mmm)];
> +            if ((size = end - start) <= 0)
> +                continue;
> +            if (tns->direction[w][filt]) {
> +                inc = -1; start = end - 1;
> +            } else {
> +                inc = 1;
> +            }
> +            start += w * 128;
> +
> +            // ar filter
> +            for (m = 0; m < size; m++, start += inc)
> +                for (i = 1; i <= FFMIN(m, order); i++)
> +                    coef[start] -= coef[start - i*inc] * lpc[i];
> +        }
> +    }
> +}
> +
> +/**
>   * Conduct IMDCT and windowing.
>   */
>  static void imdct_and_windowing(AACContext * ac, SingleChannelElement * sce) {

> Index: libavcodec/aac.h
> ===================================================================
> --- libavcodec/aac.h	(revision 14828)
> +++ libavcodec/aac.h	(working copy)
> @@ -149,6 +149,18 @@
>  } IndividualChannelStream;
>  
>  /**
> + * Temporal Noise Shaping
> + */
> +typedef struct {
> +    int present;
> +    int n_filt[8];
> +    int length[8][4];
> +    int direction[8][4];
> +    int order[8][4];
> +    float coef[8][4][TNS_MAX_ORDER];
> +} TemporalNoiseShaping;
> +
> +/**
>   * Dynamic Range Control - decoded from the bitstream but not processed further.
>   */
>  typedef struct {
> Index: libavcodec/aacdectab.h
> ===================================================================
> --- libavcodec/aacdectab.h	(revision 14828)
> +++ libavcodec/aacdectab.h	(working copy)
> @@ -171,4 +171,39 @@
>  };
>  // @}
>  
> +/* @name tns_tmp2_map
> + * Tables of the tmp2[] arrays of LPC coefficients used for TNS.
> + * The suffix _M_N[] indicate the values of coef_compress and coef_res
> + * respectively.
> + * @{
> + */
> +static const float tns_tmp2_map_1_3[4] = {
> +     0.00000000,  0.43388373, -0.64278758, -0.34202015,
> +};
> +
> +static const float tns_tmp2_map_0_3[8] = {
> +     0.00000000,  0.43388373,  0.78183150,  0.97492790,
> +    -0.98480773, -0.86602539, -0.64278758, -0.34202015,
> +};
> +
> +static const float tns_tmp2_map_1_4[8] = {
> +     0.00000000,  0.20791170,  0.40673664,  0.58778524,
> +    -0.67369562, -0.52643216, -0.36124167, -0.18374951,
> +};
> +
> +static const float tns_tmp2_map_0_4[16] = {
> +     0.00000000,  0.20791170,  0.40673664,  0.58778524,
> +     0.74314481,  0.86602539,  0.95105654,  0.99452192,
> +    -0.99573416, -0.96182561, -0.89516330, -0.79801720,
> +    -0.67369562, -0.52643216, -0.36124167, -0.18374951,
> +};
> +
> +static const float *tns_tmp2_map[4] = {
> +    tns_tmp2_map_0_3,
> +    tns_tmp2_map_0_4,
> +    tns_tmp2_map_1_3,
> +    tns_tmp2_map_1_4
> +};
> +// @}
> +
>  #endif /* FFMPEG_AACDECTAB_H */

ok

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

I have often repented speaking, but never of holding my tongue.
-- Xenocrates
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20080818/87c3a06e/attachment.pgp>



More information about the ffmpeg-devel mailing list