]> git.sesse.net Git - ffmpeg/commitdiff
avcodec: add ADPCM IMA MOFLEX decoder
authorPaul B Mahol <onemda@gmail.com>
Mon, 24 Aug 2020 22:51:11 +0000 (00:51 +0200)
committerPaul B Mahol <onemda@gmail.com>
Thu, 3 Sep 2020 16:06:50 +0000 (18:06 +0200)
Changelog
libavcodec/Makefile
libavcodec/adpcm.c
libavcodec/allcodecs.c
libavcodec/codec_desc.c
libavcodec/codec_id.h
libavcodec/utils.c
libavcodec/version.h

index 7467e733067c2f37a7c8e38647ee32b614248acb..d39063d59f600c7f169e5bcb33d7f15e37418918 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -15,6 +15,7 @@ version <next>:
 - Argonaut Games ASF muxer
 - AV1 Low overhead bitstream format demuxer
 - RPZA video encoder
+- ADPCM IMA MOFLEX decoder
 
 
 version 4.3:
index ca2e8a2530d1f372f5b85a880ba0a798e0c99d41..191c4e0a7c8df9f067b70813e00438b7758180e0 100644 (file)
@@ -866,6 +866,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_MOFLEX_DECODER)   += adpcm.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_IMA_MTF_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
index 1366932352be4104b67acf530a59afbfc5dc4570..71e37efde74daabbf48940df3014aa96f577285f 100644 (file)
@@ -210,6 +210,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx)
     case AV_CODEC_ID_ADPCM_PSX:
     case AV_CODEC_ID_ADPCM_MTAF:
     case AV_CODEC_ID_ADPCM_ARGO:
+    case AV_CODEC_ID_ADPCM_IMA_MOFLEX:
         avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
         break;
     case AV_CODEC_ID_ADPCM_IMA_WS:
@@ -774,6 +775,7 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
         case AV_CODEC_ID_ADPCM_4XM:
         case AV_CODEC_ID_ADPCM_AGM:
         case AV_CODEC_ID_ADPCM_IMA_DAT4:
+        case AV_CODEC_ID_ADPCM_IMA_MOFLEX:
         case AV_CODEC_ID_ADPCM_IMA_ISS:     header_size = 4 * ch;      break;
         case AV_CODEC_ID_ADPCM_IMA_AMV:     header_size = 8;           break;
         case AV_CODEC_ID_ADPCM_IMA_SMJPEG:  header_size = 4 * ch;      break;
@@ -1298,6 +1300,29 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
             *samples++ = adpcm_ima_expand_nibble(&c->status[st], v2, 3);
         }
         break;
+    case AV_CODEC_ID_ADPCM_IMA_MOFLEX:
+        for (channel = 0; channel < avctx->channels; channel++) {
+            cs = &c->status[channel];
+            cs->step_index = sign_extend(bytestream2_get_le16u(&gb), 16);
+            cs->predictor  = sign_extend(bytestream2_get_le16u(&gb), 16);
+            if (cs->step_index > 88u){
+                av_log(avctx, AV_LOG_ERROR, "ERROR: step_index[%d] = %i\n",
+                       channel, cs->step_index);
+                return AVERROR_INVALIDDATA;
+            }
+        }
+
+        for (int subframe = 0; subframe < nb_samples / 256; subframe++) {
+            for (channel = 0; channel < avctx->channels; channel++) {
+                samples = samples_p[channel] + 256 * subframe;
+                for (n = 0; n < 256; n += 2) {
+                    int v = bytestream2_get_byteu(&gb);
+                    *samples++ = adpcm_ima_expand_nibble(&c->status[channel], v & 0x0F, 3);
+                    *samples++ = adpcm_ima_expand_nibble(&c->status[channel], v >> 4  , 3);
+                }
+            }
+        }
+        break;
     case AV_CODEC_ID_ADPCM_IMA_DAT4:
         for (channel = 0; channel < avctx->channels; channel++) {
             cs = &c->status[channel];
@@ -2107,6 +2132,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_MOFLEX,  sample_fmts_s16p, adpcm_ima_moflex,  "ADPCM IMA MobiClip MOFLEX");
 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");
index 729d2fd9ad91e2c9b6134e22562fe631a7c58ea4..084a289c9eeebfd4602bbd6f9c6082e267cf2688 100644 (file)
@@ -619,6 +619,7 @@ extern AVCodec ff_adpcm_ima_dk4_decoder;
 extern AVCodec ff_adpcm_ima_ea_eacs_decoder;
 extern AVCodec ff_adpcm_ima_ea_sead_decoder;
 extern AVCodec ff_adpcm_ima_iss_decoder;
+extern AVCodec ff_adpcm_ima_moflex_decoder;
 extern AVCodec ff_adpcm_ima_mtf_decoder;
 extern AVCodec ff_adpcm_ima_oki_decoder;
 extern AVCodec ff_adpcm_ima_qt_encoder;
index 0ae6aee63bc9eaad49c0ae4a4d94f8b303976eb0..b5bc5c3c715e584f6fed3bb7e7ed7fe8444b1749 100644 (file)
@@ -2376,6 +2376,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
         .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Cunning Developments"),
         .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
     },
+    {
+        .id        = AV_CODEC_ID_ADPCM_IMA_MOFLEX,
+        .type      = AVMEDIA_TYPE_AUDIO,
+        .name      = "adpcm_ima_moflex",
+        .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA MobiClip MOFLEX"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+    },
 
     /* AMR */
     {
index 896ecb0ce04f63085ced66885772fce4729e9488..aac1174f283eefbf299d3d996ed849472d0c0274 100644 (file)
@@ -388,6 +388,7 @@ enum AVCodecID {
     AV_CODEC_ID_ADPCM_IMA_ALP,
     AV_CODEC_ID_ADPCM_IMA_MTF,
     AV_CODEC_ID_ADPCM_IMA_CUNNING,
+    AV_CODEC_ID_ADPCM_IMA_MOFLEX,
 
     /* AMR */
     AV_CODEC_ID_AMR_NB = 0x12000,
index 14cb5cf1aad393284a88ab2a55f43d7c2fe11498..187ce230b8d20bc95698faa5762a4d43ead938de 100644 (file)
@@ -1664,6 +1664,8 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba,
         if (ch > 0 && ch < INT_MAX/16) {
             /* calc from frame_bytes and channels */
             switch (id) {
+            case AV_CODEC_ID_ADPCM_IMA_MOFLEX:
+                return (frame_bytes - 4 * ch) / (128 * ch) * 256;
             case AV_CODEC_ID_ADPCM_AFC:
                 return frame_bytes / (9 * ch) * 16;
             case AV_CODEC_ID_ADPCM_PSX:
index 91e0564570a5acff8e81e9f1231a61679264934f..739caf5c6e460f355fe60b0e8b816da4efa267c2 100644 (file)
@@ -28,8 +28,8 @@
 #include "libavutil/version.h"
 
 #define LIBAVCODEC_VERSION_MAJOR  58
-#define LIBAVCODEC_VERSION_MINOR 101
-#define LIBAVCODEC_VERSION_MICRO 101
+#define LIBAVCODEC_VERSION_MINOR 102
+#define LIBAVCODEC_VERSION_MICRO 100
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
                                                LIBAVCODEC_VERSION_MINOR, \