diff mbox series

[FFmpeg-devel,v3,1/2] avcodec: add decoder for High Voltage Software's ALP ADPCM

Message ID 20200308120827.26912-2-zane@zanevaniperen.com
State Accepted
Headers show
Series High Voltage Software ALP demuxer + decoder. | expand

Checks

Context Check Description
andriy/ffmpeg-patchwork success Make fate finished

Commit Message

Zane van Iperen March 8, 2020, 12:09 p.m. UTC
Signed-off-by: Zane van Iperen <zane@zanevaniperen.com>
---
 Changelog               |  1 +
 doc/general.texi        |  1 +
 libavcodec/Makefile     |  1 +
 libavcodec/adpcm.c      | 36 ++++++++++++++++++++++++++++++++++++
 libavcodec/allcodecs.c  |  1 +
 libavcodec/avcodec.h    |  1 +
 libavcodec/codec_desc.c |  7 +++++++
 libavcodec/version.h    |  4 ++--
 8 files changed, 50 insertions(+), 2 deletions(-)

Comments

Paul B Mahol March 8, 2020, 2:32 p.m. UTC | #1
lgtm

On 3/8/20, Zane van Iperen <zane@zanevaniperen.com> wrote:
> Signed-off-by: Zane van Iperen <zane@zanevaniperen.com>
> ---
>  Changelog               |  1 +
>  doc/general.texi        |  1 +
>  libavcodec/Makefile     |  1 +
>  libavcodec/adpcm.c      | 36 ++++++++++++++++++++++++++++++++++++
>  libavcodec/allcodecs.c  |  1 +
>  libavcodec/avcodec.h    |  1 +
>  libavcodec/codec_desc.c |  7 +++++++
>  libavcodec/version.h    |  4 ++--
>  8 files changed, 50 insertions(+), 2 deletions(-)
>
> diff --git a/Changelog b/Changelog
> index cb310a3abc..a962657b85 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -43,6 +43,7 @@ version <next>:
>  - Rayman 2 ADPCM decoder
>  - Rayman 2 APM demuxer
>  - cas video filter
> +- High Voltage Software ADPCM decoder
>
>
>  version 4.2:
> diff --git a/doc/general.texi b/doc/general.texi
> index dbdc348598..87eaad7791 100644
> --- a/doc/general.texi
> +++ b/doc/general.texi
> @@ -1100,6 +1100,7 @@ following image formats are supported:
>  @item ADPCM IMA Electronic Arts EACS  @tab     @tab  X
>  @item ADPCM IMA Electronic Arts SEAD  @tab     @tab  X
>  @item ADPCM IMA Funcom       @tab     @tab  X
> +@item ADPCM IMA High Voltage Software ALP   @tab     @tab  X
>  @item ADPCM IMA QuickTime    @tab  X  @tab  X
>  @item ADPCM IMA Simon & Schuster Interactive   @tab  @tab  X
>  @item ADPCM IMA Ubisoft APM  @tab     @tab X
> 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@zanevaniperen.com)
>   * Simon & Schuster Interactive ADPCM decoder by Zane van Iperen
> (zane@zanevaniperen.com)
>   * Ubisoft ADPCM decoder by Zane van Iperen (zane@zanevaniperen.com)
> + * High Voltage Software ALP decoder by Zane van Iperen
> (zane@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
>
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Michael Niedermayer March 8, 2020, 11:52 p.m. UTC | #2
On Sun, Mar 08, 2020 at 03:32:25PM +0100, Paul B Mahol wrote:
> lgtm

will apply

thx

[...]
diff mbox series

Patch

diff --git a/Changelog b/Changelog
index cb310a3abc..a962657b85 100644
--- a/Changelog
+++ b/Changelog
@@ -43,6 +43,7 @@  version <next>:
 - Rayman 2 ADPCM decoder
 - Rayman 2 APM demuxer
 - cas video filter
+- High Voltage Software ADPCM decoder
 
 
 version 4.2:
diff --git a/doc/general.texi b/doc/general.texi
index dbdc348598..87eaad7791 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -1100,6 +1100,7 @@  following image formats are supported:
 @item ADPCM IMA Electronic Arts EACS  @tab     @tab  X
 @item ADPCM IMA Electronic Arts SEAD  @tab     @tab  X
 @item ADPCM IMA Funcom       @tab     @tab  X
+@item ADPCM IMA High Voltage Software ALP   @tab     @tab  X
 @item ADPCM IMA QuickTime    @tab  X  @tab  X
 @item ADPCM IMA Simon & Schuster Interactive   @tab  @tab  X
 @item ADPCM IMA Ubisoft APM  @tab     @tab X
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@zanevaniperen.com)
  * Simon & Schuster Interactive ADPCM decoder by Zane van Iperen (zane@zanevaniperen.com)
  * Ubisoft ADPCM decoder by Zane van Iperen (zane@zanevaniperen.com)
+ * High Voltage Software ALP decoder by Zane van Iperen (zane@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, \