mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-12-08 06:09:50 +00:00
avcodec: add ADPCM IMA HVQM2 decoder
(cherry picked from commit 480e36592d5fc27a47e378d62570824613f26b7b)
This commit is contained in:
parent
1943b31cdd
commit
58c0711fca
5 changed files with 58 additions and 1 deletions
|
|
@ -986,7 +986,8 @@ OBJS-$(CONFIG_ADPCM_IMA_DK3_DECODER) += adpcm.o adpcm_data.o
|
||||||
OBJS-$(CONFIG_ADPCM_IMA_DK4_DECODER) += adpcm.o adpcm_data.o
|
OBJS-$(CONFIG_ADPCM_IMA_DK4_DECODER) += adpcm.o adpcm_data.o
|
||||||
OBJS-$(CONFIG_ADPCM_IMA_EA_EACS_DECODER) += adpcm.o adpcm_data.o
|
OBJS-$(CONFIG_ADPCM_IMA_EA_EACS_DECODER) += adpcm.o adpcm_data.o
|
||||||
OBJS-$(CONFIG_ADPCM_IMA_EA_SEAD_DECODER) += adpcm.o adpcm_data.o
|
OBJS-$(CONFIG_ADPCM_IMA_EA_SEAD_DECODER) += adpcm.o adpcm_data.o
|
||||||
OBJS-$(CONFIG_ADPCM_IMA_HVMQ4_DECODER) += adpcm.o adpcm_data.o
|
OBJS-$(CONFIG_ADPCM_IMA_HVQM2_DECODER) += adpcm.o adpcm_data.o
|
||||||
|
OBJS-$(CONFIG_ADPCM_IMA_HVQM4_DECODER) += adpcm.o adpcm_data.o
|
||||||
OBJS-$(CONFIG_ADPCM_IMA_ISS_DECODER) += adpcm.o adpcm_data.o
|
OBJS-$(CONFIG_ADPCM_IMA_ISS_DECODER) += adpcm.o adpcm_data.o
|
||||||
OBJS-$(CONFIG_ADPCM_IMA_MOFLEX_DECODER) += adpcm.o adpcm_data.o
|
OBJS-$(CONFIG_ADPCM_IMA_MOFLEX_DECODER) += adpcm.o adpcm_data.o
|
||||||
OBJS-$(CONFIG_ADPCM_IMA_MTF_DECODER) += adpcm.o adpcm_data.o
|
OBJS-$(CONFIG_ADPCM_IMA_MTF_DECODER) += adpcm.o adpcm_data.o
|
||||||
|
|
|
||||||
|
|
@ -548,6 +548,43 @@ int16_t ff_adpcm_ima_qt_expand_nibble(ADPCMChannelStatus *c, int nibble)
|
||||||
return c->predictor;
|
return c->predictor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void decode_adpcm_ima_hvqm2(AVCodecContext *avctx, int16_t *outbuf, int samples_to_do,
|
||||||
|
int frame_format, GetByteContext *gb)
|
||||||
|
{
|
||||||
|
ADPCMDecodeContext *c = avctx->priv_data;
|
||||||
|
int st = avctx->ch_layout.nb_channels == 2;
|
||||||
|
uint8_t nibble;
|
||||||
|
|
||||||
|
for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++) {
|
||||||
|
unsigned tmp;
|
||||||
|
|
||||||
|
switch (frame_format) {
|
||||||
|
case 0: /* combined hist+index */
|
||||||
|
tmp = bytestream2_get_be16(gb);
|
||||||
|
c->status[ch].predictor = sign_extend(tmp & 0xFF80, 16);
|
||||||
|
c->status[ch].step_index = tmp & 0x7f;
|
||||||
|
*outbuf++ = c->status[ch].predictor;
|
||||||
|
samples_to_do--;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
c->status[ch].step_index = av_clip(c->status[ch].step_index, 0, 88);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < samples_to_do; i++) {
|
||||||
|
if (!(i&1)) {
|
||||||
|
nibble = bytestream2_get_byte(gb);
|
||||||
|
*outbuf++ = ff_adpcm_ima_qt_expand_nibble(&c->status[st], nibble >> 4);
|
||||||
|
} else {
|
||||||
|
*outbuf++ = ff_adpcm_ima_qt_expand_nibble(&c->status[ 0], nibble & 0xF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bytestream2_seek(gb, 0, SEEK_END);
|
||||||
|
}
|
||||||
|
|
||||||
static void decode_adpcm_ima_hvqm4(AVCodecContext *avctx, int16_t *outbuf, int samples_to_do,
|
static void decode_adpcm_ima_hvqm4(AVCodecContext *avctx, int16_t *outbuf, int samples_to_do,
|
||||||
int frame_format, GetByteContext *gb)
|
int frame_format, GetByteContext *gb)
|
||||||
{
|
{
|
||||||
|
|
@ -1150,6 +1187,9 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
|
||||||
*coded_samples -= *coded_samples % 28;
|
*coded_samples -= *coded_samples % 28;
|
||||||
nb_samples = (buf_size - 12) / (ch == 2 ? 30 : 15) * 28;
|
nb_samples = (buf_size - 12) / (ch == 2 ? 30 : 15) * 28;
|
||||||
break;
|
break;
|
||||||
|
case AV_CODEC_ID_ADPCM_IMA_HVQM2:
|
||||||
|
nb_samples = ((bytestream2_peek_be64(gb) >> 16) & 0xFFFF);
|
||||||
|
break;
|
||||||
case AV_CODEC_ID_ADPCM_IMA_HVQM4:
|
case AV_CODEC_ID_ADPCM_IMA_HVQM4:
|
||||||
{
|
{
|
||||||
int frame_format = bytestream2_get_be16(gb);
|
int frame_format = bytestream2_get_be16(gb);
|
||||||
|
|
@ -1755,6 +1795,12 @@ static int adpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame,
|
||||||
*samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F, 3);
|
*samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F, 3);
|
||||||
}
|
}
|
||||||
) /* End of CASE */
|
) /* End of CASE */
|
||||||
|
CASE(ADPCM_IMA_HVQM2,
|
||||||
|
int format = bytestream2_get_be16(&gb);
|
||||||
|
|
||||||
|
bytestream2_skip(&gb, 4);
|
||||||
|
decode_adpcm_ima_hvqm2(avctx, samples, nb_samples, format, &gb);
|
||||||
|
) /* End of CASE */
|
||||||
CASE(ADPCM_IMA_HVQM4,
|
CASE(ADPCM_IMA_HVQM4,
|
||||||
int format = bytestream2_get_be16(&gb);
|
int format = bytestream2_get_be16(&gb);
|
||||||
|
|
||||||
|
|
@ -2813,6 +2859,7 @@ ADPCM_DECODER(ADPCM_IMA_DK3, sample_fmts_s16, adpcm_ima_dk3, "ADPCM IMA
|
||||||
ADPCM_DECODER(ADPCM_IMA_DK4, sample_fmts_s16, adpcm_ima_dk4, "ADPCM IMA Duck DK4")
|
ADPCM_DECODER(ADPCM_IMA_DK4, sample_fmts_s16, adpcm_ima_dk4, "ADPCM IMA Duck DK4")
|
||||||
ADPCM_DECODER(ADPCM_IMA_EA_EACS, sample_fmts_s16, adpcm_ima_ea_eacs, "ADPCM IMA Electronic Arts EACS")
|
ADPCM_DECODER(ADPCM_IMA_EA_EACS, sample_fmts_s16, adpcm_ima_ea_eacs, "ADPCM IMA Electronic Arts EACS")
|
||||||
ADPCM_DECODER(ADPCM_IMA_EA_SEAD, sample_fmts_s16, adpcm_ima_ea_sead, "ADPCM IMA Electronic Arts SEAD")
|
ADPCM_DECODER(ADPCM_IMA_EA_SEAD, sample_fmts_s16, adpcm_ima_ea_sead, "ADPCM IMA Electronic Arts SEAD")
|
||||||
|
ADPCM_DECODER(ADPCM_IMA_HVQM2, sample_fmts_s16, adpcm_ima_hvqm2, "ADPCM IMA HVQM2")
|
||||||
ADPCM_DECODER(ADPCM_IMA_HVQM4, sample_fmts_s16, adpcm_ima_hvqm4, "ADPCM IMA HVQM4")
|
ADPCM_DECODER(ADPCM_IMA_HVQM4, sample_fmts_s16, adpcm_ima_hvqm4, "ADPCM IMA HVQM4")
|
||||||
ADPCM_DECODER(ADPCM_IMA_ISS, sample_fmts_s16, adpcm_ima_iss, "ADPCM IMA Funcom ISS")
|
ADPCM_DECODER(ADPCM_IMA_ISS, sample_fmts_s16, adpcm_ima_iss, "ADPCM IMA Funcom ISS")
|
||||||
ADPCM_DECODER(ADPCM_IMA_MOFLEX, sample_fmts_s16p, adpcm_ima_moflex, "ADPCM IMA MobiClip MOFLEX")
|
ADPCM_DECODER(ADPCM_IMA_MOFLEX, sample_fmts_s16p, adpcm_ima_moflex, "ADPCM IMA MobiClip MOFLEX")
|
||||||
|
|
|
||||||
|
|
@ -677,6 +677,7 @@ extern const FFCodec ff_adpcm_ima_dk3_decoder;
|
||||||
extern const FFCodec ff_adpcm_ima_dk4_decoder;
|
extern const FFCodec ff_adpcm_ima_dk4_decoder;
|
||||||
extern const FFCodec ff_adpcm_ima_ea_eacs_decoder;
|
extern const FFCodec ff_adpcm_ima_ea_eacs_decoder;
|
||||||
extern const FFCodec ff_adpcm_ima_ea_sead_decoder;
|
extern const FFCodec ff_adpcm_ima_ea_sead_decoder;
|
||||||
|
extern const FFCodec ff_adpcm_ima_hvqm2_decoder;
|
||||||
extern const FFCodec ff_adpcm_ima_hvqm4_decoder;
|
extern const FFCodec ff_adpcm_ima_hvqm4_decoder;
|
||||||
extern const FFCodec ff_adpcm_ima_iss_decoder;
|
extern const FFCodec ff_adpcm_ima_iss_decoder;
|
||||||
extern const FFCodec ff_adpcm_ima_moflex_decoder;
|
extern const FFCodec ff_adpcm_ima_moflex_decoder;
|
||||||
|
|
|
||||||
|
|
@ -2655,6 +2655,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
|
||||||
.long_name = NULL_IF_CONFIG_SMALL("ADPCM Silicon Graphics N64"),
|
.long_name = NULL_IF_CONFIG_SMALL("ADPCM Silicon Graphics N64"),
|
||||||
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
|
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.id = AV_CODEC_ID_ADPCM_IMA_HVQM2,
|
||||||
|
.type = AVMEDIA_TYPE_AUDIO,
|
||||||
|
.name = "adpcm_ima_hvqm2",
|
||||||
|
.long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA HVQM2"),
|
||||||
|
.props = AV_CODEC_PROP_LOSSY,
|
||||||
|
},
|
||||||
|
|
||||||
/* AMR */
|
/* AMR */
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -430,6 +430,7 @@ enum AVCodecID {
|
||||||
AV_CODEC_ID_ADPCM_IMA_HVQM4,
|
AV_CODEC_ID_ADPCM_IMA_HVQM4,
|
||||||
AV_CODEC_ID_ADPCM_IMA_PDA,
|
AV_CODEC_ID_ADPCM_IMA_PDA,
|
||||||
AV_CODEC_ID_ADPCM_N64,
|
AV_CODEC_ID_ADPCM_N64,
|
||||||
|
AV_CODEC_ID_ADPCM_IMA_HVQM2,
|
||||||
|
|
||||||
/* AMR */
|
/* AMR */
|
||||||
AV_CODEC_ID_AMR_NB = 0x12000,
|
AV_CODEC_ID_AMR_NB = 0x12000,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue