diff options
Diffstat (limited to 'libavcodec/adpcm.c')
-rw-r--r-- | libavcodec/adpcm.c | 115 |
1 files changed, 91 insertions, 24 deletions
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 70a5360ce8..ba312558b0 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -2,20 +2,20 @@ * ADPCM codecs * Copyright (c) 2001-2003 The ffmpeg Project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "avcodec.h" @@ -271,6 +271,42 @@ 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 diff, step = step_table[c->step_index]; + int nibble = 8*(delta < 0); + + delta= abs(delta); + diff = delta + (step >> 3); + + if (delta >= step) { + nibble |= 4; + delta -= step; + } + step >>= 1; + if (delta >= step) { + nibble |= 2; + delta -= step; + } + step >>= 1; + if (delta >= step) { + nibble |= 1; + delta -= step; + } + diff -= delta; + + 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 + index_table[nibble], 0, 88); + + return nibble; +} + static inline unsigned char adpcm_ms_compress_sample(ADPCMChannelStatus *c, short sample) { int predictor, nibble, bias; @@ -604,16 +640,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; } } @@ -750,6 +784,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) case CODEC_ID_ADPCM_EA_R1: case CODEC_ID_ADPCM_EA_R2: case CODEC_ID_ADPCM_EA_R3: + case CODEC_ID_ADPCM_EA_XAS: max_channels = 6; break; } @@ -807,6 +842,32 @@ static inline short adpcm_ima_expand_nibble(ADPCMChannelStatus *c, char nibble, return (short)c->predictor; } +static inline int adpcm_ima_qt_expand_nibble(ADPCMChannelStatus *c, int nibble, int shift) +{ + int step_index; + int predictor; + int diff, step; + + step = step_table[c->step_index]; + step_index = c->step_index + index_table[nibble]; + step_index = av_clip(step_index, 0, 88); + + diff = step >> 3; + if (nibble & 4) diff += step; + if (nibble & 2) diff += step >> 1; + if (nibble & 1) diff += step >> 2; + + if (nibble & 8) + predictor = c->predictor - diff; + else + predictor = c->predictor + diff; + + c->predictor = av_clip_int16(predictor); + c->step_index = step_index; + + return c->predictor; +} + static inline short adpcm_ms_expand_nibble(ADPCMChannelStatus *c, char nibble) { int predictor; @@ -1009,35 +1070,41 @@ static int adpcm_decode_frame(AVCodecContext *avctx, case CODEC_ID_ADPCM_IMA_QT: n = buf_size - 2*avctx->channels; for (channel = 0; channel < avctx->channels; channel++) { + int16_t predictor; + int step_index; cs = &(c->status[channel]); /* (pppppp) (piiiiiii) */ /* Bits 15-7 are the _top_ 9 bits of the 16-bit initial predictor value */ - cs->predictor = (*src++) << 8; - cs->predictor |= (*src & 0x80); - cs->predictor &= 0xFF80; - - /* sign extension */ - if(cs->predictor & 0x8000) - cs->predictor -= 0x10000; - - cs->predictor = av_clip_int16(cs->predictor); - - cs->step_index = (*src++) & 0x7F; + predictor = AV_RB16(src); + step_index = predictor & 0x7F; + predictor &= 0xFF80; + + src += 2; + + if (cs->step_index == step_index) { + int diff = (int)predictor - cs->predictor; + if (diff < 0) + diff = - diff; + if (diff > 0x7f) + goto update; + } else { + update: + cs->step_index = step_index; + cs->predictor = predictor; + } if (cs->step_index > 88){ av_log(avctx, AV_LOG_ERROR, "ERROR: step_index = %i\n", cs->step_index); cs->step_index = 88; } - cs->step = step_table[cs->step_index]; - samples = (short*)data + channel; for(m=32; n>0 && m>0; n--, m--) { /* in QuickTime, IMA is encoded by chuncks of 34 bytes (=64 samples) */ - *samples = adpcm_ima_expand_nibble(cs, src[0] & 0x0F, 3); + *samples = adpcm_ima_qt_expand_nibble(cs, src[0] & 0x0F, 3); samples += avctx->channels; - *samples = adpcm_ima_expand_nibble(cs, src[0] >> 4 , 3); + *samples = adpcm_ima_qt_expand_nibble(cs, src[0] >> 4 , 3); samples += avctx->channels; src ++; } @@ -1291,7 +1358,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, } break; case CODEC_ID_ADPCM_EA: - if (buf_size < 4 || AV_RL32(src) >= ((buf_size - 12) * 2)) { + if (buf_size < 12 || AV_RL32(src) > (buf_size - 12)/30*28) { src += buf_size; break; } |