Browse code

ADPCM IMA Radical decoder

Signed-off-by: James Almer <jamrial@gmail.com>

James Almer authored on 2013/05/11 04:53:50
Showing 12 changed files
... ...
@@ -44,6 +44,7 @@ version <next>:
44 44
 - ADP demuxer
45 45
 - RSD demuxer
46 46
 - RedSpark demuxer
47
+- ADPCM IMA Radical decoder
47 48
 
48 49
 
49 50
 version 1.2:
... ...
@@ -772,6 +772,7 @@ following image formats are supported:
772 772
     @tab Used in some Sega Saturn console games.
773 773
 @item ADPCM IMA Duck DK4     @tab     @tab  X
774 774
     @tab Used in some Sega Saturn console games.
775
+@item ADPCM IMA Radical      @tab     @tab  X
775 776
 @item ADPCM Microsoft        @tab  X  @tab  X
776 777
 @item ADPCM MS IMA           @tab  X  @tab  X
777 778
 @item ADPCM Nintendo Gamecube AFC  @tab     @tab  X
... ...
@@ -590,6 +590,7 @@ OBJS-$(CONFIG_ADPCM_IMA_ISS_DECODER)      += adpcm.o adpcm_data.o
590 590
 OBJS-$(CONFIG_ADPCM_IMA_OKI_DECODER)      += adpcm.o adpcm_data.o
591 591
 OBJS-$(CONFIG_ADPCM_IMA_QT_DECODER)       += adpcm.o adpcm_data.o
592 592
 OBJS-$(CONFIG_ADPCM_IMA_QT_ENCODER)       += adpcmenc.o adpcm_data.o
593
+OBJS-$(CONFIG_ADPCM_IMA_RAD_DECODER)      += adpcm.o adpcm_data.o
593 594
 OBJS-$(CONFIG_ADPCM_IMA_SMJPEG_DECODER)   += adpcm.o adpcm_data.o
594 595
 OBJS-$(CONFIG_ADPCM_IMA_WAV_DECODER)      += adpcm.o adpcm_data.o
595 596
 OBJS-$(CONFIG_ADPCM_IMA_WAV_ENCODER)      += adpcmenc.o adpcm_data.o
... ...
@@ -551,6 +551,11 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
551 551
             buf_size = FFMIN(buf_size, avctx->block_align);
552 552
         nb_samples = 1 + (buf_size - 4 * ch) * 2 / ch;
553 553
         break;
554
+    case AV_CODEC_ID_ADPCM_IMA_RAD:
555
+        if (avctx->block_align > 0)
556
+            buf_size = FFMIN(buf_size, avctx->block_align);
557
+        nb_samples = (buf_size - 4 * ch) * 2 / ch;
558
+        break;
554 559
     case AV_CODEC_ID_ADPCM_IMA_WAV:
555 560
         if (avctx->block_align > 0)
556 561
             buf_size = FFMIN(buf_size, avctx->block_align);
... ...
@@ -912,6 +917,31 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
912 912
             *samples++ = adpcm_ima_oki_expand_nibble(&c->status[st], v & 0x0F);
913 913
         }
914 914
         break;
915
+    case AV_CODEC_ID_ADPCM_IMA_RAD:
916
+        for (channel = 0; channel < avctx->channels; channel++) {
917
+            cs = &c->status[channel];
918
+            cs->step_index = sign_extend(bytestream2_get_le16u(&gb), 16);
919
+            cs->predictor  = sign_extend(bytestream2_get_le16u(&gb), 16);
920
+            if (cs->step_index > 88u){
921
+                av_log(avctx, AV_LOG_ERROR, "ERROR: step_index[%d] = %i\n",
922
+                       channel, cs->step_index);
923
+                return AVERROR_INVALIDDATA;
924
+            }
925
+        }
926
+        for (n = 0; n < nb_samples / 2; n++) {
927
+            int byte[2];
928
+
929
+            byte[0] = bytestream2_get_byteu(&gb);
930
+            if (st)
931
+                byte[1] = bytestream2_get_byteu(&gb);
932
+            for(channel = 0; channel < avctx->channels; channel++) {
933
+                *samples++ = adpcm_ima_expand_nibble(&c->status[channel], byte[channel] & 0x0F, 3);
934
+            }
935
+            for(channel = 0; channel < avctx->channels; channel++) {
936
+                *samples++ = adpcm_ima_expand_nibble(&c->status[channel], byte[channel] >> 4  , 3);
937
+            }
938
+        }
939
+        break;
915 940
     case AV_CODEC_ID_ADPCM_IMA_WS:
916 941
         if (c->vqa_version == 3) {
917 942
             for (channel = 0; channel < avctx->channels; channel++) {
... ...
@@ -1489,6 +1519,7 @@ ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_EA_SEAD, sample_fmts_s16,  adpcm_ima_ea_sead
1489 1489
 ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_ISS,     sample_fmts_s16,  adpcm_ima_iss,     "ADPCM IMA Funcom ISS");
1490 1490
 ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_OKI,     sample_fmts_s16,  adpcm_ima_oki,     "ADPCM IMA Dialogic OKI");
1491 1491
 ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_QT,      sample_fmts_s16p, adpcm_ima_qt,      "ADPCM IMA QuickTime");
1492
+ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_RAD,     sample_fmts_s16,  adpcm_ima_rad,     "ADPCM IMA Radical");
1492 1493
 ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_SMJPEG,  sample_fmts_s16,  adpcm_ima_smjpeg,  "ADPCM IMA Loki SDL MJPEG");
1493 1494
 ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WAV,     sample_fmts_s16p, adpcm_ima_wav,     "ADPCM IMA WAV");
1494 1495
 ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WS,      sample_fmts_both, adpcm_ima_ws,      "ADPCM IMA Westwood");
... ...
@@ -437,6 +437,7 @@ void avcodec_register_all(void)
437 437
     REGISTER_DECODER(ADPCM_IMA_ISS,     adpcm_ima_iss);
438 438
     REGISTER_DECODER(ADPCM_IMA_OKI,     adpcm_ima_oki);
439 439
     REGISTER_ENCDEC (ADPCM_IMA_QT,      adpcm_ima_qt);
440
+    REGISTER_DECODER(ADPCM_IMA_RAD,     adpcm_ima_rad);
440 441
     REGISTER_DECODER(ADPCM_IMA_SMJPEG,  adpcm_ima_smjpeg);
441 442
     REGISTER_ENCDEC (ADPCM_IMA_WAV,     adpcm_ima_wav);
442 443
     REGISTER_DECODER(ADPCM_IMA_WS,      adpcm_ima_ws);
... ...
@@ -363,6 +363,7 @@ enum AVCodecID {
363 363
     AV_CODEC_ID_ADPCM_AFC  = MKBETAG('A','F','C',' '),
364 364
     AV_CODEC_ID_ADPCM_IMA_OKI = MKBETAG('O','K','I',' '),
365 365
     AV_CODEC_ID_ADPCM_DTK  = MKBETAG('D','T','K',' '),
366
+    AV_CODEC_ID_ADPCM_IMA_RAD = MKBETAG('R','A','D',' '),
366 367
 
367 368
     /* AMR */
368 369
     AV_CODEC_ID_AMR_NB = 0x12000,
... ...
@@ -1823,6 +1823,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
1823 1823
         .long_name = NULL_IF_CONFIG_SMALL("ADPCM Nintendo Gamecube DTK"),
1824 1824
         .props     = AV_CODEC_PROP_LOSSY,
1825 1825
     },
1826
+    {
1827
+        .id        = AV_CODEC_ID_ADPCM_IMA_RAD,
1828
+        .type      = AVMEDIA_TYPE_AUDIO,
1829
+        .name      = "adpcm_ima_rad",
1830
+        .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Radical"),
1831
+        .props     = AV_CODEC_PROP_LOSSY,
1832
+    },
1826 1833
 
1827 1834
     /* AMR */
1828 1835
     {
... ...
@@ -2883,6 +2883,8 @@ int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes)
2883 2883
                     return blocks * (((ba - 16) * 2 / 3 * 4) / ch);
2884 2884
                 case AV_CODEC_ID_ADPCM_IMA_DK4:
2885 2885
                     return blocks * (1 + (ba - 4 * ch) * 2 / ch);
2886
+                case AV_CODEC_ID_ADPCM_IMA_RAD:
2887
+                    return blocks * ((ba - 4 * ch) * 2 / ch);
2886 2888
                 case AV_CODEC_ID_ADPCM_MS:
2887 2889
                     return blocks * (2 + (ba - 7 * ch) * 2 / ch);
2888 2890
                 }
... ...
@@ -29,7 +29,7 @@
29 29
 #include "libavutil/avutil.h"
30 30
 
31 31
 #define LIBAVCODEC_VERSION_MAJOR 55
32
-#define LIBAVCODEC_VERSION_MINOR  8
32
+#define LIBAVCODEC_VERSION_MINOR  9
33 33
 #define LIBAVCODEC_VERSION_MICRO 100
34 34
 
35 35
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
... ...
@@ -27,6 +27,7 @@
27 27
 
28 28
 static const AVCodecTag rsd_tags[] = {
29 29
     { AV_CODEC_ID_ADPCM_THP,       MKTAG('G','A','D','P') },
30
+    { AV_CODEC_ID_ADPCM_IMA_RAD,   MKTAG('R','A','D','P') },
30 31
     { AV_CODEC_ID_PCM_S16BE,       MKTAG('P','C','M','B') },
31 32
     { AV_CODEC_ID_PCM_S16LE,       MKTAG('P','C','M',' ') },
32 33
     { AV_CODEC_ID_NONE, 0 },
... ...
@@ -34,7 +35,6 @@ static const AVCodecTag rsd_tags[] = {
34 34
 
35 35
 static const uint32_t rsd_unsupported_tags[] = {
36 36
     MKTAG('O','G','G',' '),
37
-    MKTAG('R','A','D','P'),
38 37
     MKTAG('V','A','G',' '),
39 38
     MKTAG('W','A','D','P'),
40 39
     MKTAG('X','A','D','P'),
... ...
@@ -92,6 +92,11 @@ static int rsd_read_header(AVFormatContext *s)
92 92
     avio_skip(pb, 4); // Unknown
93 93
 
94 94
     switch (codec->codec_id) {
95
+    case AV_CODEC_ID_ADPCM_IMA_RAD:
96
+        codec->block_align = 20 * codec->channels;
97
+        if (pb->seekable)
98
+            st->duration = av_get_audio_frame_duration(codec, avio_size(pb) - start);
99
+        break;
95 100
     case AV_CODEC_ID_ADPCM_THP:
96 101
         /* RSD3GADP is mono, so only alloc enough memory
97 102
            to store the coeff table for a single channel. */
... ...
@@ -131,12 +136,16 @@ static int rsd_read_header(AVFormatContext *s)
131 131
 
132 132
 static int rsd_read_packet(AVFormatContext *s, AVPacket *pkt)
133 133
 {
134
+    AVCodecContext *codec = s->streams[0]->codec;
134 135
     int ret, size = 1024;
135 136
 
136 137
     if (url_feof(s->pb))
137 138
         return AVERROR_EOF;
138 139
 
139
-    ret = av_get_packet(s->pb, pkt, size);
140
+    if (codec->codec_id == AV_CODEC_ID_ADPCM_IMA_RAD)
141
+        ret = av_get_packet(s->pb, pkt, codec->block_align);
142
+    else
143
+        ret = av_get_packet(s->pb, pkt, size);
140 144
 
141 145
     if (ret != size) {
142 146
         if (ret < 0) {
... ...
@@ -61,6 +61,9 @@ fate-adpcm-ima-iss: CMD = md5 -i $(SAMPLES)/funcom-iss/0004010100.iss -f s16le
61 61
 FATE_ADPCM-$(call DEMDEC, WAV, ADPCM_IMA_OKI) += fate-adpcm-ima-oki
62 62
 fate-adpcm-ima-oki: CMD = md5 -i $(SAMPLES)/oki/test.wav -f s16le
63 63
 
64
+FATE_ADPCM-$(call DEMDEC, RSD, ADPCM_IMA_RAD) += fate-adpcm-ima-rad
65
+fate-adpcm-ima-rad: CMD = md5 -i $(SAMPLES)/rsd/hit_run_partial.rsd -f s16le
66
+
64 67
 FATE_ADPCM-$(call DEMDEC, SMJPEG, ADPCM_IMA_SMJPEG) += fate-adpcm-ima-smjpeg
65 68
 fate-adpcm-ima-smjpeg: CMD = framecrc -i $(SAMPLES)/smjpeg/scenwin.mjpg -vn
66 69
 
67 70
new file mode 100644
... ...
@@ -0,0 +1 @@
0
+495f0ae514c28c6bdcbd40811a17e2a5