mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
avcodec: add SDX2 DPCM decoder
Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
parent
2ccc1b304e
commit
035ae3c009
@ -25,6 +25,7 @@ version <next>:
|
|||||||
- wve demuxer
|
- wve demuxer
|
||||||
- zero-copy Intel QSV transcoding in ffmpeg
|
- zero-copy Intel QSV transcoding in ffmpeg
|
||||||
- shuffleframes filter
|
- shuffleframes filter
|
||||||
|
- SDX2 DPCM decoder
|
||||||
|
|
||||||
|
|
||||||
version 2.8:
|
version 2.8:
|
||||||
|
@ -960,6 +960,8 @@ following image formats are supported:
|
|||||||
@tab Used in Quake III, Jedi Knight 2 and other computer games.
|
@tab Used in Quake III, Jedi Knight 2 and other computer games.
|
||||||
@item DPCM Interplay @tab @tab X
|
@item DPCM Interplay @tab @tab X
|
||||||
@tab Used in various Interplay computer games.
|
@tab Used in various Interplay computer games.
|
||||||
|
@item DPCM Squareroot-Delta-Exact
|
||||||
|
@tab Used in various games.
|
||||||
@item DPCM Sierra Online @tab @tab X
|
@item DPCM Sierra Online @tab @tab X
|
||||||
@tab Used in Sierra Online game audio files.
|
@tab Used in Sierra Online game audio files.
|
||||||
@item DPCM Sol @tab @tab X
|
@item DPCM Sol @tab @tab X
|
||||||
|
@ -458,6 +458,7 @@ OBJS-$(CONFIG_S302M_DECODER) += s302m.o
|
|||||||
OBJS-$(CONFIG_S302M_ENCODER) += s302menc.o
|
OBJS-$(CONFIG_S302M_ENCODER) += s302menc.o
|
||||||
OBJS-$(CONFIG_SANM_DECODER) += sanm.o
|
OBJS-$(CONFIG_SANM_DECODER) += sanm.o
|
||||||
OBJS-$(CONFIG_SCREENPRESSO_DECODER) += screenpresso.o
|
OBJS-$(CONFIG_SCREENPRESSO_DECODER) += screenpresso.o
|
||||||
|
OBJS-$(CONFIG_SDX2_DPCM_DECODER) += dpcm.o
|
||||||
OBJS-$(CONFIG_SGI_DECODER) += sgidec.o
|
OBJS-$(CONFIG_SGI_DECODER) += sgidec.o
|
||||||
OBJS-$(CONFIG_SGI_ENCODER) += sgienc.o rle.o
|
OBJS-$(CONFIG_SGI_ENCODER) += sgienc.o rle.o
|
||||||
OBJS-$(CONFIG_SGIRLE_DECODER) += sgirledec.o
|
OBJS-$(CONFIG_SGIRLE_DECODER) += sgirledec.o
|
||||||
|
@ -287,6 +287,7 @@ void avcodec_register_all(void)
|
|||||||
REGISTER_ENCDEC (S302M, s302m);
|
REGISTER_ENCDEC (S302M, s302m);
|
||||||
REGISTER_DECODER(SANM, sanm);
|
REGISTER_DECODER(SANM, sanm);
|
||||||
REGISTER_DECODER(SCREENPRESSO, screenpresso);
|
REGISTER_DECODER(SCREENPRESSO, screenpresso);
|
||||||
|
REGISTER_DECODER(SDX2_DPCM, sdx2_dpcm);
|
||||||
REGISTER_ENCDEC (SGI, sgi);
|
REGISTER_ENCDEC (SGI, sgi);
|
||||||
REGISTER_DECODER(SGIRLE, sgirle);
|
REGISTER_DECODER(SGIRLE, sgirle);
|
||||||
REGISTER_DECODER(SMACKER, smacker);
|
REGISTER_DECODER(SMACKER, smacker);
|
||||||
|
@ -410,6 +410,8 @@ enum AVCodecID {
|
|||||||
AV_CODEC_ID_XAN_DPCM,
|
AV_CODEC_ID_XAN_DPCM,
|
||||||
AV_CODEC_ID_SOL_DPCM,
|
AV_CODEC_ID_SOL_DPCM,
|
||||||
|
|
||||||
|
AV_CODEC_ID_SDX2_DPCM = 0x14800,
|
||||||
|
|
||||||
/* audio codecs */
|
/* audio codecs */
|
||||||
AV_CODEC_ID_MP2 = 0x15000,
|
AV_CODEC_ID_MP2 = 0x15000,
|
||||||
AV_CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3
|
AV_CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3
|
||||||
|
@ -2054,6 +2054,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
|
|||||||
.long_name = NULL_IF_CONFIG_SMALL("DPCM Sol"),
|
.long_name = NULL_IF_CONFIG_SMALL("DPCM Sol"),
|
||||||
.props = AV_CODEC_PROP_LOSSY,
|
.props = AV_CODEC_PROP_LOSSY,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.id = AV_CODEC_ID_SDX2_DPCM,
|
||||||
|
.type = AVMEDIA_TYPE_AUDIO,
|
||||||
|
.name = "sdx2_dpcm",
|
||||||
|
.long_name = NULL_IF_CONFIG_SMALL("DPCM Squareroot-Delta-Exact"),
|
||||||
|
.props = AV_CODEC_PROP_LOSSY,
|
||||||
|
},
|
||||||
|
|
||||||
/* audio codecs */
|
/* audio codecs */
|
||||||
{
|
{
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
#include "mathops.h"
|
#include "mathops.h"
|
||||||
|
|
||||||
typedef struct DPCMContext {
|
typedef struct DPCMContext {
|
||||||
int16_t roq_square_array[256];
|
int16_t square_array[256];
|
||||||
int sample[2]; ///< previous sample (for SOL_DPCM)
|
int sample[2]; ///< previous sample (for SOL_DPCM)
|
||||||
const int8_t *sol_table; ///< delta table for SOL_DPCM
|
const int8_t *sol_table; ///< delta table for SOL_DPCM
|
||||||
} DPCMContext;
|
} DPCMContext;
|
||||||
@ -130,8 +130,8 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx)
|
|||||||
/* initialize square table */
|
/* initialize square table */
|
||||||
for (i = 0; i < 128; i++) {
|
for (i = 0; i < 128; i++) {
|
||||||
int16_t square = i * i;
|
int16_t square = i * i;
|
||||||
s->roq_square_array[i ] = square;
|
s->square_array[i ] = square;
|
||||||
s->roq_square_array[i + 128] = -square;
|
s->square_array[i + 128] = -square;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -153,6 +153,13 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx)
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -200,6 +207,9 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
|
|||||||
else
|
else
|
||||||
out = buf_size;
|
out = buf_size;
|
||||||
break;
|
break;
|
||||||
|
case AV_CODEC_ID_SDX2_DPCM:
|
||||||
|
out = buf_size;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (out <= 0) {
|
if (out <= 0) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
|
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 */
|
/* decode the samples */
|
||||||
while (output_samples < samples_end) {
|
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]);
|
predictor[ch] = av_clip_int16(predictor[ch]);
|
||||||
*output_samples++ = predictor[ch];
|
*output_samples++ = predictor[ch];
|
||||||
|
|
||||||
@ -318,6 +328,19 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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;
|
*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_INTERPLAY_DPCM, interplay_dpcm, "DPCM Interplay");
|
||||||
DPCM_DECODER(AV_CODEC_ID_ROQ_DPCM, roq_dpcm, "DPCM id RoQ");
|
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_SOL_DPCM, sol_dpcm, "DPCM Sol");
|
||||||
DPCM_DECODER(AV_CODEC_ID_XAN_DPCM, xan_dpcm, "DPCM Xan");
|
DPCM_DECODER(AV_CODEC_ID_XAN_DPCM, xan_dpcm, "DPCM Xan");
|
||||||
|
@ -2906,6 +2906,7 @@ int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
|
|||||||
case AV_CODEC_ID_PCM_S8_PLANAR:
|
case AV_CODEC_ID_PCM_S8_PLANAR:
|
||||||
case AV_CODEC_ID_PCM_U8:
|
case AV_CODEC_ID_PCM_U8:
|
||||||
case AV_CODEC_ID_PCM_ZORK:
|
case AV_CODEC_ID_PCM_ZORK:
|
||||||
|
case AV_CODEC_ID_SDX2_DPCM:
|
||||||
return 8;
|
return 8;
|
||||||
case AV_CODEC_ID_PCM_S16BE:
|
case AV_CODEC_ID_PCM_S16BE:
|
||||||
case AV_CODEC_ID_PCM_S16BE_PLANAR:
|
case AV_CODEC_ID_PCM_S16BE_PLANAR:
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#include "libavutil/version.h"
|
#include "libavutil/version.h"
|
||||||
|
|
||||||
#define LIBAVCODEC_VERSION_MAJOR 57
|
#define LIBAVCODEC_VERSION_MAJOR 57
|
||||||
#define LIBAVCODEC_VERSION_MINOR 9
|
#define LIBAVCODEC_VERSION_MINOR 10
|
||||||
#define LIBAVCODEC_VERSION_MICRO 100
|
#define LIBAVCODEC_VERSION_MICRO 100
|
||||||
|
|
||||||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
||||||
|
@ -52,6 +52,7 @@ static const AVCodecTag ff_codec_aiff_tags[] = {
|
|||||||
{ AV_CODEC_ID_ADPCM_IMA_QT, MKTAG('i','m','a','4') },
|
{ AV_CODEC_ID_ADPCM_IMA_QT, MKTAG('i','m','a','4') },
|
||||||
{ AV_CODEC_ID_QDM2, MKTAG('Q','D','M','2') },
|
{ AV_CODEC_ID_QDM2, MKTAG('Q','D','M','2') },
|
||||||
{ AV_CODEC_ID_QCELP, MKTAG('Q','c','l','p') },
|
{ AV_CODEC_ID_QCELP, MKTAG('Q','c','l','p') },
|
||||||
|
{ AV_CODEC_ID_SDX2_DPCM, MKTAG('S','D','X','2') },
|
||||||
{ AV_CODEC_ID_NONE, 0 },
|
{ AV_CODEC_ID_NONE, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -159,6 +159,7 @@ static int get_aiff_header(AVFormatContext *s, int size,
|
|||||||
codec->bits_per_coded_sample = 5;
|
codec->bits_per_coded_sample = 5;
|
||||||
case AV_CODEC_ID_ADPCM_G722:
|
case AV_CODEC_ID_ADPCM_G722:
|
||||||
case AV_CODEC_ID_MACE6:
|
case AV_CODEC_ID_MACE6:
|
||||||
|
case AV_CODEC_ID_SDX2_DPCM:
|
||||||
codec->block_align = 1*codec->channels;
|
codec->block_align = 1*codec->channels;
|
||||||
break;
|
break;
|
||||||
case AV_CODEC_ID_GSM:
|
case AV_CODEC_ID_GSM:
|
||||||
|
@ -84,6 +84,7 @@ static int genh_read_header(AVFormatContext *s)
|
|||||||
case 5: st->codec->codec_id = st->codec->block_align > 0 ?
|
case 5: st->codec->codec_id = st->codec->block_align > 0 ?
|
||||||
AV_CODEC_ID_PCM_S8_PLANAR :
|
AV_CODEC_ID_PCM_S8_PLANAR :
|
||||||
AV_CODEC_ID_PCM_S8; break;
|
AV_CODEC_ID_PCM_S8; break;
|
||||||
|
case 6: st->codec->codec_id = AV_CODEC_ID_SDX2_DPCM; break;
|
||||||
case 7: ret = ff_alloc_extradata(st->codec, 2);
|
case 7: ret = ff_alloc_extradata(st->codec, 2);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -168,6 +169,9 @@ static int genh_read_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
} else if (codec->codec_id == AV_CODEC_ID_SDX2_DPCM) {
|
||||||
|
ret = av_get_packet(s->pb, pkt, codec->block_align * 1024);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ret = av_get_packet(s->pb, pkt, codec->block_align ? codec->block_align : 1024 * codec->channels);
|
ret = av_get_packet(s->pb, pkt, codec->block_align ? codec->block_align : 1024 * codec->channels);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user