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_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
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue