mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-21 10:55:51 +02:00
avcodec: add ADPCM XMD decoder
This commit is contained in:
parent
9bfdd8524e
commit
280e6e93fc
@ -34,6 +34,7 @@ version <next>:
|
||||
- ssim360 video filter
|
||||
- ffmpeg CLI new options: -enc_stats_pre[_fmt], -enc_stats_post[_fmt]
|
||||
- hstack_vaapi, vstack_vaapi and xstack_vaapi filters
|
||||
- XMD ADPCM decoder
|
||||
|
||||
|
||||
version 5.1:
|
||||
|
@ -959,6 +959,7 @@ OBJS-$(CONFIG_ADPCM_THP_DECODER) += adpcm.o adpcm_data.o
|
||||
OBJS-$(CONFIG_ADPCM_THP_LE_DECODER) += adpcm.o adpcm_data.o
|
||||
OBJS-$(CONFIG_ADPCM_VIMA_DECODER) += vima.o adpcm_data.o
|
||||
OBJS-$(CONFIG_ADPCM_XA_DECODER) += adpcm.o adpcm_data.o
|
||||
OBJS-$(CONFIG_ADPCM_XMD_DECODER) += adpcm.o adpcm_data.o
|
||||
OBJS-$(CONFIG_ADPCM_YAMAHA_DECODER) += adpcm.o adpcm_data.o
|
||||
OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcmenc.o adpcm_data.o
|
||||
OBJS-$(CONFIG_ADPCM_ZORK_DECODER) += adpcm.o adpcm_data.o
|
||||
|
@ -324,6 +324,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx)
|
||||
case AV_CODEC_ID_ADPCM_IMA_WAV:
|
||||
case AV_CODEC_ID_ADPCM_4XM:
|
||||
case AV_CODEC_ID_ADPCM_XA:
|
||||
case AV_CODEC_ID_ADPCM_XMD:
|
||||
case AV_CODEC_ID_ADPCM_EA_R1:
|
||||
case AV_CODEC_ID_ADPCM_EA_R2:
|
||||
case AV_CODEC_ID_ADPCM_EA_R3:
|
||||
@ -1043,6 +1044,9 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
|
||||
case AV_CODEC_ID_ADPCM_XA:
|
||||
nb_samples = (buf_size / 128) * 224 / ch;
|
||||
break;
|
||||
case AV_CODEC_ID_ADPCM_XMD:
|
||||
nb_samples = buf_size / (21 * ch) * 32;
|
||||
break;
|
||||
case AV_CODEC_ID_ADPCM_DTK:
|
||||
case AV_CODEC_ID_ADPCM_PSX:
|
||||
nb_samples = buf_size / (16 * ch) * 28;
|
||||
@ -1553,6 +1557,45 @@ static int adpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame,
|
||||
}
|
||||
bytestream2_seek(&gb, 0, SEEK_END);
|
||||
) /* End of CASE */
|
||||
CASE(ADPCM_XMD,
|
||||
int bytes_remaining, block = 0;
|
||||
while (bytestream2_get_bytes_left(&gb) >= 21 * channels) {
|
||||
for (int channel = 0; channel < channels; channel++) {
|
||||
int16_t *out = samples_p[channel] + block * 32;
|
||||
int16_t history[2];
|
||||
uint16_t scale;
|
||||
|
||||
history[1] = sign_extend(bytestream2_get_le16(&gb), 16);
|
||||
history[0] = sign_extend(bytestream2_get_le16(&gb), 16);
|
||||
scale = bytestream2_get_le16(&gb);
|
||||
|
||||
out[0] = history[1];
|
||||
out[1] = history[0];
|
||||
|
||||
for (int n = 0; n < 15; n++) {
|
||||
unsigned byte = bytestream2_get_byte(&gb);
|
||||
int32_t nibble[2];
|
||||
|
||||
nibble[0] = sign_extend(byte & 15, 4);
|
||||
nibble[1] = sign_extend(byte >> 4, 4);
|
||||
|
||||
out[2+n*2] = (nibble[0]*(scale<<14) + (history[0]*29336) - (history[1]*13136)) >> 14;
|
||||
history[1] = history[0];
|
||||
history[0] = out[2+n*2];
|
||||
|
||||
out[2+n*2+1] = (nibble[1]*(scale<<14) + (history[0]*29336) - (history[1]*13136)) >> 14;
|
||||
history[1] = history[0];
|
||||
history[0] = out[2+n*2+1];
|
||||
}
|
||||
}
|
||||
|
||||
block++;
|
||||
}
|
||||
bytes_remaining = bytestream2_get_bytes_left(&gb);
|
||||
if (bytes_remaining > 0) {
|
||||
bytestream2_skip(&gb, bytes_remaining);
|
||||
}
|
||||
) /* End of CASE */
|
||||
CASE(ADPCM_XA,
|
||||
int16_t *out0 = samples_p[0];
|
||||
int16_t *out1 = samples_p[1];
|
||||
@ -2350,5 +2393,6 @@ ADPCM_DECODER(ADPCM_SWF, sample_fmts_s16, adpcm_swf, "ADPCM Sho
|
||||
ADPCM_DECODER(ADPCM_THP_LE, sample_fmts_s16p, adpcm_thp_le, "ADPCM Nintendo THP (little-endian)")
|
||||
ADPCM_DECODER(ADPCM_THP, sample_fmts_s16p, adpcm_thp, "ADPCM Nintendo THP")
|
||||
ADPCM_DECODER(ADPCM_XA, sample_fmts_s16p, adpcm_xa, "ADPCM CDROM XA")
|
||||
ADPCM_DECODER(ADPCM_XMD, sample_fmts_s16p, adpcm_xmd, "ADPCM Konami XMD")
|
||||
ADPCM_DECODER(ADPCM_YAMAHA, sample_fmts_s16, adpcm_yamaha, "ADPCM Yamaha")
|
||||
ADPCM_DECODER(ADPCM_ZORK, sample_fmts_s16, adpcm_zork, "ADPCM Zork")
|
||||
|
@ -695,6 +695,7 @@ extern const FFCodec ff_adpcm_thp_decoder;
|
||||
extern const FFCodec ff_adpcm_thp_le_decoder;
|
||||
extern const FFCodec ff_adpcm_vima_decoder;
|
||||
extern const FFCodec ff_adpcm_xa_decoder;
|
||||
extern const FFCodec ff_adpcm_xmd_decoder;
|
||||
extern const FFCodec ff_adpcm_yamaha_encoder;
|
||||
extern const FFCodec ff_adpcm_yamaha_decoder;
|
||||
extern const FFCodec ff_adpcm_zork_decoder;
|
||||
|
@ -2536,6 +2536,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
|
||||
.long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Acorn Replay"),
|
||||
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
|
||||
},
|
||||
{
|
||||
.id = AV_CODEC_ID_ADPCM_XMD,
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.name = "adpcm_xmd",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("ADPCM Konami XMD"),
|
||||
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
|
||||
},
|
||||
|
||||
/* AMR */
|
||||
{
|
||||
|
@ -413,6 +413,7 @@ enum AVCodecID {
|
||||
AV_CODEC_ID_ADPCM_IMA_CUNNING,
|
||||
AV_CODEC_ID_ADPCM_IMA_MOFLEX,
|
||||
AV_CODEC_ID_ADPCM_IMA_ACORN,
|
||||
AV_CODEC_ID_ADPCM_XMD,
|
||||
|
||||
/* AMR */
|
||||
AV_CODEC_ID_AMR_NB = 0x12000,
|
||||
|
@ -769,6 +769,9 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba,
|
||||
case AV_CODEC_ID_ADPCM_MTAF:
|
||||
tmp = blocks * (ba - 16LL) * 2 / ch;
|
||||
break;
|
||||
case AV_CODEC_ID_ADPCM_XMD:
|
||||
tmp = blocks * 32;
|
||||
break;
|
||||
}
|
||||
if (tmp) {
|
||||
if (tmp != (int)tmp)
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
#include "version_major.h"
|
||||
|
||||
#define LIBAVCODEC_VERSION_MINOR 59
|
||||
#define LIBAVCODEC_VERSION_MINOR 60
|
||||
#define LIBAVCODEC_VERSION_MICRO 100
|
||||
|
||||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
||||
|
Loading…
Reference in New Issue
Block a user