diff options
author | Paul B Mahol <onemda@gmail.com> | 2015-10-24 21:41:32 +0300 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2015-10-26 12:08:01 +0300 |
commit | 035ae3c0096f6c0a3f199d331ed4094ff5beafd1 (patch) | |
tree | 5eb7e43f1e39621980e9cb2ceef6c098c95aa40c /libavcodec/dpcm.c | |
parent | 2ccc1b304e08a5f5e045c056e897ed377bf670f7 (diff) |
avcodec: add SDX2 DPCM decoder
Signed-off-by: Paul B Mahol <onemda@gmail.com>
Diffstat (limited to 'libavcodec/dpcm.c')
-rw-r--r-- | libavcodec/dpcm.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index c13945edb6..52a2c616db 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -44,7 +44,7 @@ #include "mathops.h" typedef struct DPCMContext { - int16_t roq_square_array[256]; + int16_t square_array[256]; int sample[2]; ///< previous sample (for SOL_DPCM) const int8_t *sol_table; ///< delta table for SOL_DPCM } DPCMContext; @@ -130,8 +130,8 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx) /* initialize square table */ for (i = 0; i < 128; i++) { int16_t square = i * i; - s->roq_square_array[i ] = square; - s->roq_square_array[i + 128] = -square; + s->square_array[i ] = square; + s->square_array[i + 128] = -square; } break; @@ -153,6 +153,13 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx) } break; + case AV_CODEC_ID_SDX2_DPCM: + for (i = -128; i < 128; i++) { + int16_t square = i * i * 2; + s->square_array[i+128] = i < 0 ? -square: square; + } + break; + default: break; } @@ -200,6 +207,9 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, else out = buf_size; break; + case AV_CODEC_ID_SDX2_DPCM: + out = buf_size; + break; } if (out <= 0) { av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); @@ -230,7 +240,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, /* decode the samples */ while (output_samples < samples_end) { - predictor[ch] += s->roq_square_array[bytestream2_get_byteu(&gb)]; + predictor[ch] += s->square_array[bytestream2_get_byteu(&gb)]; predictor[ch] = av_clip_int16(predictor[ch]); *output_samples++ = predictor[ch]; @@ -318,6 +328,19 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, } } break; + + case AV_CODEC_ID_SDX2_DPCM: + while (output_samples < samples_end) { + int8_t n = bytestream2_get_byteu(&gb); + + if (!(n & 1)) + s->sample[ch] = 0; + s->sample[ch] += s->square_array[n + 128]; + s->sample[ch] = av_clip_int16(s->sample[ch]); + *output_samples++ = s->sample[ch]; + ch ^= stereo; + } + break; } *got_frame_ptr = 1; @@ -339,5 +362,6 @@ AVCodec ff_ ## name_ ## _decoder = { \ DPCM_DECODER(AV_CODEC_ID_INTERPLAY_DPCM, interplay_dpcm, "DPCM Interplay"); DPCM_DECODER(AV_CODEC_ID_ROQ_DPCM, roq_dpcm, "DPCM id RoQ"); +DPCM_DECODER(AV_CODEC_ID_SDX2_DPCM, sdx2_dpcm, "DPCM Squareroot-Delta-Exact"); DPCM_DECODER(AV_CODEC_ID_SOL_DPCM, sol_dpcm, "DPCM Sol"); DPCM_DECODER(AV_CODEC_ID_XAN_DPCM, xan_dpcm, "DPCM Xan"); |