[FFmpeg-devel] [PATCH] AAC Decoder - Round 2.

Robert Swain robert.swain
Mon Jun 23 15:10:56 CEST 2008


2008/6/20 Michael Niedermayer <michaelni at gmx.at>:
> On Thu, Jun 19, 2008 at 04:22:57PM +0100, Robert Swain wrote:
> [...]
>> +static void vector_fmul_add_add_add(AACContext * ac, float * dst, const float * src0, const float * src1, const float * src2, const float * src3, float src4, int len) {
>> +    int i;
>> +    ac->dsp.vector_fmul_add_add(dst, src0, src1, src2, src4, len, 1);
>> +    for (i = 0; i < len; i++)
>> +        dst[i] += src3[i];
>> +}
>
> why does AAC need this and other codecs not?
> (iam askng as my gut says there might be a bug but i could be wrong, i didnt
>  investigate this too carefull but IIRC there was some comment somewhere in
>  the src about short windows having artifacts and its strange that other
>  codecs do not need above)

The eight short window sequence has to take saved data both from the
saved frame and from the saved short window hence the additional
addition.

> [...]
>> +
>> +    for (g = 0; g < ics->num_window_groups; g++) {
>> +        for (i = 0; i < ics->max_sfb; i++) {
>> +            if (cb[g][i] == NOISE_HCB) {
>> +                for (group = 0; group < ics->group_len[g]; group++) {
>> +                    float energy = 0;
>> +                    float scale = 1.;// / (float)(offsets[i+1] - offsets[i]);
>> +                    for (k = offsets[i]; k < offsets[i+1]; k++)
>> +                        energy += (float)icoef[group*128+k] * icoef[group*128+k];
>> +                    scale *= sf[g][i] / sqrt(energy);
>
> are you sure that the random values have to be normalized like that?
> I suspect energy is supposed tp be a constant.

That's how it is in the spec. From section 4.6.13 Perceptual Noise
Substitution (PNS):

The energy information for percpetual noise substitution decoding is
represented by a "noise energy" value indicating the overall power of
the substituted spectral coefficients in steps of 1.5 dB. If noise
substitution coding is active for a particular group and scalefactor
band, a noise energy value is transmitted instead of the scalefactor
of the respective channel.

> [...]
>> +static void coupling_dependent_trans(AACContext * ac, che_struct * cc, sce_struct * sce, int index) {
>> +    ics_struct * ics = &cc->ch[0].ics;
>> +    const uint16_t * offsets = ics->swb_offset;
>> +    float * dest = sce->coeffs;
>> +    float * src = cc->ch[0].coeffs;
>> +    int g, i, group, k;
>> +    if(ac->m4ac.object_type == AOT_AAC_LTP) {
>> +        av_log(ac->avccontext, 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++) {
>> +            if (cc->ch[0].cb[g][i] != ZERO_HCB) {
>> +                float gain = cc->coup.gain[index][g][i] * sce->mixing_gain;
>> +                for (group = 0; group < ics->group_len[g]; group++) {
>
>> +                    for (k = offsets[i]; k < offsets[i+1]; k++) {
>> +                        dest[group*128+k] += gain * src[group*128+k];
>> +                    }
>
> this should be moved into dsputil at some point i think (unless we
> already have such routine there)
>
> [...]
>> +static int output_samples(AVCodecContext * avccontext, uint16_t * data, int * data_size) {
>> +    AACContext * ac = avccontext->priv_data;
>> +    int i, ch;
>> +    float *c, *l, *r, *sl, *sr, *out;
>> +
>> +    if (!ac->is_saved) {
>> +        ac->is_saved = 1;
>> +        *data_size = 0;
>> +        return 0;
>> +    }
>> +
>> +    if(ac->mm[MIXDOWN_CENTER]) {
>> +        /* Matrix mixdown */
>> +        l   = ac->mm[MIXDOWN_FRONT ]->ch[0].ret;
>> +        r   = ac->mm[MIXDOWN_FRONT ]->ch[1].ret;
>> +        c   = ac->mm[MIXDOWN_CENTER]->ch[0].ret;
>> +        sl  = ac->mm[MIXDOWN_BACK  ]->ch[0].ret;
>> +        sr  = ac->mm[MIXDOWN_BACK  ]->ch[1].ret;
>> +        out = ac->interleaved_output;
>> +
>
>> +        if(avccontext->channels == 2) {
>> +            if(ac->pcs.pseudo_surround) {
>> +                for(i = 0; i < 1024; i++) {
>> +                    *out++ = *l++ + *c   - *sl   - *sr   - ac->add_bias * 3;
>> +                    *out++ = *r++ + *c++ + *sl++ + *sr++ - ac->add_bias * 3;
>> +                }
>> +            } else {
>> +                for(i = 0; i < 1024; i++) {
>> +                    *out++ = *l++ + *c   + *sl++ - ac->add_bias * 2;
>> +                    *out++ = *r++ + *c++ + *sr++ - ac->add_bias * 2;
>> +                }
>> +            }
>> +
>> +        } else {
>> +            assert(avccontext->channels == 1);
>> +            for(i = 0; i < 1024; i++) {
>> +                *out++ = *l++ + *r++ + *c++ + *sl++ + *sr++ - ac->add_bias * 4;
>> +            }
>> +        }
>
> also things for dsputil

I'm going to mark these as dsputil-isable with comments.

Rob




More information about the ffmpeg-devel mailing list