summaryrefslogtreecommitdiff
path: root/libavcodec/flac.c
diff options
context:
space:
mode:
authorLoren Merritt <lorenm@u.washington.edu>2007-09-30 02:12:03 +0000
committerLoren Merritt <lorenm@u.washington.edu>2007-09-30 02:12:03 +0000
commit08965b22e2565dffc2aaadf25ec8a481eadf6285 (patch)
tree79505efc813a34dcd0b61709b17c5f21366911b7 /libavcodec/flac.c
parentbfdd5bc1f15c0c632dd8ad683fa03a63b4dec9f6 (diff)
downloadffmpeg-08965b22e2565dffc2aaadf25ec8a481eadf6285.tar.gz
replace FIR with finite differences.
3x faster decode_subframe_fixed(). overall flac decoding: 10% faster if file was encoded with fixed predictors. Originally committed as revision 10626 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/flac.c')
-rw-r--r--libavcodec/flac.c33
1 files changed, 17 insertions, 16 deletions
diff --git a/libavcodec/flac.c b/libavcodec/flac.c
index d8e8813d9e..5c0a2f76b1 100644
--- a/libavcodec/flac.c
+++ b/libavcodec/flac.c
@@ -259,7 +259,9 @@ static int decode_residuals(FLACContext *s, int channel, int pred_order)
static int decode_subframe_fixed(FLACContext *s, int channel, int pred_order)
{
- int i;
+ const int blocksize = s->blocksize;
+ int32_t *decoded = s->decoded[channel];
+ int a, b, c, d, i;
// av_log(s->avctx, AV_LOG_DEBUG, " SUBFRAME FIXED\n");
@@ -268,38 +270,37 @@ static int decode_subframe_fixed(FLACContext *s, int channel, int pred_order)
for (i = 0; i < pred_order; i++)
{
- s->decoded[channel][i] = get_sbits(&s->gb, s->curr_bps);
+ decoded[i] = get_sbits(&s->gb, s->curr_bps);
// av_log(s->avctx, AV_LOG_DEBUG, " %d: %d\n", i, s->decoded[channel][i]);
}
if (decode_residuals(s, channel, pred_order) < 0)
return -1;
+ a = decoded[pred_order-1];
+ b = a - decoded[pred_order-2];
+ c = b - decoded[pred_order-2] + decoded[pred_order-3];
+ d = c - decoded[pred_order-2] + 2*decoded[pred_order-3] - decoded[pred_order-4];
+
switch(pred_order)
{
case 0:
break;
case 1:
- for (i = pred_order; i < s->blocksize; i++)
- s->decoded[channel][i] += s->decoded[channel][i-1];
+ for (i = pred_order; i < blocksize; i++)
+ decoded[i] = a += decoded[i];
break;
case 2:
- for (i = pred_order; i < s->blocksize; i++)
- s->decoded[channel][i] += 2*s->decoded[channel][i-1]
- - s->decoded[channel][i-2];
+ for (i = pred_order; i < blocksize; i++)
+ decoded[i] = a += b += decoded[i];
break;
case 3:
- for (i = pred_order; i < s->blocksize; i++)
- s->decoded[channel][i] += 3*s->decoded[channel][i-1]
- - 3*s->decoded[channel][i-2]
- + s->decoded[channel][i-3];
+ for (i = pred_order; i < blocksize; i++)
+ decoded[i] = a += b += c += decoded[i];
break;
case 4:
- for (i = pred_order; i < s->blocksize; i++)
- s->decoded[channel][i] += 4*s->decoded[channel][i-1]
- - 6*s->decoded[channel][i-2]
- + 4*s->decoded[channel][i-3]
- - s->decoded[channel][i-4];
+ for (i = pred_order; i < blocksize; i++)
+ decoded[i] = a += b += c += d += decoded[i];
break;
default:
av_log(s->avctx, AV_LOG_ERROR, "illegal pred order %d\n", pred_order);