Mercurial > libavcodec.hg
changeset 10530:d428e57f14c6 libavcodec
Add long-term prediction to the ALS decoder.
author | thilo.borgmann |
---|---|
date | Sat, 14 Nov 2009 06:29:19 +0000 |
parents | f8fc0a56745e |
children | 142645a57180 |
files | als_data.h alsdec.c |
diffstat | 2 files changed, 55 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/als_data.h Sat Nov 14 00:25:48 2009 +0000 +++ b/als_data.h Sat Nov 14 06:29:19 2009 +0000 @@ -92,4 +92,14 @@ }; +/** Gain values of p(0) for long-term prediction. + * To be indexed by the Rice coded indices. + */ +static const uint8_t ltp_gain_values [4][4] = { + { 0, 8, 16, 24}, + {32, 40, 48, 56}, + {64, 70, 76, 82}, + {88, 92, 96, 100} +}; + #endif /* AVCODEC_ALS_DATA_H */
--- a/alsdec.c Sat Nov 14 00:25:48 2009 +0000 +++ b/alsdec.c Sat Nov 14 06:29:19 2009 +0000 @@ -78,6 +78,7 @@ unsigned int frame_id; ///< the frame ID / number of the current frame unsigned int js_switch; ///< if true, joint-stereo decoding is enforced unsigned int num_blocks; ///< number of blocks used in the current frame + int ltp_lag_length; ///< number of bits used for ltp lag value int32_t *quant_cof; ///< quantized parcor coefficients int32_t *lpc_cof; ///< coefficients of the direct form prediction filter int32_t *prev_raw_samples; ///< contains unshifted raw samples from the previous block @@ -270,7 +271,6 @@ } MISSING_ERR(sconf->floating, "Floating point decoding", -1); - MISSING_ERR(sconf->long_term_prediction, "Long-term prediction", -1); MISSING_ERR(sconf->bgmc, "BGMC entropy decoding", -1); MISSING_ERR(sconf->mc_coding, "Multi-channel correlation", -1); MISSING_ERR(sconf->rlslms, "Adaptive RLS-LMS prediction", -1); @@ -443,6 +443,9 @@ int smp = 0; int sb, store_prev_samples; int64_t y; + int use_ltp = 0; + int ltp_lag = 0; + int ltp_gain[5]; *js_blocks = get_bits1(gb); @@ -540,7 +543,23 @@ } } - // TODO: LTP mode + // read LTP gain and lag values + if (sconf->long_term_prediction) { + use_ltp = get_bits1(gb); + + if (use_ltp) { + ltp_gain[0] = decode_rice(gb, 1) << 3; + ltp_gain[1] = decode_rice(gb, 2) << 3; + + ltp_gain[2] = ltp_gain_values[get_unary(gb, 0, 4)][get_bits(gb, 2)]; + + ltp_gain[3] = decode_rice(gb, 2) << 3; + ltp_gain[4] = decode_rice(gb, 1) << 3; + + ltp_lag = get_bits(gb, ctx->ltp_lag_length); + ltp_lag += FFMAX(4, opt_order + 1); + } + } // read first value and residuals in case of a random access block if (ra_block) { @@ -565,6 +584,26 @@ *current_res++ = decode_rice(gb, s[sb]); } + // reverse long-term prediction + if (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; + int begin = FFMAX(0, center - 2); + int end = center + 3; + int tab = 5 - (end - begin); + int base; + + y = 1 << 6; + + for (base = begin; base < end; base++, tab++) + y += MUL64(ltp_gain[tab], raw_samples[base]); + + raw_samples[ltp_smp] += y >> 7; + } + } + // reconstruct all samples from residuals if (ra_block) { for (smp = 0; smp < opt_order; smp++) { @@ -949,6 +988,10 @@ avctx->bits_per_raw_sample = (sconf->resolution + 1) * 8; } + // set lag value for long-term prediction + ctx->ltp_lag_length = 8 + (avctx->sample_rate >= 96000) + + (avctx->sample_rate >= 192000); + avctx->frame_size = sconf->frame_length; channel_size = sconf->frame_length + sconf->max_order;