Skip to content

Commit 67fad0d

Browse files
committedMay 10, 2013
ADPCM IMA Radical decoder
Signed-off-by: James Almer <[email protected]>
1 parent e5e86db commit 67fad0d

File tree

12 files changed

+61
-3
lines changed

12 files changed

+61
-3
lines changed
 

Diff for: ‎Changelog

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ version <next>:
4444
- ADP demuxer
4545
- RSD demuxer
4646
- RedSpark demuxer
47+
- ADPCM IMA Radical decoder
4748

4849

4950
version 1.2:

Diff for: ‎doc/general.texi

+1
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,7 @@ following image formats are supported:
772772
@tab Used in some Sega Saturn console games.
773773
@item ADPCM IMA Duck DK4 @tab @tab X
774774
@tab Used in some Sega Saturn console games.
775+
@item ADPCM IMA Radical @tab @tab X
775776
@item ADPCM Microsoft @tab X @tab X
776777
@item ADPCM MS IMA @tab X @tab X
777778
@item ADPCM Nintendo Gamecube AFC @tab @tab X

Diff for: ‎libavcodec/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,7 @@ OBJS-$(CONFIG_ADPCM_IMA_ISS_DECODER) += adpcm.o adpcm_data.o
590590
OBJS-$(CONFIG_ADPCM_IMA_OKI_DECODER) += adpcm.o adpcm_data.o
591591
OBJS-$(CONFIG_ADPCM_IMA_QT_DECODER) += adpcm.o adpcm_data.o
592592
OBJS-$(CONFIG_ADPCM_IMA_QT_ENCODER) += adpcmenc.o adpcm_data.o
593+
OBJS-$(CONFIG_ADPCM_IMA_RAD_DECODER) += adpcm.o adpcm_data.o
593594
OBJS-$(CONFIG_ADPCM_IMA_SMJPEG_DECODER) += adpcm.o adpcm_data.o
594595
OBJS-$(CONFIG_ADPCM_IMA_WAV_DECODER) += adpcm.o adpcm_data.o
595596
OBJS-$(CONFIG_ADPCM_IMA_WAV_ENCODER) += adpcmenc.o adpcm_data.o

Diff for: ‎libavcodec/adpcm.c

+31
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,11 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
551551
buf_size = FFMIN(buf_size, avctx->block_align);
552552
nb_samples = 1 + (buf_size - 4 * ch) * 2 / ch;
553553
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;
554559
case AV_CODEC_ID_ADPCM_IMA_WAV:
555560
if (avctx->block_align > 0)
556561
buf_size = FFMIN(buf_size, avctx->block_align);
@@ -912,6 +917,31 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
912917
*samples++ = adpcm_ima_oki_expand_nibble(&c->status[st], v & 0x0F);
913918
}
914919
break;
920+
case AV_CODEC_ID_ADPCM_IMA_RAD:
921+
for (channel = 0; channel < avctx->channels; channel++) {
922+
cs = &c->status[channel];
923+
cs->step_index = sign_extend(bytestream2_get_le16u(&gb), 16);
924+
cs->predictor = sign_extend(bytestream2_get_le16u(&gb), 16);
925+
if (cs->step_index > 88u){
926+
av_log(avctx, AV_LOG_ERROR, "ERROR: step_index[%d] = %i\n",
927+
channel, cs->step_index);
928+
return AVERROR_INVALIDDATA;
929+
}
930+
}
931+
for (n = 0; n < nb_samples / 2; n++) {
932+
int byte[2];
933+
934+
byte[0] = bytestream2_get_byteu(&gb);
935+
if (st)
936+
byte[1] = bytestream2_get_byteu(&gb);
937+
for(channel = 0; channel < avctx->channels; channel++) {
938+
*samples++ = adpcm_ima_expand_nibble(&c->status[channel], byte[channel] & 0x0F, 3);
939+
}
940+
for(channel = 0; channel < avctx->channels; channel++) {
941+
*samples++ = adpcm_ima_expand_nibble(&c->status[channel], byte[channel] >> 4 , 3);
942+
}
943+
}
944+
break;
915945
case AV_CODEC_ID_ADPCM_IMA_WS:
916946
if (c->vqa_version == 3) {
917947
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
14891519
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_ISS, sample_fmts_s16, adpcm_ima_iss, "ADPCM IMA Funcom ISS");
14901520
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_OKI, sample_fmts_s16, adpcm_ima_oki, "ADPCM IMA Dialogic OKI");
14911521
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_QT, sample_fmts_s16p, adpcm_ima_qt, "ADPCM IMA QuickTime");
1522+
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_RAD, sample_fmts_s16, adpcm_ima_rad, "ADPCM IMA Radical");
14921523
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_SMJPEG, sample_fmts_s16, adpcm_ima_smjpeg, "ADPCM IMA Loki SDL MJPEG");
14931524
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WAV, sample_fmts_s16p, adpcm_ima_wav, "ADPCM IMA WAV");
14941525
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WS, sample_fmts_both, adpcm_ima_ws, "ADPCM IMA Westwood");

Diff for: ‎libavcodec/allcodecs.c

+1
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ void avcodec_register_all(void)
437437
REGISTER_DECODER(ADPCM_IMA_ISS, adpcm_ima_iss);
438438
REGISTER_DECODER(ADPCM_IMA_OKI, adpcm_ima_oki);
439439
REGISTER_ENCDEC (ADPCM_IMA_QT, adpcm_ima_qt);
440+
REGISTER_DECODER(ADPCM_IMA_RAD, adpcm_ima_rad);
440441
REGISTER_DECODER(ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg);
441442
REGISTER_ENCDEC (ADPCM_IMA_WAV, adpcm_ima_wav);
442443
REGISTER_DECODER(ADPCM_IMA_WS, adpcm_ima_ws);

Diff for: ‎libavcodec/avcodec.h

+1
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ enum AVCodecID {
363363
AV_CODEC_ID_ADPCM_AFC = MKBETAG('A','F','C',' '),
364364
AV_CODEC_ID_ADPCM_IMA_OKI = MKBETAG('O','K','I',' '),
365365
AV_CODEC_ID_ADPCM_DTK = MKBETAG('D','T','K',' '),
366+
AV_CODEC_ID_ADPCM_IMA_RAD = MKBETAG('R','A','D',' '),
366367

367368
/* AMR */
368369
AV_CODEC_ID_AMR_NB = 0x12000,

Diff for: ‎libavcodec/codec_desc.c

+7
Original file line numberDiff line numberDiff line change
@@ -1823,6 +1823,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
18231823
.long_name = NULL_IF_CONFIG_SMALL("ADPCM Nintendo Gamecube DTK"),
18241824
.props = AV_CODEC_PROP_LOSSY,
18251825
},
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+
},
18261833

18271834
/* AMR */
18281835
{

Diff for: ‎libavcodec/utils.c

+2
Original file line numberDiff line numberDiff line change
@@ -2883,6 +2883,8 @@ int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes)
28832883
return blocks * (((ba - 16) * 2 / 3 * 4) / ch);
28842884
case AV_CODEC_ID_ADPCM_IMA_DK4:
28852885
return blocks * (1 + (ba - 4 * ch) * 2 / ch);
2886+
case AV_CODEC_ID_ADPCM_IMA_RAD:
2887+
return blocks * ((ba - 4 * ch) * 2 / ch);
28862888
case AV_CODEC_ID_ADPCM_MS:
28872889
return blocks * (2 + (ba - 7 * ch) * 2 / ch);
28882890
}

Diff for: ‎libavcodec/version.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#include "libavutil/avutil.h"
3030

3131
#define LIBAVCODEC_VERSION_MAJOR 55
32-
#define LIBAVCODEC_VERSION_MINOR 8
32+
#define LIBAVCODEC_VERSION_MINOR 9
3333
#define LIBAVCODEC_VERSION_MICRO 100
3434

3535
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \

Diff for: ‎libavformat/rsd.c

+11-2
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@
2727

2828
static const AVCodecTag rsd_tags[] = {
2929
{ AV_CODEC_ID_ADPCM_THP, MKTAG('G','A','D','P') },
30+
{ AV_CODEC_ID_ADPCM_IMA_RAD, MKTAG('R','A','D','P') },
3031
{ AV_CODEC_ID_PCM_S16BE, MKTAG('P','C','M','B') },
3132
{ AV_CODEC_ID_PCM_S16LE, MKTAG('P','C','M',' ') },
3233
{ AV_CODEC_ID_NONE, 0 },
3334
};
3435

3536
static const uint32_t rsd_unsupported_tags[] = {
3637
MKTAG('O','G','G',' '),
37-
MKTAG('R','A','D','P'),
3838
MKTAG('V','A','G',' '),
3939
MKTAG('W','A','D','P'),
4040
MKTAG('X','A','D','P'),
@@ -92,6 +92,11 @@ static int rsd_read_header(AVFormatContext *s)
9292
avio_skip(pb, 4); // Unknown
9393

9494
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;
95100
case AV_CODEC_ID_ADPCM_THP:
96101
/* RSD3GADP is mono, so only alloc enough memory
97102
to store the coeff table for a single channel. */
@@ -131,12 +136,16 @@ static int rsd_read_header(AVFormatContext *s)
131136

132137
static int rsd_read_packet(AVFormatContext *s, AVPacket *pkt)
133138
{
139+
AVCodecContext *codec = s->streams[0]->codec;
134140
int ret, size = 1024;
135141

136142
if (url_feof(s->pb))
137143
return AVERROR_EOF;
138144

139-
ret = av_get_packet(s->pb, pkt, size);
145+
if (codec->codec_id == AV_CODEC_ID_ADPCM_IMA_RAD)
146+
ret = av_get_packet(s->pb, pkt, codec->block_align);
147+
else
148+
ret = av_get_packet(s->pb, pkt, size);
140149

141150
if (ret != size) {
142151
if (ret < 0) {

Diff for: ‎tests/fate/adpcm.mak

+3
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ fate-adpcm-ima-iss: CMD = md5 -i $(SAMPLES)/funcom-iss/0004010100.iss -f s16le
6161
FATE_ADPCM-$(call DEMDEC, WAV, ADPCM_IMA_OKI) += fate-adpcm-ima-oki
6262
fate-adpcm-ima-oki: CMD = md5 -i $(SAMPLES)/oki/test.wav -f s16le
6363

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+
6467
FATE_ADPCM-$(call DEMDEC, SMJPEG, ADPCM_IMA_SMJPEG) += fate-adpcm-ima-smjpeg
6568
fate-adpcm-ima-smjpeg: CMD = framecrc -i $(SAMPLES)/smjpeg/scenwin.mjpg -vn
6669

Diff for: ‎tests/ref/fate/adpcm-ima-rad

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
495f0ae514c28c6bdcbd40811a17e2a5

0 commit comments

Comments
 (0)
Please sign in to comment.