diff options
Diffstat (limited to 'libavcodec/adpcm.c')
-rw-r--r-- | libavcodec/adpcm.c | 196 |
1 files changed, 149 insertions, 47 deletions
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 3b0eb8b9d0..cd68257256 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -1,20 +1,20 @@ /* * 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" @@ -100,10 +100,12 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) case AV_CODEC_ID_ADPCM_EA: min_channels = 2; break; + case AV_CODEC_ID_ADPCM_AFC: case AV_CODEC_ID_ADPCM_EA_R1: case AV_CODEC_ID_ADPCM_EA_R2: case AV_CODEC_ID_ADPCM_EA_R3: case AV_CODEC_ID_ADPCM_EA_XAS: + case AV_CODEC_ID_ADPCM_THP: max_channels = 6; break; } @@ -146,6 +148,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) case AV_CODEC_ID_ADPCM_EA_R3: case AV_CODEC_ID_ADPCM_EA_XAS: case AV_CODEC_ID_ADPCM_THP: + case AV_CODEC_ID_ADPCM_AFC: avctx->sample_fmt = AV_SAMPLE_FMT_S16P; break; case AV_CODEC_ID_ADPCM_IMA_WS: @@ -229,6 +232,27 @@ static inline short adpcm_ms_expand_nibble(ADPCMChannelStatus *c, int nibble) return c->sample1; } +static inline short adpcm_ima_oki_expand_nibble(ADPCMChannelStatus *c, int nibble) +{ + int step_index, predictor, sign, delta, diff, step; + + step = ff_adpcm_oki_step_table[c->step_index]; + step_index = c->step_index + ff_adpcm_index_table[(unsigned)nibble]; + step_index = av_clip(step_index, 0, 48); + + sign = nibble & 8; + delta = nibble & 7; + diff = ((2 * delta + 1) * step) >> 3; + predictor = c->predictor; + if (sign) predictor -= diff; + else predictor += diff; + + c->predictor = av_clip(predictor, -2048, 2047); + c->step_index = step_index; + + return c->predictor << 4; +} + static inline short adpcm_ct_expand_nibble(ADPCMChannelStatus *c, char nibble) { int sign, delta, diff; @@ -302,11 +326,9 @@ static int xa_decode(AVCodecContext *avctx, int16_t *out0, int16_t *out1, for(i=0;i<4;i++) { shift = 12 - (in[4+i*2] & 15); filter = in[4+i*2] >> 4; - if (filter > 4) { - av_log(avctx, AV_LOG_ERROR, - "Invalid XA-ADPCM filter %d (max. allowed is 4)\n", - filter); - return AVERROR_INVALIDDATA; + if (filter >= FF_ARRAY_ELEMS(xa_adpcm_table)) { + av_log_ask_for_sample(avctx, "unknown XA-ADPCM filter %d\n", filter); + filter=0; } f0 = xa_adpcm_table[filter][0]; f1 = xa_adpcm_table[filter][1]; @@ -333,12 +355,11 @@ static int xa_decode(AVCodecContext *avctx, int16_t *out0, int16_t *out1, shift = 12 - (in[5+i*2] & 15); filter = in[5+i*2] >> 4; - if (filter > 4) { - av_log(avctx, AV_LOG_ERROR, - "Invalid XA-ADPCM filter %d (max. allowed is 4)\n", - filter); - return AVERROR_INVALIDDATA; + if (filter >= FF_ARRAY_ELEMS(xa_adpcm_table)) { + av_log_ask_for_sample(avctx, "unknown XA-ADPCM filter %d\n", filter); + filter=0; } + f0 = xa_adpcm_table[filter][0]; f1 = xa_adpcm_table[filter][1]; @@ -444,6 +465,9 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, *coded_samples = 0; + if(ch <= 0) + return 0; + switch (avctx->codec->id) { /* constant, only check buf_size */ case AV_CODEC_ID_ADPCM_EA_XAS: @@ -460,6 +484,7 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, case AV_CODEC_ID_ADPCM_CT: case AV_CODEC_ID_ADPCM_IMA_APC: case AV_CODEC_ID_ADPCM_IMA_EA_SEAD: + case AV_CODEC_ID_ADPCM_IMA_OKI: case AV_CODEC_ID_ADPCM_IMA_WS: case AV_CODEC_ID_ADPCM_YAMAHA: nb_samples = buf_size * 2 / ch; @@ -474,7 +499,7 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, case AV_CODEC_ID_ADPCM_4XM: case AV_CODEC_ID_ADPCM_IMA_ISS: header_size = 4 * ch; break; case AV_CODEC_ID_ADPCM_IMA_AMV: header_size = 8; break; - case AV_CODEC_ID_ADPCM_IMA_SMJPEG: header_size = 4; break; + case AV_CODEC_ID_ADPCM_IMA_SMJPEG: header_size = 4 * ch; break; } if (header_size > 0) return (buf_size - header_size) * 2 / ch; @@ -574,7 +599,10 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, bytestream2_skip(gb, 4); // channel size *coded_samples = bytestream2_get_be32(gb); *coded_samples -= *coded_samples % 14; - nb_samples = (buf_size - 80) / (8 * ch) * 14; + nb_samples = (buf_size - (8 + 36 * ch)) / (8 * ch) * 14; + break; + case AV_CODEC_ID_ADPCM_AFC: + nb_samples = buf_size / (9 * ch) * 16; break; case AV_CODEC_ID_ADPCM_XA: nb_samples = (buf_size / 128) * 224 / ch; @@ -773,7 +801,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } } - for (n = nb_samples >> (1 - st); n > 0; n--) { + for (n = (nb_samples - 1) >> (1 - st); n > 0; n--) { int v = bytestream2_get_byteu(&gb); *samples++ = adpcm_ima_expand_nibble(&c->status[0 ], v >> 4 , 3); *samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F, 3); @@ -874,6 +902,13 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, *samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F, 3); } break; + case AV_CODEC_ID_ADPCM_IMA_OKI: + while (bytestream2_get_bytes_left(&gb) > 0) { + int v = bytestream2_get_byteu(&gb); + *samples++ = adpcm_ima_oki_expand_nibble(&c->status[0], v >> 4 ); + *samples++ = adpcm_ima_oki_expand_nibble(&c->status[st], v & 0x0F); + } + break; case AV_CODEC_ID_ADPCM_IMA_WS: if (c->vqa_version == 3) { for (channel = 0; channel < avctx->channels; channel++) { @@ -949,6 +984,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, /* Each EA ADPCM frame has a 12-byte header followed by 30-byte pieces, each coding 28 stereo samples. */ + if(avctx->channels != 2) + return AVERROR_INVALIDDATA; + current_left_sample = sign_extend(bytestream2_get_le16u(&gb), 16); previous_left_sample = sign_extend(bytestream2_get_le16u(&gb), 16); current_right_sample = sign_extend(bytestream2_get_le16u(&gb), 16); @@ -1134,16 +1172,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, } break; case AV_CODEC_ID_ADPCM_IMA_AMV: - case AV_CODEC_ID_ADPCM_IMA_SMJPEG: - if (avctx->codec->id == AV_CODEC_ID_ADPCM_IMA_AMV) { - c->status[0].predictor = sign_extend(bytestream2_get_le16u(&gb), 16); - c->status[0].step_index = bytestream2_get_le16u(&gb); - bytestream2_skipu(&gb, 4); - } else { - c->status[0].predictor = sign_extend(bytestream2_get_be16u(&gb), 16); - c->status[0].step_index = bytestream2_get_byteu(&gb); - bytestream2_skipu(&gb, 1); - } + c->status[0].predictor = sign_extend(bytestream2_get_le16u(&gb), 16); + c->status[0].step_index = bytestream2_get_le16u(&gb); + bytestream2_skipu(&gb, 4); if (c->status[0].step_index > 88u) { av_log(avctx, AV_LOG_ERROR, "ERROR: step_index = %i\n", c->status[0].step_index); @@ -1151,18 +1182,29 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, } for (n = nb_samples >> (1 - st); n > 0; n--) { - int hi, lo, v = bytestream2_get_byteu(&gb); + int v = bytestream2_get_byteu(&gb); - if (avctx->codec->id == AV_CODEC_ID_ADPCM_IMA_AMV) { - hi = v & 0x0F; - lo = v >> 4; - } else { - lo = v & 0x0F; - hi = v >> 4; + *samples++ = adpcm_ima_expand_nibble(&c->status[0], v >> 4, 3); + *samples++ = adpcm_ima_expand_nibble(&c->status[0], v & 0xf, 3); + } + break; + case AV_CODEC_ID_ADPCM_IMA_SMJPEG: + for (i = 0; i < avctx->channels; i++) { + c->status[i].predictor = sign_extend(bytestream2_get_be16u(&gb), 16); + c->status[i].step_index = bytestream2_get_byteu(&gb); + bytestream2_skipu(&gb, 1); + if (c->status[i].step_index > 88u) { + av_log(avctx, AV_LOG_ERROR, "ERROR: step_index = %i\n", + c->status[i].step_index); + return AVERROR_INVALIDDATA; } + } + + for (n = nb_samples >> (1 - st); n > 0; n--) { + int v = bytestream2_get_byteu(&gb); - *samples++ = adpcm_ima_expand_nibble(&c->status[0], lo, 3); - *samples++ = adpcm_ima_expand_nibble(&c->status[0], hi, 3); + *samples++ = adpcm_ima_qt_expand_nibble(&c->status[0 ], v >> 4, 3); + *samples++ = adpcm_ima_qt_expand_nibble(&c->status[st], v & 0xf, 3); } break; case AV_CODEC_ID_ADPCM_CT: @@ -1226,22 +1268,75 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, *samples++ = adpcm_yamaha_expand_nibble(&c->status[st], v >> 4 ); } break; + case AV_CODEC_ID_ADPCM_AFC: + { + int samples_per_block; + int blocks; + + if (avctx->extradata && avctx->extradata_size == 1 && avctx->extradata[0]) { + samples_per_block = avctx->extradata[0] / 16; + blocks = nb_samples / avctx->extradata[0]; + } else { + samples_per_block = nb_samples / 16; + blocks = 1; + } + + for (m = 0; m < blocks; m++) { + for (channel = 0; channel < avctx->channels; channel++) { + int prev1 = c->status[channel].sample1; + int prev2 = c->status[channel].sample2; + + samples = samples_p[channel] + m * 16; + /* Read in every sample for this channel. */ + for (i = 0; i < samples_per_block; i++) { + int byte = bytestream2_get_byteu(&gb); + int scale = 1 << (byte >> 4); + int index = byte & 0xf; + int factor1 = ff_adpcm_afc_coeffs[0][index]; + int factor2 = ff_adpcm_afc_coeffs[1][index]; + + /* Decode 16 samples. */ + for (n = 0; n < 16; n++) { + int32_t sampledat; + + if (n & 1) { + sampledat = sign_extend(byte, 4); + } else { + byte = bytestream2_get_byteu(&gb); + sampledat = sign_extend(byte >> 4, 4); + } + + sampledat = ((prev1 * factor1 + prev2 * factor2) + + ((sampledat * scale) << 11)) >> 11; + *samples = av_clip_int16(sampledat); + prev2 = prev1; + prev1 = *samples++; + } + } + + c->status[channel].sample1 = prev1; + c->status[channel].sample2 = prev2; + } + } + bytestream2_seek(&gb, 0, SEEK_END); + break; + } case AV_CODEC_ID_ADPCM_THP: { - int table[2][16]; - int prev[2][2]; + int table[6][16]; int ch; - for (i = 0; i < 2; i++) + for (i = 0; i < avctx->channels; i++) for (n = 0; n < 16; n++) table[i][n] = sign_extend(bytestream2_get_be16u(&gb), 16); /* Initialize the previous sample. */ - for (i = 0; i < 2; i++) - for (n = 0; n < 2; n++) - prev[i][n] = sign_extend(bytestream2_get_be16u(&gb), 16); + for (i = 0; i < avctx->channels; i++) { + c->status[i].sample1 = sign_extend(bytestream2_get_be16u(&gb), 16); + c->status[i].sample2 = sign_extend(bytestream2_get_be16u(&gb), 16); + } - for (ch = 0; ch <= st; ch++) { + for (ch = 0; ch < avctx->channels; ch++) { samples = samples_p[ch]; /* Read in every sample for this channel. */ @@ -1263,11 +1358,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, sampledat = sign_extend(byte >> 4, 4); } - sampledat = ((prev[ch][0]*factor1 - + prev[ch][1]*factor2) >> 11) + (sampledat << exp); + sampledat = ((c->status[ch].sample1 * factor1 + + c->status[ch].sample2 * factor2) >> 11) + (sampledat << exp); *samples = av_clip_int16(sampledat); - prev[ch][1] = prev[ch][0]; - prev[ch][0] = *samples++; + c->status[ch].sample2 = c->status[ch].sample1; + c->status[ch].sample1 = *samples++; } } } @@ -1278,6 +1373,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, return -1; } + if (avpkt->size && bytestream2_tell(&gb) == 0) { + av_log(avctx, AV_LOG_ERROR, "Nothing consumed\n"); + return AVERROR_INVALIDDATA; + } + *got_frame_ptr = 1; *(AVFrame *)data = c->frame; @@ -1308,6 +1408,7 @@ AVCodec ff_ ## name_ ## _decoder = { \ /* Note: Do not forget to add new entries to the Makefile as well. */ ADPCM_DECODER(AV_CODEC_ID_ADPCM_4XM, sample_fmts_s16p, adpcm_4xm, "ADPCM 4X Movie"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_AFC, sample_fmts_s16p, adpcm_afc, "ADPCM Nintendo Gamecube AFC"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_CT, sample_fmts_s16, adpcm_ct, "ADPCM Creative Technology"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA, sample_fmts_s16, adpcm_ea, "ADPCM Electronic Arts"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_MAXIS_XA, sample_fmts_s16, adpcm_ea_maxis_xa, "ADPCM Electronic Arts Maxis CDROM XA"); @@ -1322,6 +1423,7 @@ ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_DK4, sample_fmts_s16, adpcm_ima_dk4, ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_EA_EACS, sample_fmts_s16, adpcm_ima_ea_eacs, "ADPCM IMA Electronic Arts EACS"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_EA_SEAD, sample_fmts_s16, adpcm_ima_ea_sead, "ADPCM IMA Electronic Arts SEAD"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_ISS, sample_fmts_s16, adpcm_ima_iss, "ADPCM IMA Funcom ISS"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_OKI, sample_fmts_s16, adpcm_ima_oki, "ADPCM IMA Dialogic OKI"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_QT, sample_fmts_s16p, adpcm_ima_qt, "ADPCM IMA QuickTime"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_SMJPEG, sample_fmts_s16, adpcm_ima_smjpeg, "ADPCM IMA Loki SDL MJPEG"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WAV, sample_fmts_s16p, adpcm_ima_wav, "ADPCM IMA WAV"); |