[FFmpeg-devel] [PATCH] ALS decoder
Michael Niedermayer
michaelni
Fri Sep 4 20:42:06 CEST 2009
On Thu, Sep 03, 2009 at 09:44:25PM +0200, Thilo Borgmann wrote:
> Revision 16 attached.
[...]
> +#define DEBUG 0
that doesnt belong in here
[...]
> +typedef struct {
> + int resolution; ///< 000 = 8-bit; 001 = 16-bit; 010 = 24-bit; 011 = 32-bit
> + int floating; ///< 1 = IEEE 32-bit floating-point, 0 = integer
> + int frame_length; ///< frame length for each frame (last frame may differ)
> + int ra_distance; ///< distance between RA frames (in frames, 0...255)
if each frame is a RA frame that would be 1 i assume, but then 0...255
makes no sense as 0 makes no sense
[...]
> +/** 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;
whats the point of that instead of using avctx->extradata directly?
extradata_size is also used directly
[...]
> +/** 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, 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 sb, smp;
> + int64_t y;
> +
> + *js_blocks = get_bits1(gb);
> +
> + // determine the number of sub blocks for entropy decoding
> + if (!sconf->bgmc && !sconf->sb_part)
> + sub_blocks = 1;
> + else if (sconf->bgmc && sconf->sb_part)
> + sub_blocks = 1 << get_bits(gb, 2);
> + else
> + sub_blocks = 1 << (2 * get_bits1(gb));
> +
> + // do not continue in case of a damaged stream since
> + // block_length must be evenly divisible by sub_blocks
> + if (block_length % sub_blocks) {
> + av_log(avctx, AV_LOG_WARNING,
> + "Block length is not evenly divisible by the number of sub blocks.\n");
> + return -1;
> + }
> +
> + sb_length = block_length / sub_blocks;
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;
if (block_length & (sub_blocks-1)) {
av_log(avctx, AV_LOG_WARNING,
"Block length %d is not evenly divisible by the number of sub blocks %d.\n", block_length, sub_blocks);
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;
> +
> +
> + if (!sconf->rlslms) {
> + if (sconf->adapt_order) {
> + int opt_order_length = FFMAX(av_ceil_log2((block_length >> 3) - 1), 1);
> + opt_order_length = FFMIN(av_ceil_log2(sconf->max_order+1), opt_order_length);
this can be calculated as
av_ceil_log2(av_clip(...))
which should be simpler and faster
> + 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] = parcor_scaled_values[get_bits(gb, 7)];
> +
> + // read coefficient 1
> + quant_cof[1] = -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] = parcor_scaled_values[quant_cof[0] + 64];
> + quant_cof[1] = -parcor_scaled_values[quant_cof[1] + 64];
> + }
> +
> + for (k = 2; k < opt_order; k++)
> + quant_cof[k] = (quant_cof[k] << 14) + (add_base << 13);
> + }
> + }
> +
> + // TODO: LTP mode
> +
> + // read first value and residuals in case of a random access block
> + if (ra_block) {
> + if (opt_order)
> + raw_samples[0] = decode_rice(gb, avctx->bits_per_raw_sample - 4);
> + if (opt_order > 1)
> + raw_samples[1] = decode_rice(gb, s[0] + 3);
> + if (opt_order > 2)
> + raw_samples[2] = decode_rice(gb, s[0] + 1);
> +
> + start = FFMIN(opt_order, 3);
> + }
> +
> + // read all residuals
> + if (sconf->bgmc) {
> + // TODO: BGMC mode
> + } else {
> + int32_t *current_res = raw_samples + start;
> +
> + for (sb = 0; sb < sub_blocks; sb++, start = 0)
> + for (; start < sb_length; start++)
> + *current_res++ = decode_rice(gb, s[sb]);
> + }
> +
> + // reconstruct all samples from residuals
> + if (ra_block) {
> + unsigned int progressive = FFMIN(block_length, opt_order);
useless, you can just use opt_order instead of progressive in te following
code
> +
> + for (smp = 0; smp < block_length; smp++) {
> + unsigned int dequant = smp < progressive;
> + unsigned int max = dequant ? smp : progressive;
> +
> + y = 1 << 19;
> +
> + for (sb = 0; sb < max; sb++)
> + y += MUL64(lpc_cof[sb],raw_samples[smp - (sb + 1)]);
> +
> + raw_samples[smp] -= y >> 20;
> + if (dequant)
> + parcor_to_lpc(smp, quant_cof, lpc_cof);
> + }
this could be split in 2 loop with the 2nd being identical to the else
case below and thus factorizeable i think
> + } else {
> + int store_prev_samples = (*js_blocks && raw_other) || *shift_lsbs;
> +
> + for (k = 0; k < opt_order; k++)
> + parcor_to_lpc(k, quant_cof, lpc_cof);
> +
> + // store previous smaples in case that they have to be altered
smaples?
[...]
> +/** Computes the bytes left to decode for the current frame.
> + */
> +static void zero_remaining(unsigned int b, unsigned int b_max,
> + const unsigned int *div_blocks, int32_t *buf)
> +{
the doxy only describes half of what the function does
[...]
> +/** 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);
> + ra_frame = sconf->ra_distance && !(ctx->frame_id % sconf->ra_distance);
is it true that if ra_distance == 0 then no frame is a ra frame?
seems odd
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
The greatest way to live with honor in this world is to be what we pretend
to be. -- 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/20090904/1761cec2/attachment.pgp>
More information about the ffmpeg-devel
mailing list