diff options
author | Baptiste Coudurier <baptiste.coudurier@gmail.com> | 2011-09-07 22:27:03 -0400 |
---|---|---|
committer | Justin Ruggles <justin.ruggles@gmail.com> | 2011-09-23 20:54:29 -0400 |
commit | b304244b54611e9a84e22ab40e94be4a7a474c21 (patch) | |
tree | a0f008982b5db10d73b611b0dbf292f53250628b | |
parent | bf334535b4d41e7278bd5361492cfe357b8b9821 (diff) | |
download | ffmpeg-b304244b54611e9a84e22ab40e94be4a7a474c21.tar.gz |
adpcmenc: fix QT IMA ADPCM encoder
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/adpcmenc.c | 39 | ||||
-rw-r--r-- | tests/ref/acodec/adpcm_ima_qt | 6 |
2 files changed, 38 insertions, 7 deletions
diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c index ec062849bd..6295eedc55 100644 --- a/libavcodec/adpcmenc.c +++ b/libavcodec/adpcmenc.c @@ -164,6 +164,39 @@ static inline unsigned char adpcm_ima_compress_sample(ADPCMChannelStatus *c, sho return nibble; } +static inline unsigned char adpcm_ima_qt_compress_sample(ADPCMChannelStatus *c, short sample) +{ + int delta = sample - c->prev_sample; + int mask, step = ff_adpcm_step_table[c->step_index]; + int diff = step >> 3; + int nibble = 0; + + if (delta < 0) { + nibble = 8; + delta = -delta; + } + + for (mask = 4; mask;) { + if (delta >= step) { + nibble |= mask; + delta -= step; + diff += step; + } + step >>= 1; + mask >>= 1; + } + + if (nibble & 8) + c->prev_sample -= diff; + else + c->prev_sample += diff; + + c->prev_sample = av_clip_int16(c->prev_sample); + c->step_index = av_clip(c->step_index + ff_adpcm_index_table[nibble], 0, 88); + + return nibble; +} + static inline unsigned char adpcm_ms_compress_sample(ADPCMChannelStatus *c, short sample) { int predictor, nibble, bias; @@ -497,16 +530,14 @@ static int adpcm_encode_frame(AVCodecContext *avctx, adpcm_compress_trellis(avctx, samples+ch, buf, &c->status[ch], 64); for(i=0; i<64; i++) put_bits(&pb, 4, buf[i^1]); - c->status[ch].prev_sample = c->status[ch].predictor & ~0x7F; } else { for (i=0; i<64; i+=2){ int t1, t2; - t1 = adpcm_ima_compress_sample(&c->status[ch], samples[avctx->channels*(i+0)+ch]); - t2 = adpcm_ima_compress_sample(&c->status[ch], samples[avctx->channels*(i+1)+ch]); + t1 = adpcm_ima_qt_compress_sample(&c->status[ch], samples[avctx->channels*(i+0)+ch]); + t2 = adpcm_ima_qt_compress_sample(&c->status[ch], samples[avctx->channels*(i+1)+ch]); put_bits(&pb, 4, t2); put_bits(&pb, 4, t1); } - c->status[ch].prev_sample &= ~0x7F; } } diff --git a/tests/ref/acodec/adpcm_ima_qt b/tests/ref/acodec/adpcm_ima_qt index a91cd2da3d..cdd60e06b9 100644 --- a/tests/ref/acodec/adpcm_ima_qt +++ b/tests/ref/acodec/adpcm_ima_qt @@ -1,4 +1,4 @@ -019564da45949d0b5278bd75ee9a4ac2 *./tests/data/acodec/adpcm_qt.aiff +057d27978b35888776512e4e9669a63b *./tests/data/acodec/adpcm_qt.aiff 281252 ./tests/data/acodec/adpcm_qt.aiff -a7fb054f7bd82270c8fd476eb9f5677c *./tests/data/adpcm_ima_qt.acodec.out.wav -stddev: 920.19 PSNR: 37.05 MAXDIFF:34029 bytes: 1058560/ 1058400 +3890343c0c20934e014d7ac93f5d65bd *./tests/data/adpcm_ima_qt.acodec.out.wav +stddev: 918.61 PSNR: 37.07 MAXDIFF:34029 bytes: 1058560/ 1058400 |