avcodec: add ADPCM IMA HVQM2 decoder

(cherry picked from commit 480e36592d5fc27a47e378d62570824613f26b7b)
This commit is contained in:
Paul B Mahol 2024-11-25 19:06:53 +00:00 committed by michaelni
parent 1943b31cdd
commit 58c0711fca
5 changed files with 58 additions and 1 deletions

View file

@ -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_EA_EACS_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_MOFLEX_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_IMA_MTF_DECODER) += adpcm.o adpcm_data.o

View file

@ -548,6 +548,43 @@ int16_t ff_adpcm_ima_qt_expand_nibble(ADPCMChannelStatus *c, int nibble)
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,
int frame_format, GetByteContext *gb)
{
@ -1150,6 +1187,9 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
*coded_samples -= *coded_samples % 28;
nb_samples = (buf_size - 12) / (ch == 2 ? 30 : 15) * 28;
break;
case AV_CODEC_ID_ADPCM_IMA_HVQM2:
nb_samples = ((bytestream2_peek_be64(gb) >> 16) & 0xFFFF);
break;
case AV_CODEC_ID_ADPCM_IMA_HVQM4:
{
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);
}
) /* 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,
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_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_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_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")

View file

@ -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_ea_eacs_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_iss_decoder;
extern const FFCodec ff_adpcm_ima_moflex_decoder;

View file

@ -2655,6 +2655,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("ADPCM Silicon Graphics N64"),
.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 */
{

View file

@ -430,6 +430,7 @@ enum AVCodecID {
AV_CODEC_ID_ADPCM_IMA_HVQM4,
AV_CODEC_ID_ADPCM_IMA_PDA,
AV_CODEC_ID_ADPCM_N64,
AV_CODEC_ID_ADPCM_IMA_HVQM2,
/* AMR */
AV_CODEC_ID_AMR_NB = 0x12000,