diff options
author | Paul B Mahol <onemda@gmail.com> | 2020-03-14 11:55:58 +0100 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2020-03-17 16:03:39 +0100 |
commit | 230703a9fa48a93b7ec54903584e9ec9c947eefc (patch) | |
tree | 0dab383dc4c4789a560a10823e165357be7cc41b /libavcodec/adpcm.c | |
parent | c149f16db14a82bbbd95482060403dde823af184 (diff) | |
download | ffmpeg-230703a9fa48a93b7ec54903584e9ec9c947eefc.tar.gz |
avcodec: add ADPCM IMA MTF decoder
Diffstat (limited to 'libavcodec/adpcm.c')
-rw-r--r-- | libavcodec/adpcm.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 4f5980f7d5..e9abddc43c 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -89,6 +89,11 @@ static const int8_t zork_index_table[8] = { -1, -1, -1, 1, 4, 7, 10, 12, }; +static const int8_t mtf_index_table[16] = { + 8, 6, 4, 2, -1, -1, -1, -1, + -1, -1, -1, -1, 2, 4, 6, 8, +}; + /* end of tables */ typedef struct ADPCMDecodeContext { @@ -304,6 +309,22 @@ static inline int16_t adpcm_ima_alp_expand_nibble(ADPCMChannelStatus *c, int8_t return (int16_t)c->predictor; } +static inline int16_t adpcm_ima_mtf_expand_nibble(ADPCMChannelStatus *c, int nibble) +{ + int step_index, step, delta, predictor; + + step = ff_adpcm_step_table[c->step_index]; + + delta = step * (2 * nibble - 15); + predictor = c->predictor + delta; + + step_index = c->step_index + mtf_index_table[(unsigned)nibble]; + c->predictor = av_clip_int16(predictor >> 4); + c->step_index = av_clip(step_index, 0, 88); + + return (int16_t)c->predictor; +} + static inline int16_t adpcm_ima_wav_expand_nibble(ADPCMChannelStatus *c, GetBitContext *gb, int bps) { int nibble, step_index, predictor, sign, delta, diff, step, shift; @@ -700,6 +721,7 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, case AV_CODEC_ID_ADPCM_IMA_SSI: case AV_CODEC_ID_ADPCM_IMA_APM: case AV_CODEC_ID_ADPCM_IMA_ALP: + case AV_CODEC_ID_ADPCM_IMA_MTF: nb_samples = buf_size * 2 / ch; break; } @@ -1956,6 +1978,16 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, *samples++ = adpcm_zork_expand_nibble(&c->status[n % avctx->channels], v); } break; + case AV_CODEC_ID_ADPCM_IMA_MTF: + for (n = nb_samples / 2; n > 0; n--) { + for (channel = 0; channel < avctx->channels; channel++) { + int v = bytestream2_get_byteu(&gb); + *samples++ = adpcm_ima_mtf_expand_nibble(&c->status[channel], v >> 4); + samples[st] = adpcm_ima_mtf_expand_nibble(&c->status[channel], v & 0x0F); + } + samples += avctx->channels; + } + break; default: av_assert0(0); // unsupported codec_id should not happen } @@ -2027,6 +2059,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_MTF, sample_fmts_s16, adpcm_ima_mtf, "ADPCM IMA Capcom's MT Framework"); 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_RAD, sample_fmts_s16, adpcm_ima_rad, "ADPCM IMA Radical"); |