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
pull/126/head
Loren Merritt 17 years ago
parent bfdd5bc1f1
commit 08965b22e2
  1. 33
      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) 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"); // 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++) 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]); // av_log(s->avctx, AV_LOG_DEBUG, " %d: %d\n", i, s->decoded[channel][i]);
} }
if (decode_residuals(s, channel, pred_order) < 0) if (decode_residuals(s, channel, pred_order) < 0)
return -1; 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) switch(pred_order)
{ {
case 0: case 0:
break; break;
case 1: case 1:
for (i = pred_order; i < s->blocksize; i++) for (i = pred_order; i < blocksize; i++)
s->decoded[channel][i] += s->decoded[channel][i-1]; decoded[i] = a += decoded[i];
break; break;
case 2: case 2:
for (i = pred_order; i < s->blocksize; i++) for (i = pred_order; i < blocksize; i++)
s->decoded[channel][i] += 2*s->decoded[channel][i-1] decoded[i] = a += b += decoded[i];
- s->decoded[channel][i-2];
break; break;
case 3: case 3:
for (i = pred_order; i < s->blocksize; i++) for (i = pred_order; i < blocksize; i++)
s->decoded[channel][i] += 3*s->decoded[channel][i-1] decoded[i] = a += b += c += decoded[i];
- 3*s->decoded[channel][i-2]
+ s->decoded[channel][i-3];
break; break;
case 4: case 4:
for (i = pred_order; i < s->blocksize; i++) for (i = pred_order; i < blocksize; i++)
s->decoded[channel][i] += 4*s->decoded[channel][i-1] decoded[i] = a += b += c += d += decoded[i];
- 6*s->decoded[channel][i-2]
+ 4*s->decoded[channel][i-3]
- s->decoded[channel][i-4];
break; break;
default: default:
av_log(s->avctx, AV_LOG_ERROR, "illegal pred order %d\n", pred_order); av_log(s->avctx, AV_LOG_ERROR, "illegal pred order %d\n", pred_order);

Loading…
Cancel
Save