diff options
author | Justin Ruggles <justin.ruggles@gmail.com> | 2011-09-14 19:16:14 -0400 |
---|---|---|
committer | Justin Ruggles <justin.ruggles@gmail.com> | 2011-10-20 13:09:25 -0400 |
commit | fe31a637f1ec5b8a22194d0f8d643c1a567b39b8 (patch) | |
tree | 470e63ceaa4909ab865e2506e0756e7eeaf78e32 | |
parent | 0f97c5014b63f94ebffeb3b0f48c21bbe77b11f3 (diff) | |
download | ffmpeg-fe31a637f1ec5b8a22194d0f8d643c1a567b39b8.tar.gz |
shorten: move decoding of prediction order and applying of global offset to
decode_subframe_lpc().
-rw-r--r-- | libavcodec/shorten.c | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index a4313aeb37..52bf2b2471 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -260,20 +260,41 @@ static int16_t * interleave_buffer(int16_t *samples, int nchan, int blocksize, i return samples; } -static void decode_subframe_lpc(ShortenContext *s, int channel, int residual_size, int pred_order) +static int decode_subframe_lpc(ShortenContext *s, int channel, + int residual_size, int32_t coffset) { - int sum, i, j; + int pred_order, sum, i, j; int *coeffs = s->coeffs; + /* read/validate prediction order */ + pred_order = get_ur_golomb_shorten(&s->gb, LPCQSIZE); + if (pred_order > s->nwrap) { + av_log(s->avctx, AV_LOG_ERROR, "invalid pred_order %d\n", pred_order); + return AVERROR(EINVAL); + } + /* read LPC coefficients */ for (i=0; i<pred_order; i++) coeffs[i] = get_sr_golomb_shorten(&s->gb, LPCQUANT); + /* subtract offset from previous samples to use in prediction */ + if (coffset) + for (i = -pred_order; i < 0; i++) + s->decoded[channel][i] -= coffset; + + /* decode residual and do LPC prediction */ for (i=0; i < s->blocksize; i++) { sum = s->lpcqoffset; for (j=0; j<pred_order; j++) sum += coeffs[j] * s->decoded[channel][i-j-1]; s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + (sum >> LPCQUANT); } + + /* add offset to current samples */ + if (coffset != 0) + for (i = 0; i < s->blocksize; i++) + s->decoded[channel][i] += coffset; + + return 0; } static int read_header(ShortenContext *s) @@ -429,6 +450,7 @@ static int shorten_decode_frame(AVCodecContext *avctx, *data_size = 0; } else { /* process audio command */ + int ret; int residual_size = 0; int channel = s->cur_chan; int32_t coffset; @@ -474,21 +496,9 @@ static int shorten_decode_frame(AVCodecContext *avctx, + s->decoded[channel][i-3]; break; case FN_QLPC: - { - int pred_order = get_ur_golomb_shorten(&s->gb, LPCQSIZE); - if (pred_order > s->nwrap) { - av_log(avctx, AV_LOG_ERROR, - "invalid pred_order %d\n", - pred_order); - return -1; - } - for (i=0; i<pred_order; i++) - s->decoded[channel][i - pred_order] -= coffset; - decode_subframe_lpc(s, channel, residual_size, pred_order); - if (coffset != 0) - for (i=0; i < s->blocksize; i++) - s->decoded[channel][i] += coffset; - } + if ((ret = decode_subframe_lpc(s, channel, residual_size, coffset)) < 0) + return ret; + break; } if (s->nmean > 0) { int32_t sum = (s->version < 2) ? 0 : s->blocksize / 2; |