diff mbox series

[FFmpeg-devel] avcodec: add ADPCM IMA Ubisoft decoder

Message ID 20211228053734.151556-1-zane@zanevaniperen.com
State New
Headers show
Series [FFmpeg-devel] avcodec: add ADPCM IMA Ubisoft decoder | expand

Checks

Context Check Description
yinshiyou/configure_loongarch64 warning Failed to run configure
yinshiyou/make_loongarch64 fail Make failed
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished
andriy/make_ppc success Make finished
andriy/make_fate_ppc fail Make fate failed

Commit Message

Zane van Iperen Dec. 28, 2021, 5:37 a.m. UTC
A simple, interleaved variant, but with initial state and
extra, uncompressed samples. Found in Ubisoft soundbanks from
early-2000's games (Splinter Cell, RS3, etc.)

Signed-off-by: Zane van Iperen <zane@zanevaniperen.com>
---
 Changelog                 |  1 +
 doc/general_contents.texi |  1 +
 libavcodec/Makefile       |  1 +
 libavcodec/adpcm.c        | 69 +++++++++++++++++++++++++++++++++++++++
 libavcodec/allcodecs.c    |  1 +
 libavcodec/codec_desc.c   |  7 ++++
 libavcodec/codec_id.h     |  1 +
 7 files changed, 81 insertions(+)

Comments

Zane van Iperen Dec. 31, 2021, 7:09 a.m. UTC | #1
Ping. Will apply (with the minor version bump I forgot) in a few days.

On 28/12/21 15:37, Zane van Iperen wrote:
> A simple, interleaved variant, but with initial state and
> extra, uncompressed samples. Found in Ubisoft soundbanks from
> early-2000's games (Splinter Cell, RS3, etc.)
> 
> Signed-off-by: Zane van Iperen <zane@zanevaniperen.com>
> ---
>   Changelog                 |  1 +
>   doc/general_contents.texi |  1 +
>   libavcodec/Makefile       |  1 +
>   libavcodec/adpcm.c        | 69 +++++++++++++++++++++++++++++++++++++++
>   libavcodec/allcodecs.c    |  1 +
>   libavcodec/codec_desc.c   |  7 ++++
>   libavcodec/codec_id.h     |  1 +
>   7 files changed, 81 insertions(+)
> 
> diff --git a/Changelog b/Changelog
> index edb4152d0f..58be0b9da5 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -44,6 +44,7 @@ version <next>:
>   - yadif_videotoolbox filter
>   - VideoToolbox ProRes encoder
>   - anlmf audio filter
> +- ADPCM IMA Ubisoft decoder
>   
>   
>   version 4.4:
> diff --git a/doc/general_contents.texi b/doc/general_contents.texi
> index df1692c8df..80506e8ab4 100644
> --- a/doc/general_contents.texi
> +++ b/doc/general_contents.texi
> @@ -1139,6 +1139,7 @@ following image formats are supported:
>   @item ADPCM IMA High Voltage Software ALP      @tab  X  @tab  X
>   @item ADPCM IMA QuickTime    @tab  X  @tab  X
>   @item ADPCM IMA Simon & Schuster Interactive   @tab  X  @tab  X
> +@item ADPCM IMA Ubisoft      @tab     @tab  X
>   @item ADPCM IMA Ubisoft APM  @tab  X  @tab  X
>   @item ADPCM IMA Loki SDL MJPEG  @tab     @tab  X
>   @item ADPCM IMA WAV          @tab  X  @tab  X
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index 9577062eec..52839e1994 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -899,6 +899,7 @@ OBJS-$(CONFIG_ADPCM_IMA_RAD_DECODER)      += adpcm.o adpcm_data.o
>   OBJS-$(CONFIG_ADPCM_IMA_SSI_DECODER)      += adpcm.o adpcm_data.o
>   OBJS-$(CONFIG_ADPCM_IMA_SSI_ENCODER)      += adpcmenc.o adpcm_data.o
>   OBJS-$(CONFIG_ADPCM_IMA_SMJPEG_DECODER)   += adpcm.o adpcm_data.o
> +OBJS-$(CONFIG_ADPCM_IMA_UBISOFT_DECODER)  += adpcm.o adpcm_data.o
>   OBJS-$(CONFIG_ADPCM_IMA_WAV_DECODER)      += adpcm.o adpcm_data.o
>   OBJS-$(CONFIG_ADPCM_IMA_WAV_ENCODER)      += adpcmenc.o adpcm_data.o
>   OBJS-$(CONFIG_ADPCM_IMA_WS_DECODER)       += adpcm.o adpcm_data.o
> diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
> index cfde5f58b9..410fea8e21 100644
> --- a/libavcodec/adpcm.c
> +++ b/libavcodec/adpcm.c
> @@ -239,6 +239,7 @@ static const int8_t mtf_index_table[16] = {
>   typedef struct ADPCMDecodeContext {
>       ADPCMChannelStatus status[14];
>       int vqa_version;                /**< VQA version. Used for ADPCM_IMA_WS */
> +    int extra_count;                /**< Number of raw PCM samples to send */
>       int has_status;                 /**< Status flag. Reset to 0 after a flush. */
>   } ADPCMDecodeContext;
>   
> @@ -301,6 +302,13 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx)
>           if (avctx->bits_per_coded_sample != 4 || avctx->block_align != 17 * avctx->channels)
>               return AVERROR_INVALIDDATA;
>           break;
> +    case AV_CODEC_ID_ADPCM_IMA_UBISOFT:
> +        if (c->extra_count < 0)
> +            return AVERROR_INVALIDDATA;
> +
> +        if (c->extra_count > 0 && c->extra_count % avctx->channels != 0)
> +            return AVERROR_INVALIDDATA;
> +        break;
>       case AV_CODEC_ID_ADPCM_ZORK:
>           if (avctx->bits_per_coded_sample != 8)
>               return AVERROR_INVALIDDATA;
> @@ -877,6 +885,10 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
>       case AV_CODEC_ID_ADPCM_IMA_MTF:
>           nb_samples = buf_size * 2 / ch;
>           break;
> +    /* simple 4-bit adpcm, with extra uncompressed samples */
> +    case AV_CODEC_ID_ADPCM_IMA_UBISOFT:
> +        nb_samples = (buf_size * 2 + s->extra_count) / ch;
> +        break;
>       }
>       if (nb_samples)
>           return nb_samples;
> @@ -1460,6 +1472,35 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
>               *samples++ = adpcm_ima_qt_expand_nibble(&c->status[st], v & 0x0F);
>           }
>           ) /* End of CASE */
> +    CASE(ADPCM_IMA_UBISOFT,
> +        if (c->extra_count) {
> +            int offset = avctx->extradata[0] == 6 ? 36 : 28;
> +            nb_samples -= c->extra_count / avctx->channels;
> +
> +            for (uint8_t *extra = avctx->extradata + offset; c->extra_count--; extra += 2) {
> +                if (avctx->extradata[0] == 3)
> +                    *samples++ = AV_RB16(extra);
> +                else
> +                    *samples++ = AV_RL16(extra);
> +            }
> +
> +            /* NB: This is enforced above. */
> +            if (avctx->channels == 1) {
> +                c->status[0].predictor = samples[-1];
> +            } else {
> +                c->status[0].predictor = samples[-2];
> +                c->status[1].predictor = samples[-1];
> +            }
> +
> +            c->extra_count = 0;
> +        }
> +
> +        for (int n = nb_samples >> (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);
> +        }
> +        ) /* End of CASE */
>       CASE(ADPCM_IMA_APM,
>           for (int n = nb_samples / 2; n > 0; n--) {
>               for (int channel = 0; channel < avctx->channels; channel++) {
> @@ -2257,6 +2298,33 @@ static void adpcm_flush(AVCodecContext *avctx)
>           if (avctx->extradata && avctx->extradata_size >= 2)
>               c->vqa_version = AV_RL16(avctx->extradata);
>           break;
> +
> +    case AV_CODEC_ID_ADPCM_IMA_UBISOFT: {
> +        if (avctx->extradata && avctx->extradata_size >= 28) {
> +            uint8_t  version = avctx->extradata[0];
> +            uint32_t sample_offset = version == 6 ? 36 : 28;
> +
> +            if (version == 3) {
> +                c->extra_count          = AV_RB16(avctx->extradata + 14);
> +                c->status[0].predictor  = AV_RB16(avctx->extradata + 16);
> +                c->status[1].predictor  = AV_RB16(avctx->extradata + 20);
> +            } else {
> +                c->extra_count          = AV_RL16(avctx->extradata + 14);
> +                c->status[0].predictor  = AV_RL16(avctx->extradata + 16);
> +                c->status[1].predictor  = AV_RL16(avctx->extradata + 20);
> +            }
> +
> +            c->status[0].step_index = av_clip(avctx->extradata[18], 0, 88);
> +            c->status[1].step_index = av_clip(avctx->extradata[22], 0, 88);
> +
> +            c->extra_count = FFMIN(
> +                c->extra_count,
> +                (avctx->extradata_size - sample_offset) / 2 / sizeof(int16_t)
> +            );
> +        }
> +        break;
> +    }
> +
>       default:
>           /* Other codecs may want to handle this during decoding. */
>           c->has_status = 0;
> @@ -2330,6 +2398,7 @@ ADPCM_DECODER(ADPCM_IMA_QT,      sample_fmts_s16p, adpcm_ima_qt,      "ADPCM IMA
>   ADPCM_DECODER(ADPCM_IMA_RAD,     sample_fmts_s16,  adpcm_ima_rad,     "ADPCM IMA Radical")
>   ADPCM_DECODER(ADPCM_IMA_SSI,     sample_fmts_s16,  adpcm_ima_ssi,     "ADPCM IMA Simon & Schuster Interactive")
>   ADPCM_DECODER(ADPCM_IMA_SMJPEG,  sample_fmts_s16,  adpcm_ima_smjpeg,  "ADPCM IMA Loki SDL MJPEG")
> +ADPCM_DECODER(ADPCM_IMA_UBISOFT, sample_fmts_s16,  adpcm_ima_ubisoft, "ADPCM IMA Ubisoft");
>   ADPCM_DECODER(ADPCM_IMA_ALP,     sample_fmts_s16,  adpcm_ima_alp,     "ADPCM IMA High Voltage Software ALP")
>   ADPCM_DECODER(ADPCM_IMA_WAV,     sample_fmts_s16p, adpcm_ima_wav,     "ADPCM IMA WAV")
>   ADPCM_DECODER(ADPCM_IMA_WS,      sample_fmts_both, adpcm_ima_ws,      "ADPCM IMA Westwood")
> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
> index d1e10197de..2a07888a8f 100644
> --- a/libavcodec/allcodecs.c
> +++ b/libavcodec/allcodecs.c
> @@ -652,6 +652,7 @@ extern const AVCodec ff_adpcm_ima_rad_decoder;
>   extern const AVCodec ff_adpcm_ima_ssi_decoder;
>   extern const AVCodec ff_adpcm_ima_ssi_encoder;
>   extern const AVCodec ff_adpcm_ima_smjpeg_decoder;
> +extern const AVCodec ff_adpcm_ima_ubisoft_decoder;
>   extern const AVCodec ff_adpcm_ima_wav_encoder;
>   extern const AVCodec ff_adpcm_ima_wav_decoder;
>   extern const AVCodec ff_adpcm_ima_ws_encoder;
> diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
> index 0974ee03de..a892d8f853 100644
> --- a/libavcodec/codec_desc.c
> +++ b/libavcodec/codec_desc.c
> @@ -2475,6 +2475,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
>           .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Acorn Replay"),
>           .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
>       },
> +    {
> +        .id        = AV_CODEC_ID_ADPCM_IMA_UBISOFT,
> +        .type      = AVMEDIA_TYPE_AUDIO,
> +        .name      = "adpcm_ima_ubisoft",
> +        .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Ubisoft"),
> +        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
> +    },
>   
>       /* AMR */
>       {
> diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
> index ab265ec584..d7b47f88ce 100644
> --- a/libavcodec/codec_id.h
> +++ b/libavcodec/codec_id.h
> @@ -401,6 +401,7 @@ enum AVCodecID {
>       AV_CODEC_ID_ADPCM_IMA_CUNNING,
>       AV_CODEC_ID_ADPCM_IMA_MOFLEX,
>       AV_CODEC_ID_ADPCM_IMA_ACORN,
> +    AV_CODEC_ID_ADPCM_IMA_UBISOFT,
>   
>       /* AMR */
>       AV_CODEC_ID_AMR_NB = 0x12000,
diff mbox series

Patch

diff --git a/Changelog b/Changelog
index edb4152d0f..58be0b9da5 100644
--- a/Changelog
+++ b/Changelog
@@ -44,6 +44,7 @@  version <next>:
 - yadif_videotoolbox filter
 - VideoToolbox ProRes encoder
 - anlmf audio filter
+- ADPCM IMA Ubisoft decoder
 
 
 version 4.4:
diff --git a/doc/general_contents.texi b/doc/general_contents.texi
index df1692c8df..80506e8ab4 100644
--- a/doc/general_contents.texi
+++ b/doc/general_contents.texi
@@ -1139,6 +1139,7 @@  following image formats are supported:
 @item ADPCM IMA High Voltage Software ALP      @tab  X  @tab  X
 @item ADPCM IMA QuickTime    @tab  X  @tab  X
 @item ADPCM IMA Simon & Schuster Interactive   @tab  X  @tab  X
+@item ADPCM IMA Ubisoft      @tab     @tab  X
 @item ADPCM IMA Ubisoft APM  @tab  X  @tab  X
 @item ADPCM IMA Loki SDL MJPEG  @tab     @tab  X
 @item ADPCM IMA WAV          @tab  X  @tab  X
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 9577062eec..52839e1994 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -899,6 +899,7 @@  OBJS-$(CONFIG_ADPCM_IMA_RAD_DECODER)      += adpcm.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_IMA_SSI_DECODER)      += adpcm.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_IMA_SSI_ENCODER)      += adpcmenc.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_IMA_SMJPEG_DECODER)   += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_UBISOFT_DECODER)  += adpcm.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_IMA_WAV_DECODER)      += adpcm.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_IMA_WAV_ENCODER)      += adpcmenc.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_IMA_WS_DECODER)       += adpcm.o adpcm_data.o
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index cfde5f58b9..410fea8e21 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -239,6 +239,7 @@  static const int8_t mtf_index_table[16] = {
 typedef struct ADPCMDecodeContext {
     ADPCMChannelStatus status[14];
     int vqa_version;                /**< VQA version. Used for ADPCM_IMA_WS */
+    int extra_count;                /**< Number of raw PCM samples to send */
     int has_status;                 /**< Status flag. Reset to 0 after a flush. */
 } ADPCMDecodeContext;
 
@@ -301,6 +302,13 @@  static av_cold int adpcm_decode_init(AVCodecContext * avctx)
         if (avctx->bits_per_coded_sample != 4 || avctx->block_align != 17 * avctx->channels)
             return AVERROR_INVALIDDATA;
         break;
+    case AV_CODEC_ID_ADPCM_IMA_UBISOFT:
+        if (c->extra_count < 0)
+            return AVERROR_INVALIDDATA;
+
+        if (c->extra_count > 0 && c->extra_count % avctx->channels != 0)
+            return AVERROR_INVALIDDATA;
+        break;
     case AV_CODEC_ID_ADPCM_ZORK:
         if (avctx->bits_per_coded_sample != 8)
             return AVERROR_INVALIDDATA;
@@ -877,6 +885,10 @@  static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
     case AV_CODEC_ID_ADPCM_IMA_MTF:
         nb_samples = buf_size * 2 / ch;
         break;
+    /* simple 4-bit adpcm, with extra uncompressed samples */
+    case AV_CODEC_ID_ADPCM_IMA_UBISOFT:
+        nb_samples = (buf_size * 2 + s->extra_count) / ch;
+        break;
     }
     if (nb_samples)
         return nb_samples;
@@ -1460,6 +1472,35 @@  static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
             *samples++ = adpcm_ima_qt_expand_nibble(&c->status[st], v & 0x0F);
         }
         ) /* End of CASE */
+    CASE(ADPCM_IMA_UBISOFT,
+        if (c->extra_count) {
+            int offset = avctx->extradata[0] == 6 ? 36 : 28;
+            nb_samples -= c->extra_count / avctx->channels;
+
+            for (uint8_t *extra = avctx->extradata + offset; c->extra_count--; extra += 2) {
+                if (avctx->extradata[0] == 3)
+                    *samples++ = AV_RB16(extra);
+                else
+                    *samples++ = AV_RL16(extra);
+            }
+
+            /* NB: This is enforced above. */
+            if (avctx->channels == 1) {
+                c->status[0].predictor = samples[-1];
+            } else {
+                c->status[0].predictor = samples[-2];
+                c->status[1].predictor = samples[-1];
+            }
+
+            c->extra_count = 0;
+        }
+
+        for (int n = nb_samples >> (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);
+        }
+        ) /* End of CASE */
     CASE(ADPCM_IMA_APM,
         for (int n = nb_samples / 2; n > 0; n--) {
             for (int channel = 0; channel < avctx->channels; channel++) {
@@ -2257,6 +2298,33 @@  static void adpcm_flush(AVCodecContext *avctx)
         if (avctx->extradata && avctx->extradata_size >= 2)
             c->vqa_version = AV_RL16(avctx->extradata);
         break;
+
+    case AV_CODEC_ID_ADPCM_IMA_UBISOFT: {
+        if (avctx->extradata && avctx->extradata_size >= 28) {
+            uint8_t  version = avctx->extradata[0];
+            uint32_t sample_offset = version == 6 ? 36 : 28;
+
+            if (version == 3) {
+                c->extra_count          = AV_RB16(avctx->extradata + 14);
+                c->status[0].predictor  = AV_RB16(avctx->extradata + 16);
+                c->status[1].predictor  = AV_RB16(avctx->extradata + 20);
+            } else {
+                c->extra_count          = AV_RL16(avctx->extradata + 14);
+                c->status[0].predictor  = AV_RL16(avctx->extradata + 16);
+                c->status[1].predictor  = AV_RL16(avctx->extradata + 20);
+            }
+
+            c->status[0].step_index = av_clip(avctx->extradata[18], 0, 88);
+            c->status[1].step_index = av_clip(avctx->extradata[22], 0, 88);
+
+            c->extra_count = FFMIN(
+                c->extra_count,
+                (avctx->extradata_size - sample_offset) / 2 / sizeof(int16_t)
+            );
+        }
+        break;
+    }
+
     default:
         /* Other codecs may want to handle this during decoding. */
         c->has_status = 0;
@@ -2330,6 +2398,7 @@  ADPCM_DECODER(ADPCM_IMA_QT,      sample_fmts_s16p, adpcm_ima_qt,      "ADPCM IMA
 ADPCM_DECODER(ADPCM_IMA_RAD,     sample_fmts_s16,  adpcm_ima_rad,     "ADPCM IMA Radical")
 ADPCM_DECODER(ADPCM_IMA_SSI,     sample_fmts_s16,  adpcm_ima_ssi,     "ADPCM IMA Simon & Schuster Interactive")
 ADPCM_DECODER(ADPCM_IMA_SMJPEG,  sample_fmts_s16,  adpcm_ima_smjpeg,  "ADPCM IMA Loki SDL MJPEG")
+ADPCM_DECODER(ADPCM_IMA_UBISOFT, sample_fmts_s16,  adpcm_ima_ubisoft, "ADPCM IMA Ubisoft");
 ADPCM_DECODER(ADPCM_IMA_ALP,     sample_fmts_s16,  adpcm_ima_alp,     "ADPCM IMA High Voltage Software ALP")
 ADPCM_DECODER(ADPCM_IMA_WAV,     sample_fmts_s16p, adpcm_ima_wav,     "ADPCM IMA WAV")
 ADPCM_DECODER(ADPCM_IMA_WS,      sample_fmts_both, adpcm_ima_ws,      "ADPCM IMA Westwood")
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index d1e10197de..2a07888a8f 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -652,6 +652,7 @@  extern const AVCodec ff_adpcm_ima_rad_decoder;
 extern const AVCodec ff_adpcm_ima_ssi_decoder;
 extern const AVCodec ff_adpcm_ima_ssi_encoder;
 extern const AVCodec ff_adpcm_ima_smjpeg_decoder;
+extern const AVCodec ff_adpcm_ima_ubisoft_decoder;
 extern const AVCodec ff_adpcm_ima_wav_encoder;
 extern const AVCodec ff_adpcm_ima_wav_decoder;
 extern const AVCodec ff_adpcm_ima_ws_encoder;
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 0974ee03de..a892d8f853 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -2475,6 +2475,13 @@  static const AVCodecDescriptor codec_descriptors[] = {
         .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Acorn Replay"),
         .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
     },
+    {
+        .id        = AV_CODEC_ID_ADPCM_IMA_UBISOFT,
+        .type      = AVMEDIA_TYPE_AUDIO,
+        .name      = "adpcm_ima_ubisoft",
+        .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Ubisoft"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+    },
 
     /* AMR */
     {
diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
index ab265ec584..d7b47f88ce 100644
--- a/libavcodec/codec_id.h
+++ b/libavcodec/codec_id.h
@@ -401,6 +401,7 @@  enum AVCodecID {
     AV_CODEC_ID_ADPCM_IMA_CUNNING,
     AV_CODEC_ID_ADPCM_IMA_MOFLEX,
     AV_CODEC_ID_ADPCM_IMA_ACORN,
+    AV_CODEC_ID_ADPCM_IMA_UBISOFT,
 
     /* AMR */
     AV_CODEC_ID_AMR_NB = 0x12000,