diff mbox series

[FFmpeg-devel,3/5] avcodec: add derf dpcm decoder

Message ID 20200315103748.2849-3-onemda@gmail.com
State Superseded
Headers show
Series [FFmpeg-devel,1/5] avcodec: add ADPCM IMA MTF decoder
Related show

Checks

Context Check Description
andriy/ffmpeg-patchwork pending
andriy/ffmpeg-patchwork success Applied patch
andriy/ffmpeg-patchwork success Configure finished
andriy/ffmpeg-patchwork success Make finished
andriy/ffmpeg-patchwork success Make fate finished

Commit Message

Paul B Mahol March 15, 2020, 10:37 a.m. UTC
Signed-off-by: Paul B Mahol <onemda@gmail.com>
---
 libavcodec/Makefile     |  1 +
 libavcodec/allcodecs.c  |  1 +
 libavcodec/avcodec.h    |  1 +
 libavcodec/codec_desc.c |  7 +++++++
 libavcodec/dpcm.c       | 32 ++++++++++++++++++++++++++++++++
 libavcodec/utils.c      |  1 +
 6 files changed, 43 insertions(+)
diff mbox series

Patch

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index b50a26907f..a88643b7d2 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -265,6 +265,7 @@  OBJS-$(CONFIG_DCA_DECODER)             += dcadec.o dca.o dcadata.o dcahuff.o \
 OBJS-$(CONFIG_DCA_ENCODER)             += dcaenc.o dca.o dcadata.o dcahuff.o \
                                           dcaadpcm.o
 OBJS-$(CONFIG_DDS_DECODER)             += dds.o
+OBJS-$(CONFIG_DERF_DPCM_DECODER)       += dpcm.o
 OBJS-$(CONFIG_DIRAC_DECODER)           += diracdec.o dirac.o diracdsp.o diractab.o \
                                           dirac_arith.o dirac_dwt.o dirac_vlc.o
 OBJS-$(CONFIG_DFA_DECODER)             += dfa.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 379c5f7b81..6046b15164 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -569,6 +569,7 @@  extern AVCodec ff_pcm_vidc_encoder;
 extern AVCodec ff_pcm_vidc_decoder;
 
 /* DPCM codecs */
+extern AVCodec ff_derf_dpcm_decoder;
 extern AVCodec ff_gremlin_dpcm_decoder;
 extern AVCodec ff_interplay_dpcm_decoder;
 extern AVCodec ff_roq_dpcm_encoder;
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 9ac97a122b..e9c658fddc 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -571,6 +571,7 @@  enum AVCodecID {
 
     AV_CODEC_ID_SDX2_DPCM = 0x14800,
     AV_CODEC_ID_GREMLIN_DPCM,
+    AV_CODEC_ID_DERF_DPCM,
 
     /* audio codecs */
     AV_CODEC_ID_MP2 = 0x15000,
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index df3671765a..130e08c1f2 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -2415,6 +2415,13 @@  static const AVCodecDescriptor codec_descriptors[] = {
         .long_name = NULL_IF_CONFIG_SMALL("DPCM Gremlin"),
         .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
     },
+    {
+        .id        = AV_CODEC_ID_DERF_DPCM,
+        .type      = AVMEDIA_TYPE_AUDIO,
+        .name      = "derf_dpcm",
+        .long_name = NULL_IF_CONFIG_SMALL("DPCM Xilam DERF"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+    },
 
     /* audio codecs */
     {
diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c
index 5958081b66..069bf1dcd8 100644
--- a/libavcodec/dpcm.c
+++ b/libavcodec/dpcm.c
@@ -49,6 +49,21 @@  typedef struct DPCMContext {
     const int8_t *sol_table;        ///< delta table for SOL_DPCM
 } DPCMContext;
 
+static const int32_t derf_steps[96] = {
+    0, 1, 2, 3, 4, 5, 6, 7,
+    8, 9, 10, 11, 12, 13, 14, 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,
+    1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327,
+    3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132,
+    7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289,
+    16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767,
+};
+
 static const int16_t interplay_delta_table[] = {
          0,      1,      2,      3,      4,      5,      6,      7,
          8,      9,     10,     11,     12,     13,     14,     15,
@@ -225,6 +240,7 @@  static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
         else
             out = buf_size;
         break;
+    case AV_CODEC_ID_DERF_DPCM:
     case AV_CODEC_ID_GREMLIN_DPCM:
     case AV_CODEC_ID_SDX2_DPCM:
         out = buf_size;
@@ -372,6 +388,21 @@  static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
         }
         }
         break;
+
+    case AV_CODEC_ID_DERF_DPCM: {
+        int idx = 0;
+
+        while (output_samples < samples_end) {
+            uint8_t n = bytestream2_get_byteu(&gb);
+            int index = FFMIN(n & 0x7f, 95);
+
+            s->sample[idx] += (n & 0x80 ? -1: 1) * derf_steps[index];
+            s->sample[idx]  = av_clip_int16(s->sample[idx]);
+            *output_samples++ = s->sample[idx];
+            idx ^= stereo;
+        }
+        }
+        break;
     }
 
     *got_frame_ptr = 1;
@@ -391,6 +422,7 @@  AVCodec ff_ ## name_ ## _decoder = {                        \
     .capabilities   = AV_CODEC_CAP_DR1,                     \
 }
 
+DPCM_DECODER(AV_CODEC_ID_DERF_DPCM,      derf_dpcm,      "DPCM Xilam DERF");
 DPCM_DECODER(AV_CODEC_ID_GREMLIN_DPCM,   gremlin_dpcm,   "DPCM Gremlin");
 DPCM_DECODER(AV_CODEC_ID_INTERPLAY_DPCM, interplay_dpcm, "DPCM Interplay");
 DPCM_DECODER(AV_CODEC_ID_ROQ_DPCM,       roq_dpcm,       "DPCM id RoQ");
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index c4dc136d3c..66bfdaf4f8 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -1478,6 +1478,7 @@  int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
     case AV_CODEC_ID_PCM_S8_PLANAR:
     case AV_CODEC_ID_PCM_U8:
     case AV_CODEC_ID_SDX2_DPCM:
+    case AV_CODEC_ID_DERF_DPCM:
         return 8;
     case AV_CODEC_ID_PCM_S16BE:
     case AV_CODEC_ID_PCM_S16BE_PLANAR: