diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2015-05-17 13:10:33 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2015-05-17 13:42:32 +0200 |
commit | b6fcb2bb6db1bf28e2d11f244448703998ea5428 (patch) | |
tree | e0f2b1b0895b1bae819ecef08d030de82a7556e7 /libavcodec | |
parent | 83356cf6cceb835e9bbed0ca94accb2cc32fcf03 (diff) | |
download | ffmpeg-b6fcb2bb6db1bf28e2d11f244448703998ea5428.tar.gz |
avcodec/flacdec: Attempt to auto-detect old buggy flac
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/flacdec.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index 36d2928137..30fe41618d 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -315,6 +315,33 @@ static int decode_subframe_fixed(FLACContext *s, int32_t *decoded, return 0; } +static void lpc_analyze_remodulate(int32_t *decoded, const int coeffs[32], + int order, int qlevel, int len, int bps) +{ + int i, j; + int ebps = 1 << (bps-1); + unsigned sigma = 0; + + for (i = order; i < len; i++) + sigma |= decoded[i] + ebps; + + if (sigma < 2*ebps) + return; + + for (i = len - 1; i >= order; i--) { + int64_t p = 0; + for (j = 0; j < order; j++) + p += coeffs[j] * (int64_t)decoded[i-order+j]; + decoded[i] -= p >> qlevel; + } + for (i = order; i < len; i++, decoded++) { + int32_t p = 0; + for (j = 0; j < order; j++) + p += coeffs[j] * (uint32_t)decoded[j]; + decoded[j] += p >> qlevel; + } +} + static int decode_subframe_lpc(FLACContext *s, int32_t *decoded, int pred_order, int bps) { @@ -352,6 +379,8 @@ static int decode_subframe_lpc(FLACContext *s, int32_t *decoded, int pred_order, s->dsp.lpc16(decoded, coeffs, pred_order, qlevel, s->blocksize); } else { s->dsp.lpc32(decoded, coeffs, pred_order, qlevel, s->blocksize); + if (s->flac_stream_info.bps <= 16) + lpc_analyze_remodulate(decoded, coeffs, pred_order, qlevel, s->blocksize, bps); } return 0; |