[FFmpeg-devel] [PATCH] ALS decoder

Thilo Borgmann thilo.borgmann
Mon Aug 31 01:20:57 CEST 2009


Michael Niedermayer schrieb:
> On Sun, Aug 30, 2009 at 12:03:32AM +0200, Thilo Borgmann wrote:
>> Revision 13 attached.
>>
>> Depends on ceillog2.rev3.patch.
> 
> [...]
>> +/** Reads an ALSSpecificConfig from a buffer into the output struct.
>> + */
>> +static av_cold int read_specific_config(ALSDecContext *ctx)
>> +{
>> +    GetBitContext gb;
>> +    uint64_t ht_size;
>> +    int i, config_offset, crc_enabled;
>> +    MPEG4AudioConfig m4ac;
>> +    ALSSpecificConfig *sconf = &ctx->sconf;
>> +    AVCodecContext *avctx    = ctx->avctx;
>> +    const uint8_t *buffer    = avctx->extradata;
>> +    uint32_t samples, als_id;
>> +
>> +    init_get_bits(&gb, buffer, avctx->extradata_size * 8);
>> +
>> +    config_offset = ff_mpeg4audio_get_config(&m4ac, buffer, avctx->extradata_size);
>> +
>> +    if (config_offset < 0)
>> +        return -1;
>> +
>> +    skip_bits_long(&gb, config_offset);
>> +
>> +    if (get_bits_left(&gb) < (22 << 3))
>> +        return -1;
>> +
>> +    // read the fixed items
>> +    als_id                      = get_bits_long(&gb, 32);
>> +    avctx->sample_rate          = m4ac.sample_rate;
>> +    skip_bits_long(&gb, 32); // sample rate already known
>> +    samples                     = get_bits_long(&gb, 32);
>> +    avctx->channels             = m4ac.channels;
>> +    skip_bits(&gb, 16);      // number of channels already knwon
>> +    skip_bits(&gb, 3);       // skip file_type
>> +    sconf->resolution           = get_bits(&gb, 3);
>> +    sconf->floating             = get_bits1(&gb);
>> +    skip_bits1(&gb);         // skip msb_first
>> +    sconf->frame_length         = get_bits(&gb, 16) + 1;
>> +    sconf->ra_distance          = get_bits(&gb, 8);
>> +    sconf->ra_flag              = get_bits(&gb, 2);
>> +    sconf->adapt_order          = get_bits1(&gb);
>> +    sconf->coef_table           = get_bits(&gb, 2);
>> +    sconf->long_term_prediction = get_bits1(&gb);
>> +    sconf->max_order            = get_bits(&gb, 10);
>> +    sconf->block_switching      = get_bits(&gb, 2);
>> +    sconf->bgmc                 = get_bits1(&gb);
>> +    sconf->sb_part              = get_bits1(&gb);
>> +    sconf->joint_stereo         = get_bits1(&gb);
>> +    sconf->mc_coding            = get_bits1(&gb);
>> +    sconf->chan_config          = get_bits1(&gb);
>> +    sconf->chan_sort            = get_bits1(&gb);
>> +    crc_enabled                 = get_bits1(&gb);
>> +    sconf->rlslms               = get_bits1(&gb);
>> +    skip_bits(&gb, 5);       // skip 5 reserved bits
>> +    skip_bits1(&gb);         // skip aux_data_enabled
>> +
>> +
>> +    // check for ALSSpecificConfig struct
>> +    if (als_id != MKBETAG('A','L','S','\0'))
>> +        return -1;
>> +
>> +    ctx->cur_frame_length = sconf->frame_length;
>> +
>> +    // allocate quantized parcor coefficient buffer
>> +    if (!(ctx->quant_cof = av_malloc(sizeof(*ctx->quant_cof) * sconf->max_order)) ||
>> +        !(ctx->lpc_cof   = av_malloc(sizeof(*ctx->lpc_cof)   * sconf->max_order))) {
>> +        av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
>> +        return AVERROR(ENOMEM);
>> +    }
>> +    // calculate total number of frames to decode if possible
>> +    if (samples != 0xFFFFFFFF) {
>> +        ctx->num_frames        = (samples - 1) / sconf->frame_length + 1;
>> +        ctx->last_frame_length = (samples - 1) % sconf->frame_length + 1;
>> +    } else {
>> +        ctx->num_frames        = 0;
>> +        ctx->last_frame_length = 0;
>> +    }
>> +
>> +    // read channel config
>> +    if (sconf->chan_config) {
>> +        if (get_bits_left(&gb) < 16)
>> +            return -1;
> 
> later there must be at least 64 bits, so we can add 64 to the check at the
> begin which then makes this one unneeded

I agree here...


> 
> 
>> +
>> +        sconf->chan_config_info = get_bits(&gb, 16);
>> +        // TODO: use this to set avctx->channel_layout
>> +    }
>> +
>> +
>> +    // read channel sorting
>> +    if (sconf->chan_sort && avctx->channels > 1) {
>> +        int chan_pos_bits = av_ceil_log2(avctx->channels);
>> +        int bits_needed  = avctx->channels * chan_pos_bits + 7;
> 
>> +        if (get_bits_left(&gb) < bits_needed)
>> +            return -1;
> 
> possibly same

... but here, bits_needed can easily be much bigger than 64.

Will be part of revision 14. Thanks!

-Thilo



More information about the ffmpeg-devel mailing list