[FFmpeg-soc] [soc]: r5419 - als/alsdec.c
thilo.borgmann
subversion at mplayerhq.hu
Tue Oct 20 15:00:40 CEST 2009
Author: thilo.borgmann
Date: Tue Oct 20 15:00:40 2009
New Revision: 5419
Log:
Splits reading of block data and decoding of block data.
Introduces ALSBlockData struct.
Modified:
als/alsdec.c
Modified: als/alsdec.c
==============================================================================
--- als/alsdec.c Mon Oct 19 11:39:30 2009 (r5418)
+++ als/alsdec.c Tue Oct 20 15:00:40 2009 (r5419)
@@ -88,6 +88,26 @@ typedef struct {
} ALSDecContext;
+typedef struct {
+ unsigned int block_length; ///< number of samples within the block
+ unsigned int ra_block; ///< if true, this is a random access block
+ int const_block; ///< if true, this is a constant value block
+ int32_t const_val; ///< the sample value of a constant block
+ int js_blocks; ///< true if this block contains a difference signal
+ unsigned int shift_lsbs; ///< shift of values for this block
+ unsigned int opt_order; ///< prediction order of this block
+ int store_prev_samples;///< if true, carryover samples have to be stored
+ int use_ltp; ///< if true, long-term prediction is used
+ int ltp_lag; ///< lag value for long-term prediction
+ int ltp_gain[5]; ///< gain values for ltp 5-tap filter
+ int32_t *quant_cof; ///< quantized parcor coefficients
+ int32_t *lpc_cof; ///< coefficients of the direct form prediction
+ int32_t *raw_samples; ///< decoded raw samples / residuals for this block
+ int32_t *prev_raw_samples; ///< contains unshifted raw samples from the previous block
+ int32_t *raw_other; ///< decoded raw samples of the other channel of a channel pair
+} ALSBlockData;
+
+
static av_cold void dprint_specific_config(ALSDecContext *ctx)
{
#ifdef DEBUG
@@ -424,38 +444,44 @@ static void get_block_sizes(ALSDecContex
/** Reads the block data for a constant block
*/
-static void read_const_block(ALSDecContext *ctx, int32_t *raw_samples,
- unsigned int block_length, unsigned int *js_blocks)
+static void read_const_block_data(ALSDecContext *ctx, ALSBlockData *bd)
{
ALSSpecificConfig *sconf = &ctx->sconf;
AVCodecContext *avctx = ctx->avctx;
GetBitContext *gb = &ctx->gb;
- int32_t const_val = 0;
- unsigned int const_block, k;
- const_block = get_bits1(gb); // 1 = constant value, 0 = zero block (silence)
- *js_blocks = get_bits1(gb);
+ bd->const_val = 0;
+ bd->const_block = get_bits1(gb); // 1 = constant value, 0 = zero block (silence)
+ bd->js_blocks = get_bits1(gb);
// skip 5 reserved bits
skip_bits(gb, 5);
- if (const_block) {
+ if (bd->const_block) {
unsigned int const_val_bits = sconf->floating ? 24 : avctx->bits_per_raw_sample;
- const_val = get_sbits_long(gb, const_val_bits);
+ bd->const_val = get_sbits_long(gb, const_val_bits);
}
+ // ensure constant block decoding by reusing this field
+ bd->const_block = 1;
+}
+
+
+/** Decodes the block data for a constant block
+ */
+static void decode_const_block_data(ALSDecContext *ctx, ALSBlockData *bd)
+{
+ int smp;
+
// write raw samples into buffer
- for (k = 0; k < block_length; k++)
- raw_samples[k] = const_val;
+ for (smp = 0; smp < bd->block_length; smp++)
+ bd->raw_samples[smp] = bd->const_val;
}
/** 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)
+static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd)
{
ALSSpecificConfig *sconf = &ctx->sconf;
AVCodecContext *avctx = ctx->avctx;
@@ -463,18 +489,14 @@ static int read_var_block(ALSDecContext
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;
- int use_ltp = 0;
- int ltp_lag = 0;
- int ltp_gain[5];
+ int sb;
- *js_blocks = get_bits1(gb);
+ // ensure variable block decoding by reusing this field
+ bd->const_block = 0;
+
+ bd->opt_order = 1;
+ bd->js_blocks = get_bits1(gb);
// determine the number of subblocks for entropy decoding
if (!sconf->bgmc && !sconf->sb_part) {
@@ -490,13 +512,13 @@ static int read_var_block(ALSDecContext
// 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)) {
+ if (bd->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;
+ sb_length = bd->block_length >> log2_sub_blocks;
if (sconf->bgmc) {
@@ -508,119 +530,134 @@ static int read_var_block(ALSDecContext
}
if (get_bits1(gb))
- *shift_lsbs = get_bits(gb, 4) + 1;
-
- store_prev_samples = (*js_blocks && raw_other) || *shift_lsbs;
+ bd->shift_lsbs = get_bits(gb, 4) + 1;
+ bd->store_prev_samples = (bd->js_blocks && bd->raw_other) ||
+ bd->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);
+ int opt_order_length = av_ceil_log2(av_clip((bd->block_length >> 3) - 1,
+ 2, sconf->max_order + 1));
+ bd->opt_order = get_bits(gb, opt_order_length);
} else {
- opt_order = sconf->max_order;
+ bd->opt_order = sconf->max_order;
}
- if (opt_order) {
+ if (bd->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)];
- quant_cof[0] *= 32;
+ bd->quant_cof[0] = parcor_scaled_values[get_bits(gb, 7)];
+ bd->quant_cof[0] *= 32;
// read coefficient 1
- quant_cof[1] = -parcor_scaled_values[get_bits(gb, 7)];
- quant_cof[0] *= 32;
+ bd->quant_cof[1] = -parcor_scaled_values[get_bits(gb, 7)];
+ bd->quant_cof[0] *= 32;
// read coefficients 2 to opt_order
- for (k = 2; k < opt_order; k++)
- quant_cof[k] = get_bits(gb, 7);
+ for (k = 2; k < bd->opt_order; k++)
+ bd->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);
+ k_max = FFMIN(bd->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;
+ bd->quant_cof[k] = decode_rice(gb, rice_param) + offset;
}
// read coefficients 20 to 126
- k_max = FFMIN(opt_order, 127);
+ k_max = FFMIN(bd->opt_order, 127);
for (; k < k_max; k++)
- quant_cof[k] = decode_rice(gb, 2) + (k & 1);
+ bd->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);
+ for (; k < bd->opt_order; k++)
+ bd->quant_cof[k] = decode_rice(gb, 1);
- quant_cof[0] = parcor_scaled_values[quant_cof[0] + 64];
- quant_cof[0] *= 32;
- quant_cof[1] = -parcor_scaled_values[quant_cof[1] + 64];
- quant_cof[1] *= 32;
+ bd->quant_cof[0] = parcor_scaled_values[bd->quant_cof[0] + 64];
+ bd->quant_cof[0] *= 32;
+ bd->quant_cof[1] = -parcor_scaled_values[bd->quant_cof[1] + 64];
+ bd->quant_cof[1] *= 32;
}
- for (k = 2; k < opt_order; k++)
- quant_cof[k] = (quant_cof[k] << 14) + (add_base << 13);
+ for (k = 2; k < bd->opt_order; k++)
+ bd->quant_cof[k] = (bd->quant_cof[k] << 14) + (add_base << 13);
}
}
// read LTP gain and lag values
if (sconf->long_term_prediction) {
- use_ltp = get_bits1(gb);
+ bd->use_ltp = get_bits1(gb);
- if (use_ltp) {
- ltp_gain[0] = decode_rice(gb, 1) << 3;
- ltp_gain[1] = decode_rice(gb, 2) << 3;
+ if (bd->use_ltp) {
+ bd->ltp_gain[0] = decode_rice(gb, 1) << 3;
+ bd->ltp_gain[1] = decode_rice(gb, 2) << 3;
- ltp_gain[2] = get_unary(gb, 0, 4);
- ltp_gain[2] <<= 2;
- ltp_gain[2] += get_bits(gb, 2);
- ltp_gain[2] = ltp_gain_values[ltp_gain[2]];
+ bd->ltp_gain[2] = get_unary(gb, 0, 4);
+ bd->ltp_gain[2] <<= 2;
+ bd->ltp_gain[2] += get_bits(gb, 2);
+ bd->ltp_gain[2] = ltp_gain_values[bd->ltp_gain[2]];
- ltp_gain[3] = decode_rice(gb, 2) << 3;
- ltp_gain[4] = decode_rice(gb, 1) << 3;
+ bd->ltp_gain[3] = decode_rice(gb, 2) << 3;
+ bd->ltp_gain[4] = decode_rice(gb, 1) << 3;
- ltp_lag = get_bits(gb, ctx->ltp_lag_length);
- ltp_lag += FFMAX(4, opt_order + 1);
+ bd->ltp_lag = get_bits(gb, ctx->ltp_lag_length);
+ bd->ltp_lag += FFMAX(4, bd->opt_order + 1);
}
}
// 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);
+ if (bd->ra_block) {
+ if (bd->opt_order)
+ bd->raw_samples[0] = decode_rice(gb, avctx->bits_per_raw_sample - 4);
+ if (bd->opt_order > 1)
+ bd->raw_samples[1] = decode_rice(gb, s[0] + 3);
+ if (bd->opt_order > 2)
+ bd->raw_samples[2] = decode_rice(gb, s[0] + 1);
- start = FFMIN(opt_order, 3);
+ start = FFMIN(bd->opt_order, 3);
}
// read all residuals
if (sconf->bgmc) {
// TODO: BGMC mode
} else {
- int32_t *current_res = raw_samples + start;
+ int32_t *current_res = bd->raw_samples + start;
for (sb = 0; sb < sub_blocks; sb++, start = 0)
for (; start < sb_length; start++)
*current_res++ = decode_rice(gb, s[sb]);
- }
+ }
+
+ return 0;
+}
+
+
+/** Decodes the block data for a non-constant block
+ */
+static int decode_var_block_data(ALSDecContext *ctx, ALSBlockData *bd)
+{
+ ALSSpecificConfig *sconf = &ctx->sconf;
+ unsigned int block_length = bd->block_length;
+ unsigned int smp = 0;
+ unsigned int k;
+ int sb;
+ int64_t y;
// reverse long-term prediction
- if (use_ltp) {
+ if (bd->use_ltp) {
int ltp_smp;
- for (ltp_smp = FFMAX(ltp_lag - 2, 0); ltp_smp < block_length; ltp_smp++) {
- int center = ltp_smp - ltp_lag;
+ for (ltp_smp = FFMAX(bd->ltp_lag - 2, 0); ltp_smp < block_length; ltp_smp++) {
+ int center = ltp_smp - bd->ltp_lag;
int begin = FFMAX(0, center - 2);
int end = center + 3;
int tab = 5 - (end - begin);
@@ -629,68 +666,68 @@ static int read_var_block(ALSDecContext
y = 1 << 6;
for (base = begin; base < end; base++, tab++)
- y += MUL64(ltp_gain[tab], raw_samples[base]);
+ y += MUL64(bd->ltp_gain[tab], bd->raw_samples[base]);
- raw_samples[ltp_smp] += y >> 7;
+ bd->raw_samples[ltp_smp] += y >> 7;
}
}
// reconstruct all samples from residuals
- if (ra_block) {
- for (smp = 0; smp < opt_order; smp++) {
+ if (bd->ra_block) {
+ for (smp = 0; smp < bd->opt_order; smp++) {
y = 1 << 19;
for (sb = 0; sb < smp; sb++)
- y += MUL64(lpc_cof[sb],raw_samples[smp - (sb + 1)]);
+ y += MUL64(bd->lpc_cof[sb], bd->raw_samples[smp - (sb + 1)]);
- raw_samples[smp] -= y >> 20;
- parcor_to_lpc(smp, quant_cof, lpc_cof);
+ bd->raw_samples[smp] -= y >> 20;
+ parcor_to_lpc(smp, bd->quant_cof, bd->lpc_cof);
}
} else {
- for (k = 0; k < opt_order; k++)
- parcor_to_lpc(k, quant_cof, lpc_cof);
+ for (k = 0; k < bd->opt_order; k++)
+ parcor_to_lpc(k, bd->quant_cof, bd->lpc_cof);
// store previous samples in case that they have to be altered
- if (store_prev_samples)
- memcpy(ctx->prev_raw_samples, raw_samples - sconf->max_order,
- sizeof(*ctx->prev_raw_samples) * sconf->max_order);
+ if (bd->store_prev_samples)
+ memcpy(bd->prev_raw_samples, bd->raw_samples - sconf->max_order,
+ sizeof(*bd->prev_raw_samples) * sconf->max_order);
// reconstruct difference signal for prediction (joint-stereo)
- if (*js_blocks && raw_other) {
+ if (bd->js_blocks && bd->raw_other) {
int32_t *left, *right;
- if (raw_other > raw_samples) { // D = R - L
- left = raw_samples;
- right = raw_other;
+ if (bd->raw_other > bd->raw_samples) { // D = R - L
+ left = bd->raw_samples;
+ right = bd->raw_other;
} else { // D = R - L
- left = raw_other;
- right = raw_samples;
+ left = bd->raw_other;
+ right = bd->raw_samples;
}
for (sb = -1; sb >= -sconf->max_order; sb--)
- raw_samples[sb] = right[sb] - left[sb];
+ bd->raw_samples[sb] = right[sb] - left[sb];
}
// reconstruct shifted signal
- if (*shift_lsbs)
+ if (bd->shift_lsbs)
for (sb = -1; sb >= -sconf->max_order; sb--)
- raw_samples[sb] >>= *shift_lsbs;
+ bd->raw_samples[sb] >>= bd->shift_lsbs;
}
// reconstruct raw samples
- for (; smp < block_length; smp++) {
+ for (; smp < bd->block_length; smp++) {
y = 1 << 19;
- for (sb = 0; sb < opt_order; sb++)
- y += MUL64(lpc_cof[sb],raw_samples[smp - (sb + 1)]);
+ for (sb = 0; sb < bd->opt_order; sb++)
+ y += MUL64(bd->lpc_cof[sb], bd->raw_samples[smp - (sb + 1)]);
- raw_samples[smp] -= y >> 20;
+ bd->raw_samples[smp] -= y >> 20;
}
// restore previous samples in case that they have been altered
- if (store_prev_samples)
- memcpy(raw_samples - sconf->max_order, ctx->prev_raw_samples,
- sizeof(*raw_samples) * sconf->max_order);
+ if (bd->store_prev_samples)
+ memcpy(bd->raw_samples - sconf->max_order, bd->prev_raw_samples,
+ sizeof(*bd->raw_samples) * sconf->max_order);
return 0;
}
@@ -698,32 +735,42 @@ static int read_var_block(ALSDecContext
/** Reads the block data.
*/
-static int read_block_data(ALSDecContext *ctx, unsigned int ra_block,
- int32_t *raw_samples, unsigned int block_length,
- unsigned int *js_blocks, int32_t *raw_other)
+static int read_block(ALSDecContext *ctx, ALSBlockData *bd)
+{
+ GetBitContext *gb = &ctx->gb;
+
+ // read block type flag and read the samples accordingly
+ if (get_bits1(gb))
+ read_var_block_data(ctx, bd);
+ else
+ read_const_block_data(ctx, bd);
+
+ return 0;
+}
+
+
+/** Decodes the block data.
+ */
+static int decode_block(ALSDecContext *ctx, ALSBlockData *bd)
{
ALSSpecificConfig *sconf = &ctx->sconf;
GetBitContext *gb = &ctx->gb;
- unsigned int shift_lsbs = 0;
- unsigned int k;
+ unsigned int smp;
// read block type flag and read the samples accordingly
- if (get_bits1(gb)) {
- if (read_var_block(ctx, ra_block, raw_samples, block_length, js_blocks,
- raw_other, &shift_lsbs))
- return -1;
- } else {
- read_const_block(ctx, raw_samples, block_length, js_blocks);
- }
+ if (bd->const_block)
+ decode_const_block_data(ctx, bd);
+ else if (decode_var_block_data(ctx, bd))
+ return -1;
// TODO: read RLSLMS extension data
if (!sconf->mc_coding || ctx->js_switch)
align_get_bits(gb);
- if (shift_lsbs)
- for (k = 0; k < block_length; k++)
- raw_samples[k] <<= shift_lsbs;
+ if (bd->shift_lsbs)
+ for (smp = 0; smp < bd->block_length; smp++)
+ bd->raw_samples[smp] <<= bd->shift_lsbs;
return 0;
}
@@ -750,21 +797,34 @@ static int decode_blocks_ind(ALSDecConte
unsigned int c, const unsigned int *div_blocks,
unsigned int *js_blocks)
{
- int32_t *raw_sample;
unsigned int b;
- raw_sample = ctx->raw_samples[c];
+ ALSBlockData bd;
+
+ memset(&bd, 0, sizeof(ALSBlockData));
+
+ bd.ra_block = ra_frame;
+ bd.quant_cof = ctx->quant_cof;
+ bd.lpc_cof = ctx->lpc_cof;
+ bd.prev_raw_samples = ctx->prev_raw_samples;
+ bd.raw_samples = ctx->raw_samples[c];
+
for (b = 0; b < ctx->num_blocks; b++) {
- if (read_block_data(ctx, ra_frame, raw_sample,
- div_blocks[b], &js_blocks[0], NULL)) {
- // damaged block, write zero for the rest of the frame
- zero_remaining(b, ctx->num_blocks, div_blocks, raw_sample);
+ bd.shift_lsbs = 0;
+ bd.block_length = div_blocks[b];
+
+ if (read_block(ctx, &bd) ||
+ decode_block(ctx, &bd)) {
+ zero_remaining(b, ctx->num_blocks, div_blocks, bd.raw_samples);
return -1;
- }
- raw_sample += div_blocks[b];
- ra_frame = 0;
+ }
+
+ bd.raw_samples += div_blocks[b];
+ bd.ra_block = 0;
}
+ *js_blocks = bd.js_blocks;
+
return 0;
}
@@ -777,39 +837,62 @@ static int decode_blocks(ALSDecContext *
{
ALSSpecificConfig *sconf = &ctx->sconf;
unsigned int offset = 0;
- int32_t *raw_samples_R;
- int32_t *raw_samples_L;
unsigned int b;
+ ALSBlockData bd[2];
+
+ memset(bd, 0, 2 * sizeof(ALSBlockData));
+
+ bd[0].ra_block = ra_frame;
+ bd[0].quant_cof = ctx->quant_cof;
+ bd[0].lpc_cof = ctx->lpc_cof;
+ bd[0].prev_raw_samples = ctx->prev_raw_samples;
+ bd[0].js_blocks = *js_blocks;
+
+ bd[1].ra_block = ra_frame;
+ bd[1].quant_cof = ctx->quant_cof;
+ bd[1].lpc_cof = ctx->lpc_cof;
+ bd[1].prev_raw_samples = ctx->prev_raw_samples;
+ bd[1].js_blocks = *(js_blocks + 1);
// 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)) {
+
+ bd[0].shift_lsbs = 0;
+ bd[1].shift_lsbs = 0;
+
+ bd[0].block_length = div_blocks[b];
+ bd[1].block_length = div_blocks[b];
+
+ bd[0].raw_samples = ctx->raw_samples[c ] + offset;
+ bd[1].raw_samples = ctx->raw_samples[c + 1] + offset;
+
+ bd[0].raw_other = bd[1].raw_samples;
+ bd[1].raw_other = bd[0].raw_samples;
+
+ if (read_block(ctx, &bd[0]) || decode_block(ctx, &bd[0]) ||
+ read_block(ctx, &bd[1]) || decode_block(ctx, &bd[1])) {
// damaged block, write zero for the rest of the frame
- zero_remaining(b, ctx->num_blocks, div_blocks, raw_samples_L);
- zero_remaining(b, ctx->num_blocks, div_blocks, raw_samples_R);
+ zero_remaining(b, ctx->num_blocks, div_blocks, bd[0].raw_samples);
+ zero_remaining(b, ctx->num_blocks, div_blocks, bd[1].raw_samples);
return -1;
}
// reconstruct joint-stereo blocks
- if (js_blocks[0]) {
- if (js_blocks[1])
+ if (bd[0].js_blocks) {
+ if (bd[1].js_blocks)
av_log(ctx->avctx, AV_LOG_WARNING, "Invalid channel pair!\n");
for (s = 0; s < div_blocks[b]; s++)
- raw_samples_L[s] = raw_samples_R[s] - raw_samples_L[s];
- } else if (js_blocks[1]) {
+ bd[0].raw_samples[s] = bd[1].raw_samples[s] - bd[0].raw_samples[s];
+ } else if (bd[1].js_blocks) {
for (s = 0; s < div_blocks[b]; s++)
- raw_samples_R[s] = raw_samples_R[s] + raw_samples_L[s];
+ bd[1].raw_samples[s] = bd[1].raw_samples[s] + bd[0].raw_samples[s];
}
offset += div_blocks[b];
- ra_frame = 0;
+ bd[0].ra_block = 0;
+ bd[1].ra_block = 0;
}
// store carryover raw samples,
More information about the FFmpeg-soc
mailing list