Skip to content

Commit 035ae3c

Browse files
committed
avcodec: add SDX2 DPCM decoder
Signed-off-by: Paul B Mahol <onemda@gmail.com>
1 parent 2ccc1b3 commit 035ae3c

File tree

12 files changed

+50
-5
lines changed

12 files changed

+50
-5
lines changed

Changelog

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ version <next>:
2525
- wve demuxer
2626
- zero-copy Intel QSV transcoding in ffmpeg
2727
- shuffleframes filter
28+
- SDX2 DPCM decoder
2829

2930

3031
version 2.8:

doc/general.texi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,8 @@ following image formats are supported:
960960
@tab Used in Quake III, Jedi Knight 2 and other computer games.
961961
@item DPCM Interplay @tab @tab X
962962
@tab Used in various Interplay computer games.
963+
@item DPCM Squareroot-Delta-Exact
964+
@tab Used in various games.
963965
@item DPCM Sierra Online @tab @tab X
964966
@tab Used in Sierra Online game audio files.
965967
@item DPCM Sol @tab @tab X

libavcodec/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,7 @@ OBJS-$(CONFIG_S302M_DECODER) += s302m.o
458458
OBJS-$(CONFIG_S302M_ENCODER) += s302menc.o
459459
OBJS-$(CONFIG_SANM_DECODER) += sanm.o
460460
OBJS-$(CONFIG_SCREENPRESSO_DECODER) += screenpresso.o
461+
OBJS-$(CONFIG_SDX2_DPCM_DECODER) += dpcm.o
461462
OBJS-$(CONFIG_SGI_DECODER) += sgidec.o
462463
OBJS-$(CONFIG_SGI_ENCODER) += sgienc.o rle.o
463464
OBJS-$(CONFIG_SGIRLE_DECODER) += sgirledec.o

libavcodec/allcodecs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ void avcodec_register_all(void)
287287
REGISTER_ENCDEC (S302M, s302m);
288288
REGISTER_DECODER(SANM, sanm);
289289
REGISTER_DECODER(SCREENPRESSO, screenpresso);
290+
REGISTER_DECODER(SDX2_DPCM, sdx2_dpcm);
290291
REGISTER_ENCDEC (SGI, sgi);
291292
REGISTER_DECODER(SGIRLE, sgirle);
292293
REGISTER_DECODER(SMACKER, smacker);

libavcodec/avcodec.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,8 @@ enum AVCodecID {
410410
AV_CODEC_ID_XAN_DPCM,
411411
AV_CODEC_ID_SOL_DPCM,
412412

413+
AV_CODEC_ID_SDX2_DPCM = 0x14800,
414+
413415
/* audio codecs */
414416
AV_CODEC_ID_MP2 = 0x15000,
415417
AV_CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3

libavcodec/codec_desc.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2054,6 +2054,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
20542054
.long_name = NULL_IF_CONFIG_SMALL("DPCM Sol"),
20552055
.props = AV_CODEC_PROP_LOSSY,
20562056
},
2057+
{
2058+
.id = AV_CODEC_ID_SDX2_DPCM,
2059+
.type = AVMEDIA_TYPE_AUDIO,
2060+
.name = "sdx2_dpcm",
2061+
.long_name = NULL_IF_CONFIG_SMALL("DPCM Squareroot-Delta-Exact"),
2062+
.props = AV_CODEC_PROP_LOSSY,
2063+
},
20572064

20582065
/* audio codecs */
20592066
{

libavcodec/dpcm.c

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
#include "mathops.h"
4545

4646
typedef struct DPCMContext {
47-
int16_t roq_square_array[256];
47+
int16_t square_array[256];
4848
int sample[2]; ///< previous sample (for SOL_DPCM)
4949
const int8_t *sol_table; ///< delta table for SOL_DPCM
5050
} DPCMContext;
@@ -130,8 +130,8 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx)
130130
/* initialize square table */
131131
for (i = 0; i < 128; i++) {
132132
int16_t square = i * i;
133-
s->roq_square_array[i ] = square;
134-
s->roq_square_array[i + 128] = -square;
133+
s->square_array[i ] = square;
134+
s->square_array[i + 128] = -square;
135135
}
136136
break;
137137

@@ -153,6 +153,13 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx)
153153
}
154154
break;
155155

156+
case AV_CODEC_ID_SDX2_DPCM:
157+
for (i = -128; i < 128; i++) {
158+
int16_t square = i * i * 2;
159+
s->square_array[i+128] = i < 0 ? -square: square;
160+
}
161+
break;
162+
156163
default:
157164
break;
158165
}
@@ -200,6 +207,9 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
200207
else
201208
out = buf_size;
202209
break;
210+
case AV_CODEC_ID_SDX2_DPCM:
211+
out = buf_size;
212+
break;
203213
}
204214
if (out <= 0) {
205215
av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
@@ -230,7 +240,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
230240

231241
/* decode the samples */
232242
while (output_samples < samples_end) {
233-
predictor[ch] += s->roq_square_array[bytestream2_get_byteu(&gb)];
243+
predictor[ch] += s->square_array[bytestream2_get_byteu(&gb)];
234244
predictor[ch] = av_clip_int16(predictor[ch]);
235245
*output_samples++ = predictor[ch];
236246

@@ -318,6 +328,19 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
318328
}
319329
}
320330
break;
331+
332+
case AV_CODEC_ID_SDX2_DPCM:
333+
while (output_samples < samples_end) {
334+
int8_t n = bytestream2_get_byteu(&gb);
335+
336+
if (!(n & 1))
337+
s->sample[ch] = 0;
338+
s->sample[ch] += s->square_array[n + 128];
339+
s->sample[ch] = av_clip_int16(s->sample[ch]);
340+
*output_samples++ = s->sample[ch];
341+
ch ^= stereo;
342+
}
343+
break;
321344
}
322345

323346
*got_frame_ptr = 1;
@@ -339,5 +362,6 @@ AVCodec ff_ ## name_ ## _decoder = { \
339362

340363
DPCM_DECODER(AV_CODEC_ID_INTERPLAY_DPCM, interplay_dpcm, "DPCM Interplay");
341364
DPCM_DECODER(AV_CODEC_ID_ROQ_DPCM, roq_dpcm, "DPCM id RoQ");
365+
DPCM_DECODER(AV_CODEC_ID_SDX2_DPCM, sdx2_dpcm, "DPCM Squareroot-Delta-Exact");
342366
DPCM_DECODER(AV_CODEC_ID_SOL_DPCM, sol_dpcm, "DPCM Sol");
343367
DPCM_DECODER(AV_CODEC_ID_XAN_DPCM, xan_dpcm, "DPCM Xan");

libavcodec/utils.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2906,6 +2906,7 @@ int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
29062906
case AV_CODEC_ID_PCM_S8_PLANAR:
29072907
case AV_CODEC_ID_PCM_U8:
29082908
case AV_CODEC_ID_PCM_ZORK:
2909+
case AV_CODEC_ID_SDX2_DPCM:
29092910
return 8;
29102911
case AV_CODEC_ID_PCM_S16BE:
29112912
case AV_CODEC_ID_PCM_S16BE_PLANAR:

libavcodec/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#include "libavutil/version.h"
3030

3131
#define LIBAVCODEC_VERSION_MAJOR 57
32-
#define LIBAVCODEC_VERSION_MINOR 9
32+
#define LIBAVCODEC_VERSION_MINOR 10
3333
#define LIBAVCODEC_VERSION_MICRO 100
3434

3535
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \

libavformat/aiff.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ static const AVCodecTag ff_codec_aiff_tags[] = {
5252
{ AV_CODEC_ID_ADPCM_IMA_QT, MKTAG('i','m','a','4') },
5353
{ AV_CODEC_ID_QDM2, MKTAG('Q','D','M','2') },
5454
{ AV_CODEC_ID_QCELP, MKTAG('Q','c','l','p') },
55+
{ AV_CODEC_ID_SDX2_DPCM, MKTAG('S','D','X','2') },
5556
{ AV_CODEC_ID_NONE, 0 },
5657
};
5758

0 commit comments

Comments
 (0)