[FFmpeg-devel] AAC decoder round 6

Michael Niedermayer michaelni
Sat Aug 9 18:25:11 CEST 2008


On Sat, Aug 09, 2008 at 12:25:09PM +0100, Robert Swain wrote:
> $subj
[...]

> +const uint8_t ff_aac_num_swb_1024[] = {
> +    41, 41, 47, 49, 49, 51, 47, 47, 43, 43, 43, 40
> +};
> +
> +const uint8_t ff_aac_num_swb_128[] = {
> +    12, 12, 12, 14, 14, 14, 15, 15, 15, 15, 15, 15
> +};
> +

dont these 2 belong to the swb offset tables? if so i think they should
be in the same file unless iam missing something either way these 2 are
ok [with static if they are only used by 1 file]


>  const uint32_t ff_aac_scalefactor_code[121] = {
>      0x3ffe8, 0x3ffe6, 0x3ffe7, 0x3ffe5, 0x7fff5, 0x7fff1, 0x7ffed, 0x7fff6,
>      0x7ffee, 0x7ffef, 0x7fff0, 0x7fffc, 0x7fffd, 0x7ffff, 0x7fffe, 0x7fff7,
> @@ -796,6 +809,13 @@
>       4064.0312908,  4074.6805676,  4085.3368071,  4096.0000000,
>  };
>  
> +/**
> + * Table of pow(2, (i - 200)/4.) used for different purposes depending on the
> + * range of indices to the table:
> + * [ 0, 255] scale factor decoding when using C dsp.float_to_int16
> + * [60, 315] scale factor decoding when using SIMD dsp.float_to_int16
> + * [45, 300] intensity stereo position decoding mapped in reverse order i.e. 0->300, 1->299, ..., 254->46, 255->45
> + */
>  const float ff_aac_pow2sf_tab[316] = {
>      8.88178420e-16, 1.05622810e-15, 1.25607397e-15, 1.49373210e-15,
>      1.77635684e-15, 2.11245619e-15, 2.51214793e-15, 2.98746420e-15,

ok

[...]

> +/* @name number of scalefactor window bands for long and short transform windows respectively
> + * @{
> + */
> +extern const uint8_t ff_aac_num_swb_1024[];
> +extern const uint8_t ff_aac_num_swb_128 [];
> +// @}
> +
>  extern const uint32_t ff_aac_scalefactor_code[121];
>  extern const uint8_t  ff_aac_scalefactor_bits[121];
>  

ok depending on where these tables end up (see above)


> Index: libavcodec/aac.c
> ===================================================================
> --- libavcodec/aac.c	(revision 14674)
> +++ libavcodec/aac.c	(working copy)
> @@ -99,6 +99,100 @@
>  static VLC vlc_spectral[11];
>  
>  
[...]
> +/**
> + * Configure output channel order based on the current program configuration element.
> + *
> + * @param   che_pos current channel position configuration
> + * @param   new_che_pos New channel position configuration - we only do something if it differs from the current one.
> + *
> + * @return  Returns error status. 0 - OK, !0 - error
> + */
> +static int output_configure(AACContext *ac, enum ChannelPosition che_pos[4][MAX_ELEM_ID],
> +        enum ChannelPosition new_che_pos[4][MAX_ELEM_ID]) {
> +    AVCodecContext *avctx = ac->avccontext;
> +    int i, j, channels = 0;
> +
> +    if(!memcmp(che_pos, new_che_pos, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0])))
> +        return 0; /* no change */
> +
> +    memcpy(che_pos, new_che_pos, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0]));
> +
> +    /* Allocate or free elements depending on if they are in the
> +     * current program configuration.
> +     *
> +     * Set up default 1:1 output mapping.
> +     *
> +     * For a 5.1 stream the output order will be:
> +     *    [ Front Left ] [ Front Right ] [ Center ] [ LFE ] [ Surround Left ] [ Surround Right ]
> +     */
> +
> +    for(i = 0; i < MAX_ELEM_ID; i++) {
> +        for(j = 0; j < 4; j++) {
> +            if(che_pos[j][i]) {
> +                if(!ac->che[j][i] && !(ac->che[j][i] = av_mallocz(sizeof(ChannelElement))))
> +                    return AVERROR(ENOMEM);
> +                if(j != TYPE_CCE) {

i think j should be renamed to type


[...]
> +/**
> + * Decode an array of 4 bit element IDs, optionally interleaved with a stereo/mono switching bit.
> + *
> + * @param cpe_map Stereo (Channel Pair Element) map, NULL if stereo bit is not present.
> + * @param sce_map mono (Single Channel Element) map
> + * @param type speaker type/position for these channels
> + */
> +static void decode_channel_map(enum ChannelPosition *cpe_map,
> +        enum ChannelPosition *sce_map, enum ChannelPosition type, GetBitContext * gb, int n) {
> +    while(n--) {
> +        enum ChannelPosition *map = cpe_map && get_bits1(gb) ? cpe_map : sce_map; // stereo or mono map
> +        map[get_bits(gb, 4)] = type;
> +    }
> +}

ok


> +
> +/**
> + * Decode program configuration element; reference: table 4.2.
> + *
> + * @param   new_che_pos New channel position configuration - we only do something if it differs from the current one.
> + *
> + * @return  Returns error status. 0 - OK, !0 - error
> + */
> +static int decode_pce(AACContext * ac, enum ChannelPosition new_che_pos[4][MAX_ELEM_ID],
> +        GetBitContext * gb) {
> +    int num_front, num_side, num_back, num_lfe, num_assoc_data, num_cc;
> +
> +    skip_bits(gb, 2);  // object_type
> +
> +    ac->m4ac.sampling_index = get_bits(gb, 4);
> +    if(ac->m4ac.sampling_index > 12) {
> +        av_log(ac->avccontext, AV_LOG_ERROR, "invalid sampling rate index %d\n", ac->m4ac.sampling_index);
> +        return -1;
> +    }
> +    ac->m4ac.sample_rate = ff_mpeg4audio_sample_rates[ac->m4ac.sampling_index];

ok
its a mess but thats the way AAC is designed i guess ...



>      num_front       = get_bits(gb, 4);
>      num_side        = get_bits(gb, 4);
>      num_back        = get_bits(gb, 4);
> @@ -130,6 +224,150 @@
>      return 0;
>  }
>  
> +/**
> + * Set up channel positions based on a default channel configuration
> + * as specified in table 1.17.
> + *
> + * @param   new_che_pos New channel position configuration - we only do something if it differs from the current one.
> + *
> + * @return  Returns error status. 0 - OK, !0 - error
> + */
> +static int set_default_channel_config(AACContext *ac, enum ChannelPosition new_che_pos[4][MAX_ELEM_ID],
> +        int channel_config)
> +{
> +    if(channel_config < 1 || channel_config > 7) {
> +        av_log(ac->avccontext, AV_LOG_ERROR, "invalid default channel configuration (%d)\n",
> +               channel_config);
> +        return -1;
> +    }
> +
> +    /* default channel configurations:
> +     *
> +     * 1ch : front center (mono)
> +     * 2ch : L + R (stereo)
> +     * 3ch : front center + L + R
> +     * 4ch : front center + L + R + back center
> +     * 5ch : front center + L + R + back stereo
> +     * 6ch : front center + L + R + back stereo + LFE
> +     * 7ch : front center + L + R + outer front left + outer front right + back stereo + LFE
> +     */
> +
> +    if(channel_config != 2)
> +        new_che_pos[TYPE_SCE][0] = AAC_CHANNEL_FRONT; // front center (or mono)
> +    if(channel_config > 1)
> +        new_che_pos[TYPE_CPE][0] = AAC_CHANNEL_FRONT; // L + R (or stereo)
> +    if(channel_config == 4)
> +        new_che_pos[TYPE_SCE][1] = AAC_CHANNEL_BACK;  // back center
> +    if(channel_config > 4)
> +        new_che_pos[TYPE_CPE][(channel_config == 7) + 1]
> +                                 = AAC_CHANNEL_BACK;  // back stereo
> +    if(channel_config > 5)
> +        new_che_pos[TYPE_LFE][0] = AAC_CHANNEL_LFE;   // LFE
> +    if(channel_config == 7)
> +        new_che_pos[TYPE_CPE][1] = AAC_CHANNEL_FRONT; // outer front left + outer front right
> +
> +    return 0;
> +}

ok


> +
> +/**
> + * Decode GA "General Audio" specific configuration; reference: table 4.1.
> + *
> + * @return  Returns error status. 0 - OK, !0 - error
> + */
> +static int decode_ga_specific_config(AACContext * ac, GetBitContext * gb, int channel_config) {
> +    enum ChannelPosition new_che_pos[4][MAX_ELEM_ID];
> +    int extension_flag, ret;
> +
> +    if(get_bits1(gb)) {  // frameLengthFlag
> +        av_log(ac->avccontext, AV_LOG_ERROR, "960/120 MDCT window is not supported.\n");

is this "update to latest svn; sample welcome or patch welcome" ?
i think we have a function to print such messages, i dont remember what its
name was though


> +        return -1;
> +    }
> +
> +    if (get_bits1(gb))       // dependsOnCoreCoder
> +        skip_bits(gb, 14);   // coreCoderDelay
> +    extension_flag = get_bits1(gb);
> +
> +    if(ac->m4ac.object_type == AOT_AAC_SCALABLE ||
> +       ac->m4ac.object_type == AOT_ER_AAC_SCALABLE)
> +        skip_bits(gb, 3);     // layerNr
> +
> +    memset(new_che_pos, 0, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0]));
> +    if (channel_config == 0) {
> +        skip_bits(gb, 4);  // element_instance_tag
> +        if((ret = decode_pce(ac, new_che_pos, gb)))
> +            return ret;
> +    } else {
> +        if((ret = set_default_channel_config(ac, new_che_pos, channel_config)))
> +            return ret;
> +    }
> +    if((ret = output_configure(ac, ac->che_pos, new_che_pos)))
> +        return ret;
> +
> +    if (extension_flag) {
> +        switch (ac->m4ac.object_type) {
> +            case AOT_ER_BSAC:
> +                skip_bits(gb, 5);    // numOfSubFrame
> +                skip_bits(gb, 11);   // layer_length
> +                break;
> +            case AOT_ER_AAC_LC:
> +            case AOT_ER_AAC_LTP:
> +            case AOT_ER_AAC_SCALABLE:
> +            case AOT_ER_AAC_LD:
> +                skip_bits(gb, 3);  /* aacSectionDataResilienceFlag
> +                                    * aacScalefactorDataResilienceFlag
> +                                    * aacSpectralDataResilienceFlag
> +                                    */
> +                break;
> +        }
> +        skip_bits1(gb);    // extensionFlag3 (TBD in version 3)
> +    }
> +    return 0;
> +}

ok


> +
> +/**
> + * Decode audio specific configuration; reference: table 1.13.
> + *
> + * @param   data        pointer to AVCodecContext extradata
> + * @param   data_size   size of AVCCodecContext extradata
> + *
> + * @return  Returns error status. 0 - OK, !0 - error
> + */
> +static int decode_audio_specific_config(AACContext * ac, void *data, int data_size) {
> +    GetBitContext gb;
> +    int i;
> +
> +    init_get_bits(&gb, data, data_size * 8);
> +
> +    if((i = ff_mpeg4audio_get_config(&ac->m4ac, data, data_size)) < 0)
> +        return -1;
> +
> +    skip_bits_long(&gb, i);
> +
> +    switch (ac->m4ac.object_type) {
> +    case AOT_AAC_LC:
> +        if (decode_ga_specific_config(ac, &gb, ac->m4ac.chan_config))
> +            return -1;
> +        break;
> +    default:
> +        av_log(ac->avccontext, AV_LOG_ERROR, "Audio object type %s%d is not supported.\n",
> +               ac->m4ac.sbr == 1? "SBR+" : "", ac->m4ac.object_type);
> +        return -1;
> +    }
> +    return 0;
> +}

ok


> +
> +/**
> + * linear congruential pseudorandom number generator
> + *
> + * @param   state   pointer to the current state of the generator
> + *
> + * @return  Returns a 32-bit pseudorandom integer
> + */
> +static inline int32_t lcg_random(int32_t *state) {
> +    *state = *state * 1664525 + 1013904223;
> +    return *state;
> +}

always_inline, besides

int lcg_random(int previous_val)
state=array[i] = lcg_random(state);

is IMHO cleaner


> +
>  static av_cold int aac_decode_init(AVCodecContext * avccontext) {
>      AACContext * ac = avccontext->priv_data;
>      int i;
> @@ -140,6 +378,7 @@
>          decode_audio_specific_config(ac, avccontext->extradata, avccontext->extradata_size))
>          return -1;
>  
> +    avccontext->sample_fmt  = SAMPLE_FMT_S16;
>      avccontext->sample_rate = ac->m4ac.sample_rate;
>      avccontext->frame_size  = 1024;
>  
> @@ -157,6 +396,8 @@
>  
>      dsputil_init(&ac->dsp, avccontext);
>  
> +    ac->random_state = 0x1f2e3d4c;
> +
>      // -1024 - Compensate wrong IMDCT method.
>      // 32768 - Required to scale values to the correct range for the bias method
>      //         for float to int16 conversion.

ok


[...]

>  
> +/**
> + * Skip data_stream_element; reference: table 4.10.
> + */
> +static void skip_data_stream_element(GetBitContext * gb) {
>      int byte_align = get_bits1(gb);
>      int count = get_bits(gb, 8);
>      if (count == 255)

ok

> @@ -198,6 +448,67 @@
>  }
>  
>  /**
> + * Decode Individual Channel Stream info; reference: table 4.6.
> + *
> + * @param   common_window   Channels have independent [0], or shared [1], Individual Channel Stream information.
> + */
> +static int decode_ics_info(AACContext * ac, IndividualChannelStream * ics, GetBitContext * gb, int common_window) {
> +    unsigned int grouping;
> +    if (get_bits1(gb)) {
> +        av_log(ac->avccontext, AV_LOG_ERROR, "Reserved bit set.\n");
> +        return -1;
> +    }
> +    ics->window_sequence[1] = ics->window_sequence[0];
> +    ics->window_sequence[0] = get_bits(gb, 2);
> +    ics->use_kb_window[1] = ics->use_kb_window[0];
> +    ics->use_kb_window[0] = get_bits1(gb);
> +    ics->num_window_groups = 1;
> +    ics->group_len[0] = 1;

ok


> +    if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
> +        int i;
> +        ics->max_sfb = get_bits(gb, 4);

> +        grouping = get_bits(gb, 7);
> +        for (i = 0; i < 7; i++) {
> +            if (grouping & (1<<(6-i))) {

isnt this if(get_bits1()) ?



> +                ics->group_len[ics->num_window_groups-1]++;
> +            } else {
> +                ics->num_window_groups++;
> +                ics->group_len[ics->num_window_groups-1] = 1;
> +            }
> +        }


> +        ics->swb_offset =     swb_offset_128[ac->m4ac.sampling_index];
> +        ics->num_swb    = ff_aac_num_swb_128[ac->m4ac.sampling_index];
> +    } else {
> +        ics->max_sfb    =                              get_bits(gb, 6);
> +        ics->swb_offset =     swb_offset_1024[ac->m4ac.sampling_index];
> +        ics->num_swb    = ff_aac_num_swb_1024[ac->m4ac.sampling_index];
> +    }

is there something that prevents sampling_index from being >=12 ?
a quick look at ff_mpeg4audio_get_config() indicates that it can at least
be 15.


> +
> +    if(ics->max_sfb > ics->num_swb) {
> +        av_log(ac->avccontext, AV_LOG_ERROR,
> +            "Number of scalefactor bands in group (%d) exceeds limit (%d).\n",
> +            ics->max_sfb, ics->num_swb);
> +        ics->max_sfb = 0;
> +        ics->num_swb = 0;
> +        return -1;
> +    }
> +

> +    if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
> +        ics->num_windows   = 8;
> +        ics->tns_max_bands = tns_max_bands_128[ac->m4ac.sampling_index];
> +    } else {
> +        ics->num_windows   = 1;
> +        ics->tns_max_bands = tns_max_bands_1024[ac->m4ac.sampling_index];
> +        if (get_bits1(gb)) {
> +            av_log(ac->avccontext, AV_LOG_ERROR,
> +                   "Predictor bit set but LTP is not supported.\n");
> +            return -1;
> +        }
> +    }

why is this split from the first part?


> +    return 0;
> +}
> +
> +/**
>   * inverse quantization
>   *
>   * @param   a   quantized value to be dequantized

> @@ -210,6 +521,15 @@
>          return cbrtf(fabsf(a)) * a;
>  }
>  
> +/**
> + * Decode band types (section_data payload); reference: table 4.46.
> + *
> + * @param   band_type           array of the used band type
> + * @param   band_type_run_end   array of the last scalefactor band of a band type run
> + *
> + * @return  Returns error status. 0 - OK, !0 - error
> + */
> +static int decode_band_types(AACContext * ac, enum BandType band_type[120],
>          int band_type_run_end[120], GetBitContext * gb, IndividualChannelStream * ics) {
>      int g, idx = 0;
>      const int bits = (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) ? 3 : 5;

ok


[...]

> +        }
> +    }
> +    return 0;
> +}
>  
> +/**
> + * Decode scalefactors; reference: table 4.47.
>   *
>   * @param   mix_gain            channel gain (Not used by AAC bitstream.)
>   * @param   global_gain         first scalefactor value as scalefactors are differentially coded

ok


[...]

> +/**
> + * Decode Mid/Side data; reference: table 4.54.
> + *
> + * @param   ms_present  Indicates mid/side stereo presence. [0] mask is all 0s;
> + *                      [1] mask is decoded from bitstream; [2] mask is all 1s;
> + *                      [3] reserved for scalable AAC
> + */
> +static void decode_mid_side_stereo(ChannelElement * cpe, GetBitContext * gb,
> +        int ms_present) {

ok


> +    int g, i, idx = 0;
> +    if (ms_present == 1) {

> +        for (g = 0; g < cpe->ch[0].ics.num_window_groups; g++)
> +            for (i = 0; i < cpe->ch[0].ics.max_sfb; i++, idx++)
> +                cpe->ms_mask[idx] = get_bits1(gb);// << i;

what does the '// << i;' mean?
besides, isnt this just

for (i = 0; i < cpe->ch[0].ics.max_sfb * cpe->ch[0].ics.num_window_groups; i++)
    cpe->ms_mask[i] = get_bits1(gb);

?


> +    } else if (ms_present == 2) {
> +        for (g = 0; g < cpe->ch[0].ics.num_window_groups; g++)
> +            memset(&cpe->ms_mask[g*cpe->ch[0].ics.max_sfb], 1, cpe->ch[0].ics.max_sfb * sizeof(cpe->ms_mask[0]));

similar to above the for seems unneeded


[...]

> @@ -330,10 +790,286 @@
>  }
>  
>  /**
> - * Parse Spectral Band Replication extension data; reference: table 4.55.
> + * Dequantize and scale spectral data; reference: 4.6.3.3.
>   *
> + * @param   icoef       array of quantized spectral data
> + * @param   band_type   array of the used band type
> + * @param   sf          array of scalefactors or intensity stereo positions
> + * @param   coef        array of dequantized, scaled spectral data
> + */
> +static void dequant(AACContext * ac, float coef[1024], const int icoef[1024], float sf[120],
> +        const IndividualChannelStream * ics, enum BandType band_type[120]) {
> +    const uint16_t * offsets = ics->swb_offset;
> +    const int c = 1024/ics->num_window_groups;
> +    int g, i, group, k, idx = 0;
> +
> +    for (g = 0; g < ics->num_window_groups; g++) {
> +        memset(coef + g * 128 + offsets[ics->max_sfb], 0, sizeof(float)*(c - offsets[ics->max_sfb]));
> +        for (i = 0; i < ics->max_sfb; i++, idx++) {
> +            if (band_type[idx] == NOISE_BT) {
> +                const float scale = sf[idx] / ((offsets[i+1] - offsets[i]) * PNS_MEAN_ENERGY);
> +                for (group = 0; group < ics->group_len[g]; group++) {
> +                    for (k = offsets[i]; k < offsets[i+1]; k++)
> +                        coef[group*128+k] = lcg_random(&ac->random_state) * scale;
> +                }
> +            } else if (band_type[idx] != INTENSITY_BT && band_type[idx] != INTENSITY_BT2) {
> +                for (group = 0; group < ics->group_len[g]; group++) {
> +                    for (k = offsets[i]; k < offsets[i+1]; k++) {
> +                        coef[group*128+k] = ivquant(icoef[group*128+k]) * sf[idx];
> +                    }
> +                }
> +            }
> +        }
> +        coef  += ics->group_len[g]*128;
> +        icoef += ics->group_len[g]*128;
> +    }
> +}

it might be better to add 128 just outside the innermost loop to avoid
the "group*128 +" inside


> +
> +/**
> + * Decode an individual_channel_stream payload; reference: table 4.44.
> + *
> + * @param   common_window   Channels have independent [0], or shared [1], Individual Channel Stream information.
> + * @param   scale_flag      scalable [1] or non-scalable [0] AAC (Unused until scalable AAC is implemented.)
> + *
> + * @return  Returns error status. 0 - OK, !0 - error
> + */
> +static int decode_ics(AACContext * ac, SingleChannelElement * sce, GetBitContext * gb, int common_window, int scale_flag) {
> +    int icoeffs[1024];
> +    Pulse pulse;
> +    TemporalNoiseShaping * tns = &sce->tns;
> +    IndividualChannelStream * ics = &sce->ics;
> +    float * out = sce->coeffs;
> +    int global_gain, pulse_present = 0;
> +
> +    /* These two assignments are to silence some GCC warnings about the
> +     * variables being used uninitialised when in fact they always are.
> +     */
> +    pulse.num_pulse = 0;
> +    pulse.start     = 0;
> +
> +    global_gain = get_bits(gb, 8);
> +
> +    if (!common_window && !scale_flag) {
> +        if (decode_ics_info(ac, ics, gb, 0) < 0)
> +            return -1;
> +    }
> +
> +    if (decode_band_types(ac, sce->band_type, sce->band_type_run_end, gb, ics) < 0)
> +        return -1;
> +    if (decode_scalefactors(ac, sce->sf, gb, sce->mixing_gain, global_gain, ics, sce->band_type, sce->band_type_run_end) < 0)
> +        return -1;
> +
> +    pulse_present = 0;
> +    if (!scale_flag) {
> +        if ((pulse_present = get_bits1(gb))) {
> +            if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
> +                av_log(ac->avccontext, AV_LOG_ERROR, "Pulse tool not allowed in eight short sequence.\n");
> +                return -1;
> +            }
> +            decode_pulses(&pulse, gb);
> +        }
> +        if ((tns->present = get_bits1(gb)) && decode_tns(ac, tns, gb, ics))
> +            return -1;
> +        if (get_bits1(gb)) {
> +            av_log(ac->avccontext, AV_LOG_ERROR, "SSR not supported.\n");
> +            return -1;
> +        }
> +    }
> +
> +    if (decode_spectrum(ac, icoeffs, gb, ics, sce->band_type) < 0)
> +        return -1;
> +    if (pulse_present)
> +        add_pulses(icoeffs, &pulse, ics);
> +    dequant(ac, out, icoeffs, sce->sf, ics, sce->band_type);
> +    return 0;
> +}

ok


> +
> +/**
> + * Mid/Side stereo decoding; reference: 4.6.8.1.3.
> + */
> +static void apply_mid_side_stereo(ChannelElement * cpe) {
> +    const IndividualChannelStream * ics = &cpe->ch[0].ics;
> +    float *ch0 = cpe->ch[0].coeffs;
> +    float *ch1 = cpe->ch[1].coeffs;
> +    int g, i, k, gp, idx = 0;
> +    const uint16_t * offsets = ics->swb_offset;
> +    for (g = 0; g < ics->num_window_groups; g++) {
> +        for (i = 0; i < ics->max_sfb; i++, idx++) {
> +            if (cpe->ms_mask[idx] &&
> +                cpe->ch[0].band_type[idx] < NOISE_BT && cpe->ch[1].band_type[idx] < NOISE_BT) {
> +                for (gp = 0; gp < ics->group_len[g]; gp++) {
> +                    for (k = offsets[i]; k < offsets[i+1]; k++) {
> +                        float tmp = ch0[gp*128 + k] - ch1[gp*128 + k];
> +                        ch0[gp*128 + k] += ch1[gp*128 + k];
> +                        ch1[gp*128 + k] = tmp;
> +                    }
> +                }
> +            }
> +        }
> +        ch0 += ics->group_len[g]*128;
> +        ch1 += ics->group_len[g]*128;

it might be better to add 128 just outside the innermost loop to avoid
the "gp*128 +" inside, this also applies to several other functions!

besides dequant() uses group instead of gp, this is very minor but inconsisant


[...]
> +/**
> + * Decode a channel_pair_element; reference: table 4.4.
> + *
> + * @param   elem_id Identifies the instance of a syntax element.
> + *
> + * @return  Returns error status. 0 - OK, !0 - error
> + */
> +static int decode_cpe(AACContext * ac, GetBitContext * gb, int elem_id) {
> +    int i, ret, common_window, ms_present = 0;
> +    ChannelElement * cpe;
> +
> +    cpe = ac->che[TYPE_CPE][elem_id];
> +    common_window = get_bits1(gb);
> +    if (common_window) {
> +        if (decode_ics_info(ac, &cpe->ch[0].ics, gb, 1))
> +            return -1;
> +        i = cpe->ch[1].ics.use_kb_window[0];
> +        cpe->ch[1].ics = cpe->ch[0].ics;
> +        cpe->ch[1].ics.use_kb_window[1] = i;
> +        ms_present = get_bits(gb, 2);
> +        if(ms_present == 3) {
> +            av_log(ac->avccontext, AV_LOG_ERROR, "ms_present = 3 is reserved.\n");
> +            return -1;
> +        } else if(ms_present)
> +            decode_mid_side_stereo(cpe, gb, ms_present);
> +    }
> +    if ((ret = decode_ics(ac, &cpe->ch[0], gb, common_window, 0)))
> +        return ret;
> +    if ((ret = decode_ics(ac, &cpe->ch[1], gb, common_window, 0)))
> +        return ret;
> +
> +    if (common_window && ms_present)
> +        apply_mid_side_stereo(cpe);
> +
> +    if (cpe->ch[1].ics.intensity_present)
> +        apply_intensity_stereo(cpe, ms_present);
> +    return 0;
> +}

ok


> +
> +/**
> + * Decode coupling_channel_element; reference: table 4.8.
> + *
> + * @param   elem_id Identifies the instance of a syntax element.
> + *
> + * @return  Returns error status. 0 - OK, !0 - error
> + */
> +static int decode_cce(AACContext * ac, GetBitContext * gb, int elem_id) {
> +    int num_gain = 0;
> +    int c, g, sfb, ret, idx = 0;
> +    int is_indep_coup, domain, sign;
> +    float scale;
> +    SingleChannelElement * sce;
> +    ChannelCoupling * coup;
> +
> +    sce = &ac->che[TYPE_CCE][elem_id]->ch[0];
> +    sce->mixing_gain = 1.0;
> +
> +    coup = &ac->che[TYPE_CCE][elem_id]->coup;
> +
> +    is_indep_coup = get_bits1(gb);
> +    coup->num_coupled = get_bits(gb, 3);
> +    for (c = 0; c <= coup->num_coupled; c++) {
> +        num_gain++;

> +        coup->is_cpe[c] = get_bits1(gb);
> +        coup->id_select[c] = get_bits(gb, 4);
> +        if (coup->is_cpe[c]) {
> +            coup->ch_select[c] = get_bits(gb, 2);
> +            if (coup->ch_select[c] == 3)
> +                num_gain++;
> +        }

i thought about this again and i think the following is overall cleaner:

coup->type[c] = get_bits1(gb) ? TYPE_CPE : TYPE_SCE;
coup->id_select[c] = get_bits(gb, 4);
if (coup->type[c] == TYPE_CPE) {
    coup->ch_select[c] = get_bits(gb, 2);
    if (coup->ch_select[c] == 3)
        num_gain++;
} else
    coup->ch_select[c] = 1;



> +    }
> +    domain = get_bits1(gb);
> +
> +    if (is_indep_coup) {
> +        coup->coupling_point = AFTER_IMDCT;
> +    } else if(domain) {
> +        coup->coupling_point = BETWEEN_TNS_AND_IMDCT;
> +    } else
> +        coup->coupling_point = BEFORE_TNS;

:/ i thought the bits were at least stored together, what morons designed
this!?

coup->coupling_point= get_bits1(gb);
...
coup->coupling_point+= 2*get_bits1(gb);

still is a possibility though that is cleaner
btw, what is the 4th possibility for?


> +
> +    sign = get_bits(gb, 1);
> +    scale = pow(2., pow(2., get_bits(gb, 2) - 3));
> +
> +    if ((ret = decode_ics(ac, sce, gb, 0, 0)))
> +        return ret;
> +
> +    for (c = 0; c < num_gain; c++) {
> +        int cge = 1;
> +        int gain = 0;
> +        float gain_cache = 1.;
> +        if (c) {
> +            cge = coup->coupling_point == AFTER_IMDCT ? 1 : get_bits1(gb);
> +            gain = cge ? get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60: 0;
> +            gain_cache = pow(scale, gain);
> +        }
> +        for (g = 0; g < sce->ics.num_window_groups; g++)
> +            for (sfb = 0; sfb < sce->ics.max_sfb; sfb++, idx++)
> +                if (sce->band_type[idx] == ZERO_BT) {
> +                    coup->gain[c][idx] = 0;
> +                } else {
> +                    if (cge) {
> +                        coup->gain[c][idx] = gain_cache;
> +                    } else {
> +                        int s, t = get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60;
> +                        if (sign) {
> +                            s = 1 - 2 * (t & 0x1);
> +                            t >>= 1;
> +                        } else
> +                            s = 1;
> +                        gain += t;
> +                        coup->gain[c][idx] = pow(scale, gain) * s;

I think t==0 should be handled as a special case to skip the pow()
maybe something like:

if(!cge){
    t=get_vlc2() ...
    if(t){
        ...
        gain += t;
        gain_cache= pow(scale, gain) * s;
    }
}
coup->gain[c][idx] = gain_cache;

also maybe the == ZERO_BT check is useless, i think the code that applies
the coupling checks for it before using the values.


> +                    }
> +                }
> +    }
> +    return 0;
> +}
> +


> +/**
> + * Decode Spectral Band Replication extension data; reference: table 4.55.
> + *
>   * @param   crc flag indicating the presence of CRC checksum
>   * @param   cnt length of TYPE_FIL syntactic element in bytes
> + *
>   * @return  Returns number of bytes consumed from the TYPE_FIL element.
>   */
>  static int decode_sbr_extension(AACContext * ac, GetBitContext * gb, int crc, int cnt) {

ok


> @@ -343,6 +1079,86 @@
>      return cnt;
>  }
>  
> +/**
> + * Parse whether channels are to be excluded from Dynamic Range Compression; reference: table 4.53.
> + *
> + * @return  Returns number of bytes consumed.
> + */
> +static int decode_drc_channel_exclusions(DynamicRangeControl *che_drc, GetBitContext * gb) {
> +    int i;
> +    int n = 0;
> +    int num_excl_chan = 0;
> +
> +    do {
> +        for (i = 0; i < 7; i++)
> +            che_drc->exclude_mask[num_excl_chan + i] = get_bits1(gb);
> +        n++;
> +        num_excl_chan += 7;
> +    } while (num_excl_chan < MAX_CHANNELS - 7 && get_bits1(gb));
> +
> +    return n;
> +}

do {
    for (i = 0; i < 7; i++)
        che_drc->exclude_mask[num_excl_chan++] = get_bits1(gb);
} while (num_excl_chan < MAX_CHANNELS - 7 && get_bits1(gb));

return num_excl_chan/7;


> +
> +/**
> + * Decode dynamic range information; reference: table 4.52.
> + *
> + * @param   cnt length of TYPE_FIL syntactic element in bytes
> + *
> + * @return  Returns number of bytes consumed.
> + */
> +static int decode_dynamic_range(DynamicRangeControl *che_drc, GetBitContext * gb, int cnt) {
> +    int n = 1;
> +    int drc_num_bands = 1;
> +    int i;
> +
> +    /* pce_tag_present? */
> +    if(get_bits1(gb)) {
> +        che_drc->pce_instance_tag  = get_bits(gb, 4);
> +        skip_bits(gb, 4); // tag_reserved_bits
> +        n++;
> +    }
> +
> +    /* excluded_chns_present? */
> +    if(get_bits1(gb)) {
> +        n += decode_drc_channel_exclusions(che_drc, gb);
> +    }
> +
> +    /* drc_bands_present? */
> +    if (get_bits1(gb)) {
> +        che_drc->band_incr            = get_bits(gb, 4);
> +        che_drc->interpolation_scheme = get_bits(gb, 4);
> +        n++;
> +        drc_num_bands += che_drc->band_incr;
> +        for (i = 0; i < drc_num_bands; i++) {
> +            che_drc->band_top[i] = get_bits(gb, 8);
> +            n++;
> +        }
> +    }
> +
> +    /* prog_ref_level_present? */
> +    if (get_bits1(gb)) {
> +        che_drc->prog_ref_level = get_bits(gb, 7);
> +        skip_bits1(gb); // prog_ref_level_reserved_bits
> +        n++;
> +    }
> +
> +    for (i = 0; i < drc_num_bands; i++) {
> +        che_drc->dyn_rng_sgn[i] = get_bits1(gb);
> +        che_drc->dyn_rng_ctl[i] = get_bits(gb, 7);
> +        n++;
> +    }
> +
> +    return n;
> +}

return get_bits_count() /8 might (or might not) be simpler.
either way, function looks ok


> +
> +/**
> + * Decode extension data (incomplete); reference: table 4.51.
> + *
> + * @param   cnt length of TYPE_FIL syntactic element in bytes
> + *
> + * @return Returns number of bytes consumed
> + */
> +static int decode_extension_payload(AACContext * ac, GetBitContext * gb, int cnt) {
>      int crc_flag = 0;
>      int res = cnt;
>      switch (get_bits(gb, 4)) { // extension type

ok


[...]
> +/**
> + * Conduct IMDCT and windowing.
> + */
> +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 * lwindow      = ics->use_kb_window[0] ? ff_aac_kbd_long_1024 : ff_aac_sine_long_1024;
> +    const float * swindow      = ics->use_kb_window[0] ? ff_aac_kbd_short_128 : ff_aac_sine_short_128;
> +    const float * lwindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_long_1024 : ff_aac_sine_long_1024;
> +    const float * swindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_short_128 : ff_aac_sine_short_128;
> +    float * buf = ac->buf_mdct;
> +    int i;
> +

ok


> +    if (ics->window_sequence[0] != EIGHT_SHORT_SEQUENCE) {
> +        ff_imdct_calc(&ac->mdct, buf, in, out); // Out can be abused, for now, as a temp buffer.
> +        if (ics->window_sequence[0] != LONG_STOP_SEQUENCE) {
> +            ac->dsp.vector_fmul_add_add(out, buf, lwindow_prev, saved, ac->add_bias, 1024, 1);
> +        } else {
> +            for (i = 0;   i < 448;  i++)   out[i] =          saved[i] + ac->add_bias;
> +            ac->dsp.vector_fmul_add_add(out + 448, buf + 448, swindow_prev, saved + 448, ac->add_bias, 128, 1);
> +            for (i = 576; i < 1024; i++)   out[i] = buf[i] + saved[i] + ac->add_bias;
> +        }
> +        if (ics->window_sequence[0] != LONG_START_SEQUENCE) {

instead of 
if(!X)
else

i think
if(X)
else

would be more readable



> +            ac->dsp.vector_fmul_reverse(saved, buf + 1024, lwindow, 1024);
> +        } else {
> +            memcpy(saved, buf + 1024, 448 * sizeof(float));
> +            ac->dsp.vector_fmul_reverse(saved + 448, buf + 1024 + 448, swindow, 128);
> +            memset(saved + 576, 0, 448 * sizeof(float));
> +        }
> +    } else {
> +        if (ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE)
> +            av_log(ac->avccontext, AV_LOG_WARNING,
> +                   "Transition from an ONLY_LONG or LONG_STOP to an EIGHT_SHORT sequence detected. "
> +                   "If you heard an audible artifact, please submit the sample to the FFmpeg developers.\n");
> +        for (i = 0; i < 2048; i += 256) {
> +            ff_imdct_calc(&ac->mdct_small, buf + i, in + i/2, out);
> +            ac->dsp.vector_fmul_reverse(ac->revers + i/2, buf + i + 128, swindow, 128);
> +        }
> +        for (i = 0; i < 448; i++)   out[i] = saved[i] + ac->add_bias;
> +
> +        ac->dsp.vector_fmul_add_add(out + 448 + 0*128, buf + 0*128, swindow_prev, saved + 448 ,       ac->add_bias, 128, 1);
> +        ac->dsp.vector_fmul_add_add(out + 448 + 1*128, buf + 2*128, swindow,      ac->revers + 0*128, ac->add_bias, 128, 1);
> +        ac->dsp.vector_fmul_add_add(out + 448 + 2*128, buf + 4*128, swindow,      ac->revers + 1*128, ac->add_bias, 128, 1);
> +        ac->dsp.vector_fmul_add_add(out + 448 + 3*128, buf + 6*128, swindow,      ac->revers + 2*128, ac->add_bias, 128, 1);
> +        ac->dsp.vector_fmul_add_add(out + 448 + 4*128, buf + 8*128, swindow,      ac->revers + 3*128, ac->add_bias,  64, 1);
> +
> +#if 0
> +        vector_fmul_add_add_add(&ac->dsp, out + 448 + 1*128, buf + 2*128, swindow,      saved + 448 + 1*128, ac->revers + 0*128, ac->add_bias, 128);
> +        vector_fmul_add_add_add(&ac->dsp, out + 448 + 2*128, buf + 4*128, swindow,      saved + 448 + 2*128, ac->revers + 1*128, ac->add_bias, 128);
> +        vector_fmul_add_add_add(&ac->dsp, out + 448 + 3*128, buf + 6*128, swindow,      saved + 448 + 3*128, ac->revers + 2*128, ac->add_bias, 128);
> +        vector_fmul_add_add_add(&ac->dsp, out + 448 + 4*128, buf + 8*128, swindow,      saved + 448 + 4*128, ac->revers + 3*128, ac->add_bias, 64);
> +#endif
> +
> +        ac->dsp.vector_fmul_add_add(saved,       buf + 1024 + 64,    swindow + 64, ac->revers + 3*128+64,  0, 64, 1);
> +        ac->dsp.vector_fmul_add_add(saved + 64,  buf + 1024 + 2*128, swindow,      ac->revers + 4*128,     0, 128, 1);
> +        ac->dsp.vector_fmul_add_add(saved + 192, buf + 1024 + 4*128, swindow,      ac->revers + 5*128,     0, 128, 1);
> +        ac->dsp.vector_fmul_add_add(saved + 320, buf + 1024 + 6*128, swindow,      ac->revers + 6*128,     0, 128, 1);
> +        memcpy(                     saved + 448, ac->revers + 7*128, 128 * sizeof(float));

> +        memset(                     saved + 576, 0,                  448 * sizeof(float));

is that really needed? I mean if the data isnt used it wouldnt be but if its
used then windowing and adding zeros seems rather like wasted cpu time.
also this applies to all the memset in thus function.


> +    }
> +}
> +
> +/**
>   * Apply dependent channel coupling (applied before IMDCT).
>   *
>   * @param   index   index into coupling gain array
> @@ -409,6 +1354,180 @@
>          sce->ret[i] += gain * (cc->ch[0].ret[i] - ac->add_bias);
>  }
>  
> +/**
> + * channel coupling transformation interface
> + *
> + * @param   index   index into coupling gain array
> + * @param   apply_coupling_method   pointer to (in)dependent coupling function
> + */
> +static void apply_channel_coupling(AACContext * ac, ChannelElement * cc,
> +        void (*apply_coupling_method)(AACContext * ac, SingleChannelElement * sce, ChannelElement * cc, int index))
> +{
> +    int c;
> +    int index = 0;
> +    ChannelCoupling * coup = &cc->coup;
> +    for (c = 0; c <= coup->num_coupled; c++) {

> +        if (     !coup->is_cpe[c] && ac->che[TYPE_SCE][coup->id_select[c]]) {
> +            apply_coupling_method(ac, &ac->che[TYPE_SCE][coup->id_select[c]]->ch[0], cc, index++);
> +        } else if(coup->is_cpe[c] && ac->che[TYPE_CPE][coup->id_select[c]]) {
> +            if (coup->ch_select[c] != 2) {
> +                apply_coupling_method(ac, &ac->che[TYPE_CPE][coup->id_select[c]]->ch[0], cc, index);
> +                if (coup->ch_select[c] != 0)
> +                    index++;
> +            }
> +            if (coup->ch_select[c] != 1)
> +                apply_coupling_method(ac, &ac->che[TYPE_CPE][coup->id_select[c]]->ch[1], cc, index++);

if (ac->che[coup->type][coup->id_select[c]]) {
    if (coup->ch_select[c] != 2) {
        apply_coupling_method(ac, &ac->che[coup->type][coup->id_select[c]]->ch[0], cc, index);
        if (coup->ch_select[c] != 0)
            index++;
    }
    if (coup->ch_select[c] != 1)
        apply_coupling_method(ac, &ac->che[coup->type][coup->id_select[c]]->ch[1], cc, index++);



> +        } else {
> +            av_log(ac->avccontext, AV_LOG_ERROR,
> +                   "coupling target %sE[%d] not available\n",
> +                   coup->is_cpe[c] ? "CP" : "SC", coup->id_select[c]);
> +            break;
> +        }
> +    }
> +}
> +

> +/**
> + * Convert spectral data to float samples, applying all supported tools as appropriate.
> + */
> +static void spectral_to_sample(AACContext * ac) {
> +    int i, j;
> +    for (i = 0; i < MAX_ELEM_ID; i++) {
> +        for(j = 0; j < 4; j++) {
> +            ChannelElement *che = ac->che[j][i];
> +            if(che) {
> +                if(j == TYPE_CCE && che->coup.coupling_point == BEFORE_TNS)

please, s/j/type/


[...]
> +/**
> + * Conduct float to int16 conversion.
> + *
> + * @param   data        pointer to output data
> + * @param   data_size   output data size in bytes
> + *
> + * @return  Returns error status. 0 - OK, !0 - error
> + */
> +static int convert_to_int16(AVCodecContext * avccontext, uint16_t * data, int * data_size) {
> +    AACContext * ac = avccontext->priv_data;
> +    int i;
> +
> +    if (!ac->is_saved) {
> +        ac->is_saved = 1;
> +        *data_size = 0;
> +        return 0;
> +    }
> +
> +    i = 1024 * avccontext->channels * sizeof(int16_t);
> +    if(*data_size < i) {
> +        av_log(avccontext, AV_LOG_ERROR,
> +               "Output buffer too small (%d) or trying to output too many samples (%d) for this frame.\n",
> +               *data_size, i);
> +        return -1;
> +    }
> +    *data_size = i;
> +
> +    ac->dsp.float_to_int16_interleave(data, (const float **)ac->output_data, 1024, avccontext->channels);
> +
> +    return 0;
> +}

I wonder if it would be cleaner if this where just inlined intead of a
seperate function, either way its ok


> +
> +static int aac_decode_frame(AVCodecContext * avccontext, void * data, int * data_size, const uint8_t * buf, int buf_size) {
> +    AACContext * ac = avccontext->priv_data;
> +    GetBitContext gb;
> +    enum RawDataBlockType elem_type;
> +    int err, elem_id;
> +
> +    init_get_bits(&gb, buf, buf_size*8);
> +
> +    // parse
> +    while ((elem_type = get_bits(&gb, 3)) != TYPE_END) {
> +        elem_id = get_bits(&gb, 4);
> +        err = -1;
> +        switch (elem_type) {
> +
> +        case TYPE_SCE:
> +            if(!ac->che[TYPE_SCE][elem_id]) {
> +                if(elem_id == 1 && ac->che[TYPE_LFE][0]) {
> +                    /* Some streams incorrectly code 5.1 audio as SCE[0] CPE[0] CPE[1] SCE[1]
> +                       instead of SCE[0] CPE[0] CPE[0] LFE[0].
> +                       If we seem to have encountered such a stream,
> +                       transfer the LFE[0] element to SCE[1] */
> +                    ac->che[TYPE_SCE][elem_id] = ac->che[TYPE_LFE][0];
> +                    ac->che[TYPE_LFE][0] = NULL;
> +                } else
> +                    break;
> +            }
> +            err = decode_ics(ac, &ac->che[TYPE_SCE][elem_id]->ch[0], &gb, 0, 0);
> +            break;
> +
> +        case TYPE_CPE:
> +            if (ac->che[TYPE_CPE][elem_id])
> +                err = decode_cpe(ac, &gb, elem_id);
> +            break;
> +
> +        case TYPE_FIL:
> +            if (elem_id == 15)
> +                elem_id += get_bits(&gb, 8) - 1;
> +            while (elem_id > 0)
> +                elem_id -= decode_extension_payload(ac, &gb, elem_id);
> +            err = 0; /* FIXME */
> +            break;
> +
> +        case TYPE_PCE:
> +        {
> +            enum ChannelPosition new_che_pos[4][MAX_ELEM_ID];
> +            memset(new_che_pos, 0, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0]));
> +            if((err = decode_pce(ac, new_che_pos, &gb)))
> +                break;
> +            err = output_configure(ac, ac->che_pos, new_che_pos);
> +            break;
> +        }
> +
> +        case TYPE_DSE:
> +            skip_data_stream_element(&gb);
> +            err = 0;
> +            break;
> +
> +        case TYPE_CCE:
> +            if (ac->che[TYPE_CCE][elem_id])
> +                err = decode_cce(ac, &gb, elem_id);
> +            break;
> +
> +        case TYPE_LFE:
> +            if (ac->che[TYPE_LFE][elem_id])
> +                err = decode_ics(ac, &ac->che[TYPE_LFE][elem_id]->ch[0], &gb, 0, 0);
> +            break;

these checks could be factorized out
if(elem_type < C && !ac->che[elem_type][elem_id])
    return -1;


[...]
> Index: libavcodec/aac.h
> ===================================================================
> --- libavcodec/aac.h	(revision 14674)
> +++ libavcodec/aac.h	(working copy)
> @@ -43,7 +43,10 @@
>          size);
>  
>  #define MAX_CHANNELS 64
> +#define MAX_ELEM_ID 16

ok


[...]

> @@ -76,6 +79,17 @@
>      AOT_SSC,                   ///< N                       SinuSoidal Coding
>  };
>  
> +enum RawDataBlockType {
> +    TYPE_SCE,
> +    TYPE_CPE,
> +    TYPE_CCE,
> +    TYPE_LFE,
> +    TYPE_DSE,
> +    TYPE_PCE,
> +    TYPE_FIL,
> +    TYPE_END,
> +};
> +
>  enum ExtensionPayloadID {
>      EXT_FILL,
>      EXT_FILL_DATA,

ok


> @@ -111,7 +125,61 @@
>      AAC_CHANNEL_CC    = 5,
>  };
>  
> +/**
> + * The point during decoding at which channel coupling is applied.
> + */
> +enum CouplingPoint {
> +    BEFORE_TNS,
> +    BETWEEN_TNS_AND_IMDCT,
> +    AFTER_IMDCT,
> +};
> +
> +/**
> + * Individual Channel Stream
> + */
>  typedef struct {

ok


[...]

> +/**
> + * Dynamic Range Control - decoded from the bitstream but not processed further.
> + */
> +typedef struct {
> +    int pce_instance_tag;                           ///< Indicates with which program the DRC info is associated.
> +    int dyn_rng_sgn[17];                            ///< DRC sign information; 0 - positive, 1 - negative
> +    int dyn_rng_ctl[17];                            ///< DRC magnitude information
> +    int exclude_mask[MAX_CHANNELS];                 ///< Channels to be excluded from DRC processing.
> +    int band_incr;                                  ///< Number of DRC bands greater than 1 having DRC info.
> +    int interpolation_scheme;                       ///< Indicates the interpolation scheme used in the SBR QMF domain.
> +    int band_top[17];                               ///< Indicates the top of the i-th DRC band in units of 4 spectral lines.
> +    int prog_ref_level;                             /**< A reference level for the long-term program audio level for all
> +                                                     *   channels combined.
> +                                                     */
> +} DynamicRangeControl;
> +
> +typedef struct {
>      int num_pulse;
>      int start;
>      int offset[4];

ok


[...]
>  /**
> + * Single Channel Element - used for both SCE and LFE elements.
> + */
> +typedef struct {

> +    float mixing_gain;                        /**< Channel gain (not used by AAC bitstream).
> +                                               *   Note that this is applied before joint stereo decoding.
> +                                               *   Thus, when used inside CPE elements, both channels must have equal gain.
> +                                               */

This variable is always 1 thus unneeded

[...]

> @@ -134,17 +242,32 @@
>      int is_saved;                 ///< Set if elements have stored overlap from previous frame.
>      DynamicRangeControl che_drc;
>  
> +    /**
> +     * @defgroup elements
> +     * @{
> +     */
>      enum ChannelPosition che_pos[4][MAX_ELEM_ID]; /**< channel element channel mapping with the
>                                                     *   first index as the first 4 raw data block types
>                                                     */
> +    ChannelElement * che[4][MAX_ELEM_ID];
> +    /** @} */
>  
>      /**

ok

[...]
> +    /**
>       * @defgroup tables   Computed / set up during initialization.
>       * @{
>       */
>      MDCTContext mdct;
>      MDCTContext mdct_small;
>      DSPContext dsp;
> +    int32_t random_state;
>      /** @} */
>  
>      /**

ok


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

Breaking DRM is a little like attempting to break through a door even
though the window is wide open and the only thing in the house is a bunch
of things you dont want and which you would get tomorrow for free anyway
-------------- 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/20080809/e65bb1ef/attachment.pgp>



More information about the ffmpeg-devel mailing list