提交 93d38cf6 编写于 作者: T Thilo Borgmann

Add long-term prediction to the ALS decoder.

Originally committed as revision 20534 to svn://svn.ffmpeg.org/ffmpeg/trunk
上级 7934cbb3
...@@ -92,4 +92,14 @@ static const int16_t parcor_scaled_values[] = { ...@@ -92,4 +92,14 @@ static const int16_t parcor_scaled_values[] = {
}; };
/** 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 */ #endif /* AVCODEC_ALS_DATA_H */
...@@ -78,6 +78,7 @@ typedef struct { ...@@ -78,6 +78,7 @@ typedef struct {
unsigned int frame_id; ///< the frame ID / number of the current frame 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 js_switch; ///< if true, joint-stereo decoding is enforced
unsigned int num_blocks; ///< number of blocks used in the current frame 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 *quant_cof; ///< quantized parcor coefficients
int32_t *lpc_cof; ///< coefficients of the direct form prediction filter int32_t *lpc_cof; ///< coefficients of the direct form prediction filter
int32_t *prev_raw_samples; ///< contains unshifted raw samples from the previous block int32_t *prev_raw_samples; ///< contains unshifted raw samples from the previous block
...@@ -270,7 +271,6 @@ static int check_specific_config(ALSDecContext *ctx) ...@@ -270,7 +271,6 @@ static int check_specific_config(ALSDecContext *ctx)
} }
MISSING_ERR(sconf->floating, "Floating point decoding", -1); 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->bgmc, "BGMC entropy decoding", -1);
MISSING_ERR(sconf->mc_coding, "Multi-channel correlation", -1); MISSING_ERR(sconf->mc_coding, "Multi-channel correlation", -1);
MISSING_ERR(sconf->rlslms, "Adaptive RLS-LMS prediction", -1); MISSING_ERR(sconf->rlslms, "Adaptive RLS-LMS prediction", -1);
...@@ -443,6 +443,9 @@ static int read_var_block(ALSDecContext *ctx, unsigned int ra_block, ...@@ -443,6 +443,9 @@ static int read_var_block(ALSDecContext *ctx, unsigned int ra_block,
int smp = 0; int smp = 0;
int sb, store_prev_samples; int sb, store_prev_samples;
int64_t y; int64_t y;
int use_ltp = 0;
int ltp_lag = 0;
int ltp_gain[5];
*js_blocks = get_bits1(gb); *js_blocks = get_bits1(gb);
...@@ -540,7 +543,23 @@ static int read_var_block(ALSDecContext *ctx, unsigned int ra_block, ...@@ -540,7 +543,23 @@ static int read_var_block(ALSDecContext *ctx, unsigned int ra_block,
} }
} }
// 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 // read first value and residuals in case of a random access block
if (ra_block) { if (ra_block) {
...@@ -565,6 +584,26 @@ static int read_var_block(ALSDecContext *ctx, unsigned int ra_block, ...@@ -565,6 +584,26 @@ static int read_var_block(ALSDecContext *ctx, unsigned int ra_block,
*current_res++ = decode_rice(gb, s[sb]); *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 // reconstruct all samples from residuals
if (ra_block) { if (ra_block) {
for (smp = 0; smp < opt_order; smp++) { for (smp = 0; smp < opt_order; smp++) {
...@@ -949,6 +988,10 @@ static av_cold int decode_init(AVCodecContext *avctx) ...@@ -949,6 +988,10 @@ static av_cold int decode_init(AVCodecContext *avctx)
avctx->bits_per_raw_sample = (sconf->resolution + 1) * 8; 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; avctx->frame_size = sconf->frame_length;
channel_size = sconf->frame_length + sconf->max_order; channel_size = sconf->frame_length + sconf->max_order;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册