avcodec: add derf dpcm decoder
authorPaul B Mahol <onemda@gmail.com>
Sun, 15 Mar 2020 10:03:27 +0000 (11:03 +0100)
committerPaul B Mahol <onemda@gmail.com>
Tue, 17 Mar 2020 15:05:15 +0000 (16:05 +0100)
Changelog
libavcodec/Makefile
libavcodec/allcodecs.c
libavcodec/avcodec.h
libavcodec/codec_desc.c
libavcodec/dpcm.c
libavcodec/utils.c

index 219afbd..2bd1181 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -50,6 +50,7 @@ version <next>:
 - avgblur_vulkan, overlay_vulkan, scale_vulkan and chromaber_vulkan filters
 - ADPCM IMA MTF decoder
 - FWSE demuxer
+- DERF DPCM decoder
 
 
 version 4.2:
index b50a269..a88643b 100644 (file)
@@ -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
index 379c5f7..6046b15 100644 (file)
@@ -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;
index 9ac97a1..e9c658f 100644 (file)
@@ -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,
index df36717..130e08c 100644 (file)
@@ -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 */
     {
index 5958081..069bf1d 100644 (file)
@@ -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");
index c4dc136..66bfdaf 100644 (file)
@@ -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: