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; igb, 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; jdecoded[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; idecoded[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;