[FFmpeg-devel] [PATCH v2 1/4] avcodec: add decoder for High Voltage Software's ALP ADPCM
Zane van Iperen
zane at zanevaniperen.com
Sat Mar 7 16:15:44 EET 2020
Signed-off-by: Zane van Iperen <zane at zanevaniperen.com>
---
libavcodec/Makefile | 1 +
libavcodec/adpcm.c | 36 ++++++++++++++++++++++++++++++++++++
libavcodec/allcodecs.c | 1 +
libavcodec/avcodec.h | 1 +
libavcodec/codec_desc.c | 7 +++++++
libavcodec/version.h | 4 ++--
6 files changed, 48 insertions(+), 2 deletions(-)
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index f1c032b456..0fd374ffed 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -834,6 +834,7 @@ OBJS-$(CONFIG_ADPCM_G726_ENCODER) += g726.o
OBJS-$(CONFIG_ADPCM_G726LE_DECODER) += g726.o
OBJS-$(CONFIG_ADPCM_G726LE_ENCODER) += g726.o
OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_ALP_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_IMA_APC_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_IMA_APM_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_IMA_DAT4_DECODER) += adpcm.o adpcm_data.o
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index 5f152ee6ef..c69cac3379 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -15,6 +15,7 @@
* Argonaut Games ADPCM decoder by Zane van Iperen (zane at zanevaniperen.com)
* Simon & Schuster Interactive ADPCM decoder by Zane van Iperen (zane at zanevaniperen.com)
* Ubisoft ADPCM decoder by Zane van Iperen (zane at zanevaniperen.com)
+ * High Voltage Software ALP decoder by Zane van Iperen (zane at zanevaniperen.com)
*
* This file is part of FFmpeg.
*
@@ -280,6 +281,29 @@ static inline int16_t adpcm_ima_expand_nibble(ADPCMChannelStatus *c, int8_t nibb
return (int16_t)c->predictor;
}
+static inline int16_t adpcm_ima_alp_expand_nibble(ADPCMChannelStatus *c, int8_t nibble, int shift)
+{
+ int step_index;
+ int predictor;
+ int sign, delta, diff, step;
+
+ step = ff_adpcm_step_table[c->step_index];
+ step_index = c->step_index + ff_adpcm_index_table[(unsigned)nibble];
+ step_index = av_clip(step_index, 0, 88);
+
+ sign = nibble & 8;
+ delta = nibble & 7;
+ diff = (delta * step) >> shift;
+ predictor = c->predictor;
+ if (sign) predictor -= diff;
+ else predictor += diff;
+
+ c->predictor = av_clip_int16(predictor);
+ c->step_index = step_index;
+
+ 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;
@@ -675,6 +699,7 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
case AV_CODEC_ID_ADPCM_AICA:
case AV_CODEC_ID_ADPCM_IMA_SSI:
case AV_CODEC_ID_ADPCM_IMA_APM:
+ case AV_CODEC_ID_ADPCM_IMA_ALP:
nb_samples = buf_size * 2 / ch;
break;
}
@@ -1247,6 +1272,16 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
samples += avctx->channels;
}
break;
+ case AV_CODEC_ID_ADPCM_IMA_ALP:
+ for (n = nb_samples / 2; n > 0; n--) {
+ for (channel = 0; channel < avctx->channels; channel++) {
+ int v = bytestream2_get_byteu(&gb);
+ *samples++ = adpcm_ima_alp_expand_nibble(&c->status[channel], v >> 4 , 2);
+ samples[st] = adpcm_ima_alp_expand_nibble(&c->status[channel], v & 0x0F, 2);
+ }
+ samples += avctx->channels;
+ }
+ break;
case AV_CODEC_ID_ADPCM_IMA_OKI:
while (bytestream2_get_bytes_left(&gb) > 0) {
int v = bytestream2_get_byteu(&gb);
@@ -1997,6 +2032,7 @@ ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_QT, sample_fmts_s16p, adpcm_ima_qt,
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_RAD, sample_fmts_s16, adpcm_ima_rad, "ADPCM IMA Radical");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_SSI, sample_fmts_s16, adpcm_ima_ssi, "ADPCM IMA Simon & Schuster Interactive");
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_ALP, sample_fmts_s16, adpcm_ima_alp, "ADPCM IMA High Voltage Software ALP");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WAV, sample_fmts_s16p, adpcm_ima_wav, "ADPCM IMA WAV");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WS, sample_fmts_both, adpcm_ima_ws, "ADPCM IMA Westwood");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_MS, sample_fmts_both, adpcm_ms, "ADPCM Microsoft");
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 674995df72..f4cf180716 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -599,6 +599,7 @@ extern AVCodec ff_adpcm_g726_decoder;
extern AVCodec ff_adpcm_g726le_encoder;
extern AVCodec ff_adpcm_g726le_decoder;
extern AVCodec ff_adpcm_ima_amv_decoder;
+extern AVCodec ff_adpcm_ima_alp_decoder;
extern AVCodec ff_adpcm_ima_apc_decoder;
extern AVCodec ff_adpcm_ima_apm_decoder;
extern AVCodec ff_adpcm_ima_dat4_decoder;
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 5a0fc3405c..833642d692 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -552,6 +552,7 @@ enum AVCodecID {
AV_CODEC_ID_ADPCM_IMA_SSI,
AV_CODEC_ID_ADPCM_ZORK,
AV_CODEC_ID_ADPCM_IMA_APM,
+ AV_CODEC_ID_ADPCM_IMA_ALP,
/* AMR */
AV_CODEC_ID_AMR_NB = 0x12000,
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 52178e7afe..0f5ddd9a9f 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -2325,6 +2325,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Ubisoft APM"),
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
},
+ {
+ .id = AV_CODEC_ID_ADPCM_IMA_ALP,
+ .type = AVMEDIA_TYPE_AUDIO,
+ .name = "adpcm_ima_alp",
+ .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA High Voltage Software ALP"),
+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+ },
/* AMR */
{
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 36536c3725..c051ac0754 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -28,8 +28,8 @@
#include "libavutil/version.h"
#define LIBAVCODEC_VERSION_MAJOR 58
-#define LIBAVCODEC_VERSION_MINOR 73
-#define LIBAVCODEC_VERSION_MICRO 102
+#define LIBAVCODEC_VERSION_MINOR 74
+#define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \
--
2.17.1
More information about the ffmpeg-devel
mailing list