X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fadpcm.c;h=2f632bdb6ef23140091dc06987f794531344532d;hb=7bbd060324f05a32aa3cc748ea484abf499cfbd8;hp=ba38041f4af5a18f264371ef36c9241e1f815548;hpb=cbed8dbb7e1e2ac73b93502ee2a56a4e3ee51354;p=ffmpeg diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index ba38041f4af..2f632bdb6ef 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -107,6 +107,9 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) case AV_CODEC_ID_ADPCM_EA_XAS: max_channels = 6; break; + case AV_CODEC_ID_ADPCM_PSX: + max_channels = 8; + break; case AV_CODEC_ID_ADPCM_THP: case AV_CODEC_ID_ADPCM_THP_LE: max_channels = 14; @@ -152,6 +155,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 +669,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 +1553,43 @@ 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 filter, shift, flag, byte; + + filter = bytestream2_get_byteu(&gb); + shift = filter & 0xf; + filter = filter >> 4; + if (filter >= FF_ARRAY_ELEMS(xa_adpcm_table)) + return AVERROR_INVALIDDATA; + flag = bytestream2_get_byteu(&gb); + + /* Decode 28 samples. */ + for (n = 0; n < 28; n++) { + int sample = 0, scale; + + if (flag < 0x07) { + if (n & 1) { + scale = sign_extend(byte >> 4, 4); + } else { + byte = bytestream2_get_byteu(&gb); + scale = sign_extend(byte, 4); + } + + scale = scale << 12; + sample = (int)((scale >> shift) + (c->status[channel].sample1 * xa_adpcm_table[filter][0] + c->status[channel].sample2 * xa_adpcm_table[filter][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");