diff --git a/Changelog b/Changelog index bca5568761..622cc5a6ef 100644 --- a/Changelog +++ b/Changelog @@ -29,6 +29,7 @@ version : - BRender PIX image decoder - ffprobe -show_entries option - ffprobe -sections option +- ADPCM IMA Dialogic decoder version 1.0: diff --git a/doc/general.texi b/doc/general.texi index 4d145a7dc9..9e8c9ea605 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -749,6 +749,7 @@ following image formats are supported: @item ADPCM IMA Westwood @tab @tab X @item ADPCM ISS IMA @tab @tab X @tab Used in FunCom games. +@item ADPCM IMA Dialogic @tab @tab X @item ADPCM IMA Duck DK3 @tab @tab X @tab Used in some Sega Saturn console games. @item ADPCM IMA Duck DK4 @tab @tab X diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 8c5a7f3d5f..d8057117d4 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -585,6 +585,7 @@ OBJS-$(CONFIG_ADPCM_IMA_DK4_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_EA_EACS_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_EA_SEAD_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_ISS_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_OKI_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_QT_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_QT_ENCODER) += adpcmenc.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_SMJPEG_DECODER) += adpcm.o adpcm_data.o diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 0d2ef5c80f..d8bbdbb88e 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -229,6 +229,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; @@ -460,6 +481,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; @@ -877,6 +899,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++) { @@ -1371,6 +1400,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"); diff --git a/libavcodec/adpcm_data.c b/libavcodec/adpcm_data.c index fe116446dc..0625fc9464 100644 --- a/libavcodec/adpcm_data.c +++ b/libavcodec/adpcm_data.c @@ -49,6 +49,14 @@ const int16_t ff_adpcm_step_table[89] = { 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 }; +const int16_t ff_adpcm_oki_step_table[49] = { + 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, + 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, + 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, + 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, + 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552 +}; + /* These are for MS-ADPCM */ /* ff_adpcm_AdaptationTable[], ff_adpcm_AdaptCoeff1[], and ff_adpcm_AdaptCoeff2[] are from libsndfile */ diff --git a/libavcodec/adpcm_data.h b/libavcodec/adpcm_data.h index 24a6909c37..0ebb7c3f04 100644 --- a/libavcodec/adpcm_data.h +++ b/libavcodec/adpcm_data.h @@ -30,6 +30,7 @@ extern const int8_t ff_adpcm_index_table[16]; extern const int16_t ff_adpcm_step_table[89]; +extern const int16_t ff_adpcm_oki_step_table[49]; extern const int16_t ff_adpcm_AdaptationTable[]; extern const uint8_t ff_adpcm_AdaptCoeff1[]; extern const int8_t ff_adpcm_AdaptCoeff2[]; diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 4ce1cc6d26..4743bb1621 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -404,6 +404,7 @@ void avcodec_register_all(void) REGISTER_DECODER (ADPCM_IMA_EA_EACS, adpcm_ima_ea_eacs); REGISTER_DECODER (ADPCM_IMA_EA_SEAD, adpcm_ima_ea_sead); REGISTER_DECODER (ADPCM_IMA_ISS, adpcm_ima_iss); + REGISTER_DECODER (ADPCM_IMA_OKI, adpcm_ima_oki); REGISTER_ENCDEC (ADPCM_IMA_QT, adpcm_ima_qt); REGISTER_DECODER (ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg); REGISTER_ENCDEC (ADPCM_IMA_WAV, adpcm_ima_wav); diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 1e14b95947..d5fd38768c 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -353,6 +353,7 @@ enum AVCodecID { AV_CODEC_ID_ADPCM_IMA_APC, AV_CODEC_ID_VIMA = MKBETAG('V','I','M','A'), AV_CODEC_ID_ADPCM_AFC = MKBETAG('A','F','C',' '), + AV_CODEC_ID_ADPCM_IMA_OKI = MKBETAG('O','K','I',' '), /* AMR */ AV_CODEC_ID_AMR_NB = 0x12000, diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 262d91779e..b4b7c4afea 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -1763,6 +1763,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("ADPCM Nintendo Gamecube AFC"), .props = AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_ADPCM_IMA_OKI, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ima_oki", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Dialogic OKI"), + .props = AV_CODEC_PROP_LOSSY, + }, /* AMR */ { diff --git a/libavcodec/utils.c b/libavcodec/utils.c index b117271b40..4749d739d4 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -2300,6 +2300,7 @@ int av_get_exact_bits_per_sample(enum AVCodecID codec_id) 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_G722: case AV_CODEC_ID_ADPCM_YAMAHA: diff --git a/libavcodec/version.h b/libavcodec/version.h index 2beef77d93..b797aecf29 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #include "libavutil/avutil.h" #define LIBAVCODEC_VERSION_MAJOR 54 -#define LIBAVCODEC_VERSION_MINOR 76 +#define LIBAVCODEC_VERSION_MINOR 77 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ diff --git a/libavformat/riff.c b/libavformat/riff.c index 9a37760b41..bae7f8aea0 100644 --- a/libavformat/riff.c +++ b/libavformat/riff.c @@ -338,8 +338,10 @@ const AVCodecTag ff_codec_wav_tags[] = { { AV_CODEC_ID_PCM_ALAW, 0x0006 }, { AV_CODEC_ID_PCM_MULAW, 0x0007 }, { AV_CODEC_ID_WMAVOICE, 0x000A }, + { AV_CODEC_ID_ADPCM_IMA_OKI, 0x0010 }, { AV_CODEC_ID_ADPCM_IMA_WAV, 0x0011 }, { AV_CODEC_ID_PCM_ZORK, 0x0011 }, /* must come after adpcm_ima_wav in this list */ + { AV_CODEC_ID_ADPCM_IMA_OKI, 0x0017 }, { AV_CODEC_ID_ADPCM_YAMAHA, 0x0020 }, { AV_CODEC_ID_TRUESPEECH, 0x0022 }, { AV_CODEC_ID_GSM_MS, 0x0031 },