[FFmpeg-devel] [PATCH] ALS decoder

Michael Niedermayer michaelni
Sat Nov 7 01:22:55 CET 2009


On Wed, Nov 04, 2009 at 05:40:27PM +0100, Thilo Borgmann wrote:
> Revision 25 attached.
[...]
> +/** Reformat block sizes from log2 format to direct form. Also assure that the
> + *  block sizes of the last frame correspond to the actual number of samples.
> + */
> +static void reconstruct_block_sizes(ALSDecContext *ctx, uint32_t *div_blocks)

does it make sense to have this as seperate function? its called just once

[...]
> +
> +/** Reads the block data for a non-constant block
> + */
> +static int read_var_block(ALSDecContext *ctx, unsigned int ra_block,
> +                          int32_t *raw_samples, unsigned int block_length,
> +                          unsigned int *js_blocks, int32_t *raw_other,
> +                          unsigned int *shift_lsbs)
> +{
> +    ALSSpecificConfig *sconf = &ctx->sconf;
> +    AVCodecContext *avctx    = ctx->avctx;
> +    GetBitContext *gb        = &ctx->gb;
> +    unsigned int k;
> +    unsigned int s[8];
> +    unsigned int sub_blocks, log2_sub_blocks, sb_length;
> +    unsigned int opt_order  = 1;
> +    int32_t      *quant_cof = ctx->quant_cof;
> +    int32_t      *lpc_cof   = ctx->lpc_cof;
> +    unsigned int start      = 0;
> +    int          smp        = 0;
> +    int          sb, store_prev_samples;
> +    int64_t      y;
> +
> +    *js_blocks  = get_bits1(gb);
> +
> +    // determine the number of subblocks for entropy decoding
> +    if (!sconf->bgmc && !sconf->sb_part) {
> +        log2_sub_blocks = 0;
> +    } else {
> +        if (sconf->bgmc && sconf->sb_part)
> +            log2_sub_blocks = get_bits(gb, 2);
> +        else
> +            log2_sub_blocks = 2 * get_bits1(gb);
> +    }
> +
> +    sub_blocks = 1 << log2_sub_blocks;
> +
> +    // do not continue in case of a damaged stream since
> +    // block_length must be evenly divisible by sub_blocks
> +    if (block_length & (sub_blocks - 1)) {
> +        av_log(avctx, AV_LOG_WARNING,
> +               "Block length is not evenly divisible by the number of subblocks.\n");
> +        return -1;
> +    }
> +
> +    sb_length = block_length >> log2_sub_blocks;
> +
> +
> +    if (sconf->bgmc) {
> +        // TODO: BGMC mode
> +    } else {
> +        s[0] = get_bits(gb, 4 + (sconf->resolution > 1));
> +        for (k = 1; k < sub_blocks; k++)
> +            s[k] = s[k - 1] + decode_rice(gb, 0);
> +    }
> +
> +    if (get_bits1(gb))
> +        *shift_lsbs = get_bits(gb, 4) + 1;
> +
> +    store_prev_samples = (*js_blocks && raw_other) || *shift_lsbs;
> +
> +
> +    if (!sconf->rlslms) {
> +        if (sconf->adapt_order) {
> +            int opt_order_length = av_ceil_log2(av_clip((block_length >> 3) - 1,
> +                                                2, sconf->max_order + 1));
> +            opt_order            = get_bits(gb, opt_order_length);
> +        } else {
> +            opt_order = sconf->max_order;
> +        }
> +
> +        if (opt_order) {
> +            int add_base;
> +
> +            if (sconf->coef_table == 3) {
> +                add_base = 0x7F;
> +
> +                // read coefficient 0
> +                quant_cof[0] = 32 * parcor_scaled_values[get_bits(gb, 7)];
> +
> +                // read coefficient 1
> +                if (opt_order > 1)
> +                    quant_cof[1] = -32 * parcor_scaled_values[get_bits(gb, 7)];
> +
> +                // read coefficients 2 to opt_order
> +                for (k = 2; k < opt_order; k++)
> +                    quant_cof[k] = get_bits(gb, 7);
> +            } else {
> +                int k_max;
> +                add_base = 1;
> +
> +                // read coefficient 0 to 19
> +                k_max = FFMIN(opt_order, 20);
> +                for (k = 0; k < k_max; k++) {
> +                    int rice_param = parcor_rice_table[sconf->coef_table][k][1];
> +                    int offset     = parcor_rice_table[sconf->coef_table][k][0];
> +                    quant_cof[k] = decode_rice(gb, rice_param) + offset;
> +                }
> +
> +                // read coefficients 20 to 126
> +                k_max = FFMIN(opt_order, 127);
> +                for (; k < k_max; k++)
> +                    quant_cof[k] = decode_rice(gb, 2) + (k & 1);
> +
> +                // read coefficients 127 to opt_order
> +                for (; k < opt_order; k++)
> +                    quant_cof[k] = decode_rice(gb, 1);
> +
> +                quant_cof[0] = 32 * parcor_scaled_values[quant_cof[0] + 64];
> +
> +                if (opt_order > 1)
> +                    quant_cof[1] = -32 * parcor_scaled_values[quant_cof[1] + 64];

> +            }
> +
> +        for (k = 2; k < opt_order; k++)
> +            quant_cof[k] = (quant_cof[k] << 14) + (add_base << 13);
> +        }

indention ...



[...]
> +/** Decodes blocks dependently.
> + */
> +static int decode_blocks(ALSDecContext *ctx, unsigned int ra_frame,
> +                         unsigned int c, const unsigned int *div_blocks,
> +                         unsigned int *js_blocks)
> +{
> +    ALSSpecificConfig *sconf = &ctx->sconf;
> +    unsigned int offset = 0;
> +    int32_t *raw_samples_R;
> +    int32_t *raw_samples_L;
> +    unsigned int b;
> +

> +    // decode all blocks
> +    for (b = 0; b < ctx->num_blocks; b++) {
> +        unsigned int s;
> +        raw_samples_L = ctx->raw_samples[c    ] + offset;
> +        raw_samples_R = ctx->raw_samples[c + 1] + offset;
> +        if (read_block_data(ctx, ra_frame, raw_samples_L, div_blocks[b],
> +                            &js_blocks[0], raw_samples_R) ||
> +            read_block_data(ctx, ra_frame, raw_samples_R, div_blocks[b],
> +                            &js_blocks[1], raw_samples_L)) {

Is it intended that the second function call will use raw_samples_L
from the first call while the first call will not use raw_samples_R
from the second call but rather what was in that array before?


[...]
> +
> +/** Reads the frame data.
> + */
> +static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame)
> +{
> +    ALSSpecificConfig *sconf = &ctx->sconf;
> +    AVCodecContext *avctx    = ctx->avctx;
> +    GetBitContext *gb = &ctx->gb;
> +    unsigned int div_blocks[32];                ///< block sizes.
> +    unsigned int c;
> +    unsigned int js_blocks[2];
> +
> +    uint32_t bs_info = 0;
> +
> +    // skip the size of the ra unit if present in the frame
> +    if (sconf->ra_flag == RA_FLAG_FRAMES && ra_frame)
> +        skip_bits_long(gb, 32);
> +
> +    if (sconf->mc_coding && sconf->joint_stereo) {
> +        ctx->js_switch = get_bits1(gb);
> +        align_get_bits(gb);
> +    }
> +
> +    if (!sconf->mc_coding || ctx->js_switch) {
> +        int independent_bs = !sconf->joint_stereo;
> +
> +        for (c = 0; c < avctx->channels; c++) {
> +            js_blocks[0] = 0;
> +            js_blocks[1] = 0;
> +
> +            get_block_sizes(ctx, div_blocks, &bs_info);
> +
> +            // if joint_stereo and block_switching is set, independent decoding
> +            // is signaled via the first bit of bs_info
> +            if (sconf->joint_stereo && sconf->block_switching)
> +                if (bs_info >> 31)
> +                    independent_bs = 2;
> +
> +            // if this is the last channel, it has to be decoded independently
> +            if (c == avctx->channels - 1)
> +                independent_bs = 1;
> +
> +            if (independent_bs) {
> +                if (decode_blocks_ind(ctx, ra_frame, c, div_blocks, js_blocks))
> +                    return -1;
> +
> +                independent_bs--;
> +            } else {
> +                if (decode_blocks(ctx, ra_frame, c, div_blocks, js_blocks))
> +                    return -1;
> +
> +                c++;
> +            }
> +
> +        // store carryover raw samples
> +        memmove(ctx->raw_samples[c] - sconf->max_order,
> +                ctx->raw_samples[c] - sconf->max_order + sconf->frame_length,
> +                sizeof(*ctx->raw_samples[c]) * sconf->max_order);
> +        }

the indention looks odd


[...]
> +/** Decodes an ALS frame.
> + */
> +static int decode_frame(AVCodecContext *avctx,
> +                        void *data, int *data_size,
> +                        AVPacket *avpkt)
> +{
> +    ALSDecContext *ctx       = avctx->priv_data;
> +    ALSSpecificConfig *sconf = &ctx->sconf;
> +    const uint8_t *buffer    = avpkt->data;
> +    int buffer_size          = avpkt->size;
> +    int invalid_frame, size;
> +    unsigned int c, sample, ra_frame, bytes_read, shift;
> +
> +    init_get_bits(&ctx->gb, buffer, buffer_size * 8);
> +
> +    // In the case that the distance between random access frames is set to zero
> +    // (sconf->ra_distance == 0) no frame is treated as a random access frame.
> +    // For the first frame, if prediction is used, all samples used from the
> +    // previous frame are assumed to be zero.
> +    ra_frame = sconf->ra_distance && !(ctx->frame_id % sconf->ra_distance);
> +
> +    // the last frame to decode might have a different length

> +    if (sconf->samples != 0xFFFFFFFF)// {
                                        ^^^^
?

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

I know you won't believe me, but the highest form of Human Excellence is
to question oneself and others. -- Socrates
-------------- 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/20091107/8179f272/attachment.pgp>



More information about the ffmpeg-devel mailing list