aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/shorten.c
diff options
context:
space:
mode:
authorJustin Ruggles <justin.ruggles@gmail.com>2011-09-14 19:16:14 -0400
committerJustin Ruggles <justin.ruggles@gmail.com>2011-10-20 13:09:25 -0400
commitfe31a637f1ec5b8a22194d0f8d643c1a567b39b8 (patch)
tree470e63ceaa4909ab865e2506e0756e7eeaf78e32 /libavcodec/shorten.c
parent0f97c5014b63f94ebffeb3b0f48c21bbe77b11f3 (diff)
downloadffmpeg-fe31a637f1ec5b8a22194d0f8d643c1a567b39b8.tar.gz
shorten: move decoding of prediction order and applying of global offset to
decode_subframe_lpc().
Diffstat (limited to 'libavcodec/shorten.c')
-rw-r--r--libavcodec/shorten.c44
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;