From 29bdcf588f81aceca268dbfff036eb46b8d8bf80 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 2 Jun 2017 12:43:02 +0200 Subject: avcodec: add Gremlin DPCM decoder Signed-off-by: Paul B Mahol --- libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/avcodec.h | 1 + libavcodec/codec_desc.c | 7 +++++++ libavcodec/dpcm.c | 44 ++++++++++++++++++++++++++++++++++++++------ libavcodec/version.h | 4 ++-- 6 files changed, 50 insertions(+), 8 deletions(-) diff --git a/libavcodec/Makefile b/libavcodec/Makefile index a752f87..7ce7d14 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -310,6 +310,7 @@ OBJS-$(CONFIG_G723_1_ENCODER) += g723_1enc.o g723_1.o \ OBJS-$(CONFIG_G729_DECODER) += g729dec.o lsp.o celp_math.o celp_filters.o acelp_filters.o acelp_pitch_delay.o acelp_vectors.o g729postfilter.o OBJS-$(CONFIG_GIF_DECODER) += gifdec.o lzw.o OBJS-$(CONFIG_GIF_ENCODER) += gif.o lzwenc.o +OBJS-$(CONFIG_GREMLIN_DPCM_DECODER) += dpcm.o OBJS-$(CONFIG_GSM_DECODER) += gsmdec.o gsmdec_data.o msgsmdec.o OBJS-$(CONFIG_GSM_MS_DECODER) += gsmdec.o gsmdec_data.o msgsmdec.o OBJS-$(CONFIG_H261_DECODER) += h261dec.o h261data.o h261.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 4373ebd..995d58b 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -520,6 +520,7 @@ static void register_all(void) REGISTER_DECODER(PCM_ZORK, pcm_zork); /* DPCM codecs */ + REGISTER_DECODER(GREMLIN_DPCM, gremlin_dpcm); REGISTER_DECODER(INTERPLAY_DPCM, interplay_dpcm); REGISTER_ENCDEC (ROQ_DPCM, roq_dpcm); REGISTER_DECODER(SOL_DPCM, sol_dpcm); diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 00f9c82..59bd1c5 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -548,6 +548,7 @@ enum AVCodecID { AV_CODEC_ID_SOL_DPCM, AV_CODEC_ID_SDX2_DPCM = 0x14800, + AV_CODEC_ID_GREMLIN_DPCM, /* audio codecs */ AV_CODEC_ID_MP2 = 0x15000, diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index f0ca4ba..4cc5729 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -2249,6 +2249,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("DPCM Squareroot-Delta-Exact"), .props = AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_GREMLIN_DPCM, + .type = AVMEDIA_TYPE_AUDIO, + .name = "gremlin_dpcm", + .long_name = NULL_IF_CONFIG_SMALL("DPCM Gremlin"), + .props = AV_CODEC_PROP_LOSSY, + }, /* audio codecs */ { diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index 2edd4d5..7d3934e 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -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"); diff --git a/libavcodec/version.h b/libavcodec/version.h index 5f2321c..2b259b8 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 96 -#define LIBAVCODEC_VERSION_MICRO 101 +#define LIBAVCODEC_VERSION_MINOR 97 +#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ -- cgit v1.1