summaryrefslogtreecommitdiff
path: root/libavcodec/adpcmenc.c
diff options
context:
space:
mode:
authorBaptiste Coudurier <baptiste.coudurier@gmail.com>2011-09-07 22:27:03 -0400
committerJustin Ruggles <justin.ruggles@gmail.com>2011-09-23 20:54:29 -0400
commitb304244b54611e9a84e22ab40e94be4a7a474c21 (patch)
treea0f008982b5db10d73b611b0dbf292f53250628b /libavcodec/adpcmenc.c
parentbf334535b4d41e7278bd5361492cfe357b8b9821 (diff)
adpcmenc: fix QT IMA ADPCM encoder
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/adpcmenc.c')
-rw-r--r--libavcodec/adpcmenc.c39
1 files changed, 35 insertions, 4 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;
}
}