|
|
|
@@ -44,7 +44,7 @@ |
|
|
|
#include "mathops.h" |
|
|
|
|
|
|
|
typedef struct DPCMContext { |
|
|
|
int16_t square_array[256]; |
|
|
|
int16_t 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->square_array[i ] = square; |
|
|
|
s->square_array[i + 128] = -square; |
|
|
|
s->array[i ] = square; |
|
|
|
s->array[i + 128] = -square; |
|
|
|
} |
|
|
|
break; |
|
|
|
|
|
|
|
@@ -156,7 +156,25 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx) |
|
|
|
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; |
|
|
|
s->array[i+128] = i < 0 ? -square: square; |
|
|
|
} |
|
|
|
break; |
|
|
|
|
|
|
|
case AV_CODEC_ID_GREMLIN_DPCM: { |
|
|
|
int delta = 0; |
|
|
|
int code = 64; |
|
|
|
int step = 45; |
|
|
|
|
|
|
|
s->array[0] = 0; |
|
|
|
for (i = 0; i < 127; i++) { |
|
|
|
delta += (code >> 5); |
|
|
|
code += step; |
|
|
|
step += 2; |
|
|
|
|
|
|
|
s->array[i*2 + 1] = delta; |
|
|
|
s->array[i*2 + 2] = -delta; |
|
|
|
} |
|
|
|
s->array[255] = delta + (code >> 5); |
|
|
|
} |
|
|
|
break; |
|
|
|
|
|
|
|
@@ -207,6 +225,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, |
|
|
|
else |
|
|
|
out = buf_size; |
|
|
|
break; |
|
|
|
case AV_CODEC_ID_GREMLIN_DPCM: |
|
|
|
case AV_CODEC_ID_SDX2_DPCM: |
|
|
|
out = buf_size; |
|
|
|
break; |
|
|
|
@@ -240,7 +259,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, |
|
|
|
|
|
|
|
/* decode the samples */ |
|
|
|
while (output_samples < samples_end) { |
|
|
|
predictor[ch] += s->square_array[bytestream2_get_byteu(&gb)]; |
|
|
|
predictor[ch] += s->array[bytestream2_get_byteu(&gb)]; |
|
|
|
predictor[ch] = av_clip_int16(predictor[ch]); |
|
|
|
*output_samples++ = predictor[ch]; |
|
|
|
|
|
|
|
@@ -335,12 +354,24 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, |
|
|
|
|
|
|
|
if (!(n & 1)) |
|
|
|
s->sample[ch] = 0; |
|
|
|
s->sample[ch] += s->square_array[n + 128]; |
|
|
|
s->sample[ch] += s->array[n + 128]; |
|
|
|
s->sample[ch] = av_clip_int16(s->sample[ch]); |
|
|
|
*output_samples++ = s->sample[ch]; |
|
|
|
ch ^= stereo; |
|
|
|
} |
|
|
|
break; |
|
|
|
|
|
|
|
case AV_CODEC_ID_GREMLIN_DPCM: { |
|
|
|
int idx = 0; |
|
|
|
|
|
|
|
while (output_samples < samples_end) { |
|
|
|
uint8_t n = bytestream2_get_byteu(&gb); |
|
|
|
|
|
|
|
*output_samples++ = s->sample[idx] += s->array[n]; |
|
|
|
idx ^= 1; |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
*got_frame_ptr = 1; |
|
|
|
@@ -360,6 +391,7 @@ AVCodec ff_ ## name_ ## _decoder = { \ |
|
|
|
.capabilities = AV_CODEC_CAP_DR1, \ |
|
|
|
} |
|
|
|
|
|
|
|
DPCM_DECODER(AV_CODEC_ID_GREMLIN_DPCM, gremlin_dpcm, "DPCM Gremlin"); |
|
|
|
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"); |
|
|
|
|