[FFmpeg-devel] [PATCH 1/2] avcodec: add ADPCM PSX decoder
Paul B Mahol
onemda at gmail.com
Tue Oct 13 15:07:35 CEST 2015
Signed-off-by: Paul B Mahol <onemda at gmail.com>
---
libavcodec/Makefile | 1 +
libavcodec/adpcm.c | 43 +++++++++++++++++++++++++++++++++++++++++++
libavcodec/allcodecs.c | 1 +
libavcodec/avcodec.h | 1 +
4 files changed, 46 insertions(+)
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index b8bd895..f9c8501 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -686,6 +686,7 @@ OBJS-$(CONFIG_ADPCM_IMA_WAV_ENCODER) += adpcmenc.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_IMA_WS_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_MS_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_MS_ENCODER) += adpcmenc.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_PSX_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_SBPRO_2_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_SBPRO_3_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_SBPRO_4_DECODER) += adpcm.o adpcm_data.o
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index ba38041..904bb2b 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -152,6 +152,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx)
case AV_CODEC_ID_ADPCM_THP_LE:
case AV_CODEC_ID_ADPCM_AFC:
case AV_CODEC_ID_ADPCM_DTK:
+ case AV_CODEC_ID_ADPCM_PSX:
avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
break;
case AV_CODEC_ID_ADPCM_IMA_WS:
@@ -665,6 +666,7 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
nb_samples = (buf_size / 128) * 224 / ch;
break;
case AV_CODEC_ID_ADPCM_DTK:
+ case AV_CODEC_ID_ADPCM_PSX:
nb_samples = buf_size / (16 * ch) * 28;
break;
}
@@ -1548,6 +1550,46 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
bytestream2_seek(&gb, 0, SEEK_SET);
}
break;
+ case AV_CODEC_ID_ADPCM_PSX:
+ for (channel = 0; channel < avctx->channels; channel++) {
+ samples = samples_p[channel];
+
+ /* Read in every sample for this channel. */
+ for (i = 0; i < nb_samples / 28; i++) {
+ int predict, shift, flag;
+ int16_t byte;
+
+ predict = bytestream2_get_byteu(&gb);
+ shift = predict & 0xf;
+ predict = predict >> 4;
+ if (predict >= 5)
+ return AVERROR_INVALIDDATA;
+ flag = bytestream2_get_byteu(&gb);
+
+ /* Decode 28 samples. */
+ for (n = 0; n < 28; n++) {
+ int32_t sample = 0;
+ int16_t scale;
+
+ if (flag < 0x07) {
+ if (!(n & 1))
+ byte = bytestream2_get_byteu(&gb);
+ if (!(n & 1))
+ scale = byte & 0xf;
+ else
+ scale = byte >> 4;
+
+ scale = scale << 12;
+
+ sample = (int)((scale >> shift) + c->status[channel].sample1 * xa_adpcm_table[predict][0] / 64 + c->status[channel].sample2 * xa_adpcm_table[predict][1] / 64);
+ }
+ *samples++ = av_clip_int16(sample);
+ c->status[channel].sample2 = c->status[channel].sample1;
+ c->status[channel].sample1 = sample;
+ }
+ }
+ }
+ break;
default:
return -1;
@@ -1622,6 +1664,7 @@ ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_SMJPEG, sample_fmts_s16, adpcm_ima_smjpeg,
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WAV, sample_fmts_s16p, adpcm_ima_wav, "ADPCM IMA WAV");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WS, sample_fmts_both, adpcm_ima_ws, "ADPCM IMA Westwood");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_MS, sample_fmts_s16, adpcm_ms, "ADPCM Microsoft");
+ADPCM_DECODER(AV_CODEC_ID_ADPCM_PSX, sample_fmts_s16p, adpcm_psx, "ADPCM PSX");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_SBPRO_2, sample_fmts_s16, adpcm_sbpro_2, "ADPCM Sound Blaster Pro 2-bit");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_SBPRO_3, sample_fmts_s16, adpcm_sbpro_3, "ADPCM Sound Blaster Pro 2.6-bit");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_SBPRO_4, sample_fmts_s16, adpcm_sbpro_4, "ADPCM Sound Blaster Pro 4-bit");
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index c8f7992..b19c9fd 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -508,6 +508,7 @@ void avcodec_register_all(void)
REGISTER_ENCDEC (ADPCM_IMA_WAV, adpcm_ima_wav);
REGISTER_DECODER(ADPCM_IMA_WS, adpcm_ima_ws);
REGISTER_ENCDEC (ADPCM_MS, adpcm_ms);
+ REGISTER_DECODER(ADPCM_PSX, adpcm_psx);
REGISTER_DECODER(ADPCM_SBPRO_2, adpcm_sbpro_2);
REGISTER_DECODER(ADPCM_SBPRO_3, adpcm_sbpro_3);
REGISTER_DECODER(ADPCM_SBPRO_4, adpcm_sbpro_4);
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 9b7ab3c..36f7632 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -393,6 +393,7 @@ enum AVCodecID {
AV_CODEC_ID_ADPCM_IMA_RAD,
AV_CODEC_ID_ADPCM_G726LE,
AV_CODEC_ID_ADPCM_THP_LE,
+ AV_CODEC_ID_ADPCM_PSX,
/* AMR */
AV_CODEC_ID_AMR_NB = 0x12000,
--
1.9.1
More information about the ffmpeg-devel
mailing list