* [FFmpeg-devel] [PATCH] A few new decoders and a parser from almpeg (PR #20325)
@ 2025-08-24 3:01 michaelni via ffmpeg-devel
0 siblings, 0 replies; only message in thread
From: michaelni via ffmpeg-devel @ 2025-08-24 3:01 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: michaelni
PR #20325 opened by michaelni
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20325
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20325.patch
These are taken from before the switch to GPLv3+
If people prefer, we can merge the GPLv3+ switch for these modules too and put them under --enable-gpl and --enable-v3
From 560ebf42e09e4e378c420908f2eed81d893f9df6 Mon Sep 17 00:00:00 2001
From: Paul B Mahol <onemda@gmail.com>
Date: Mon, 18 Nov 2024 19:04:23 +0000
Subject: [PATCH 01/15] avcodec: add AHX decoder
(cherry picked from commit 039dc23d185214b8b0ef2bbccae197ceb5ad42a2)
---
libavcodec/Makefile | 1 +
libavcodec/allcodecs.c | 1 +
libavcodec/bitstream_filters.c | 1 +
libavcodec/bsf/Makefile | 1 +
libavcodec/bsf/ahx_to_mp2.c | 62 ++++++++++++++++++++++++++++++
libavcodec/codec_desc.c | 7 ++++
libavcodec/codec_id.h | 1 +
libavcodec/mpegaudiodec_float.c | 18 +++++++++
libavcodec/mpegaudiodec_template.c | 3 +-
9 files changed, 94 insertions(+), 1 deletion(-)
create mode 100644 libavcodec/bsf/ahx_to_mp2.c
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 3d036de4b6..e1cce1275b 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -219,6 +219,7 @@ OBJS-$(CONFIG_AC3_FIXED_ENCODER) += ac3enc_fixed.o ac3enc.o ac3tab.o ac3.o
OBJS-$(CONFIG_AC3_MF_ENCODER) += mfenc.o mf_utils.o
OBJS-$(CONFIG_ACELP_KELVIN_DECODER) += g729dec.o lsp.o celp_filters.o acelp_filters.o acelp_pitch_delay.o acelp_vectors.o g729postfilter.o
OBJS-$(CONFIG_AGM_DECODER) += agm.o jpegquanttables.o
+OBJS-$(CONFIG_AHX_DECODER) += mpegaudiodec_float.o
OBJS-$(CONFIG_AIC_DECODER) += aic.o
OBJS-$(CONFIG_ALAC_DECODER) += alac.o alac_data.o alacdsp.o
OBJS-$(CONFIG_ALAC_ENCODER) += alacenc.o alac_data.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index f5ec2e01e8..017d100848 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -434,6 +434,7 @@ extern const FFCodec ff_ac3_decoder;
extern const FFCodec ff_ac3_fixed_encoder;
extern const FFCodec ff_ac3_fixed_decoder;
extern const FFCodec ff_acelp_kelvin_decoder;
+extern const FFCodec ff_ahx_decoder;
extern const FFCodec ff_alac_encoder;
extern const FFCodec ff_alac_decoder;
extern const FFCodec ff_als_decoder;
diff --git a/libavcodec/bitstream_filters.c b/libavcodec/bitstream_filters.c
index c277bc1a71..b4b852c7e6 100644
--- a/libavcodec/bitstream_filters.c
+++ b/libavcodec/bitstream_filters.c
@@ -25,6 +25,7 @@
#include "bsf_internal.h"
extern const FFBitStreamFilter ff_aac_adtstoasc_bsf;
+extern const FFBitStreamFilter ff_ahx_to_mp2_bsf;
extern const FFBitStreamFilter ff_apv_metadata_bsf;
extern const FFBitStreamFilter ff_av1_frame_merge_bsf;
extern const FFBitStreamFilter ff_av1_frame_split_bsf;
diff --git a/libavcodec/bsf/Makefile b/libavcodec/bsf/Makefile
index 8e2e6f7b14..48a2f85ac7 100644
--- a/libavcodec/bsf/Makefile
+++ b/libavcodec/bsf/Makefile
@@ -3,6 +3,7 @@ clean::
OBJS-$(CONFIG_AAC_ADTSTOASC_BSF) += bsf/aac_adtstoasc.o
OBJS-$(CONFIG_APV_METADATA_BSF) += bsf/apv_metadata.o
+OBJS-$(CONFIG_AHX_TO_MP2_BSF) += bsf/ahx_to_mp2.o
OBJS-$(CONFIG_AV1_FRAME_MERGE_BSF) += bsf/av1_frame_merge.o
OBJS-$(CONFIG_AV1_FRAME_SPLIT_BSF) += bsf/av1_frame_split.o
OBJS-$(CONFIG_AV1_METADATA_BSF) += bsf/av1_metadata.o
diff --git a/libavcodec/bsf/ahx_to_mp2.c b/libavcodec/bsf/ahx_to_mp2.c
new file mode 100644
index 0000000000..eae71fe5ee
--- /dev/null
+++ b/libavcodec/bsf/ahx_to_mp2.c
@@ -0,0 +1,62 @@
+/*
+ * AHX to MP2 bitstream filter
+ * Copyright (c) 2024 Paul B Mahol
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * AHX to MP2 bitstream filter.
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "bsf.h"
+#include "bsf_internal.h"
+
+static av_cold int init(AVBSFContext *ctx)
+{
+ ctx->par_out->codec_id = AV_CODEC_ID_MP2;
+
+ return 0;
+}
+
+static int filter(AVBSFContext *ctx, AVPacket *pkt)
+{
+ int ret;
+
+ ret = ff_bsf_get_packet_ref(ctx, pkt);
+ if (ret < 0)
+ return ret;
+
+ if (pkt->size < 1044) {
+ ret = av_grow_packet(pkt, 1044-pkt->size);
+ if (ret < 0) {
+ av_packet_unref(pkt);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+const FFBitStreamFilter ff_ahx_to_mp2_bsf = {
+ .p.name = "ahx_to_mp2",
+ .p.codec_ids = (const enum AVCodecID []){ AV_CODEC_ID_AHX, AV_CODEC_ID_NONE },
+ .init = init,
+ .filter = filter,
+};
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index a065556e51..284d1861c4 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -3495,6 +3495,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("G.728"),
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
},
+ {
+ .id = AV_CODEC_ID_AHX,
+ .type = AVMEDIA_TYPE_AUDIO,
+ .name = "ahx",
+ .long_name = NULL_IF_CONFIG_SMALL("CRI AHX"),
+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+ },
/* subtitle codecs */
{
diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
index c4842e61ff..455bc4b839 100644
--- a/libavcodec/codec_id.h
+++ b/libavcodec/codec_id.h
@@ -556,6 +556,7 @@ enum AVCodecID {
AV_CODEC_ID_QOA,
AV_CODEC_ID_LC3,
AV_CODEC_ID_G728,
+ AV_CODEC_ID_AHX,
/* subtitle codecs */
AV_CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs.
diff --git a/libavcodec/mpegaudiodec_float.c b/libavcodec/mpegaudiodec_float.c
index 05e2e399e4..232e2fa201 100644
--- a/libavcodec/mpegaudiodec_float.c
+++ b/libavcodec/mpegaudiodec_float.c
@@ -103,6 +103,24 @@ const FFCodec ff_mp2float_decoder = {
CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLT),
};
#endif
+#if CONFIG_AHX_DECODER
+const FFCodec ff_ahx_decoder = {
+ .p.name = "ahx",
+ CODEC_LONG_NAME("CRI AHX"),
+ .p.type = AVMEDIA_TYPE_AUDIO,
+ .p.id = AV_CODEC_ID_AHX,
+ .priv_data_size = sizeof(MPADecodeContext),
+ .init = decode_init,
+ FF_CODEC_DECODE_CB(decode_frame),
+ .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
+ AV_CODEC_CAP_DR1,
+ .flush = flush,
+ .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
+ AV_SAMPLE_FMT_FLT,
+ AV_SAMPLE_FMT_NONE },
+ .bsfs = "ahx_to_mp2",
+};
+#endif
#if CONFIG_MP3FLOAT_DECODER
const FFCodec ff_mp3float_decoder = {
.p.name = "mp3float",
diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c
index d7c5210eb8..005e9ba2fa 100644
--- a/libavcodec/mpegaudiodec_template.c
+++ b/libavcodec/mpegaudiodec_template.c
@@ -1604,7 +1604,8 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
if (ret >= 0) {
s->frame->nb_samples = avctx->frame_size;
*got_frame_ptr = 1;
- avctx->sample_rate = s->sample_rate;
+ if (avctx->codec_id != AV_CODEC_ID_AHX)
+ avctx->sample_rate = s->sample_rate;
//FIXME maybe move the other codec info stuff from above here too
} else {
av_log(avctx, AV_LOG_ERROR, "Error while decoding MPEG audio frame.\n");
--
2.49.1
From 8a11b844ff4fb4596be42ac9714060f718426212 Mon Sep 17 00:00:00 2001
From: Paul B Mahol <onemda@gmail.com>
Date: Tue, 19 Nov 2024 09:20:52 +0000
Subject: [PATCH 02/15] avcodec: add AHX parser
(cherry picked from commit ddcb47c4c512bf49b22cc6b2d07fade0f96377e3)
---
libavcodec/Makefile | 1 +
libavcodec/ahx_parser.c | 78 +++++++++++++++++++++++++++++++++++++++++
libavcodec/parsers.c | 1 +
3 files changed, 80 insertions(+)
create mode 100644 libavcodec/ahx_parser.c
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index e1cce1275b..3005e4a31a 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1217,6 +1217,7 @@ OBJS-$(CONFIG_AAC_PARSER) += aac_parser.o aac_ac3_parser.o
OBJS-$(CONFIG_AC3_PARSER) += aac_ac3_parser.o ac3tab.o \
ac3_channel_layout_tab.o
OBJS-$(CONFIG_ADX_PARSER) += adx_parser.o
+OBJS-$(CONFIG_AHX_PARSER) += ahx_parser.o
OBJS-$(CONFIG_AMR_PARSER) += amr_parser.o
OBJS-$(CONFIG_APV_PARSER) += apv_parser.o
OBJS-$(CONFIG_AV1_PARSER) += av1_parser.o av1_parse.o
diff --git a/libavcodec/ahx_parser.c b/libavcodec/ahx_parser.c
new file mode 100644
index 0000000000..4be037f666
--- /dev/null
+++ b/libavcodec/ahx_parser.c
@@ -0,0 +1,78 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * AHX audio parser
+ *
+ * Splits packets into individual blocks.
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "parser.h"
+
+typedef struct AHXParseContext {
+ ParseContext pc;
+ uint32_t header;
+ int size;
+} AHXParseContext;
+
+static int ahx_parse(AVCodecParserContext *s1,
+ AVCodecContext *avctx,
+ const uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size)
+{
+ AHXParseContext *s = s1->priv_data;
+ ParseContext *pc = &s->pc;
+ uint32_t state = pc->state;
+ int next = END_NOT_FOUND;
+
+ for (int i = 0; i < buf_size; i++) {
+ state = (state << 8) | buf[i];
+ s->size++;
+ if (s->size == 4 && !s->header)
+ s->header = state;
+ if (s->size > 4 && state == s->header) {
+ next = i - 3;
+ s->size = 0;
+ break;
+ }
+ }
+ pc->state = state;
+
+ if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
+ *poutbuf = NULL;
+ *poutbuf_size = 0;
+ return buf_size;
+ }
+
+ s1->duration = 1152;
+ s1->key_frame = 1;
+
+ *poutbuf = buf;
+ *poutbuf_size = buf_size;
+
+ return next;
+}
+
+const AVCodecParser ff_ahx_parser = {
+ .codec_ids = { AV_CODEC_ID_AHX },
+ .priv_data_size = sizeof(AHXParseContext),
+ .parser_parse = ahx_parse,
+ .parser_close = ff_parse_close,
+};
diff --git a/libavcodec/parsers.c b/libavcodec/parsers.c
index b12c48f79f..42b40643f9 100644
--- a/libavcodec/parsers.c
+++ b/libavcodec/parsers.c
@@ -24,6 +24,7 @@ extern const AVCodecParser ff_aac_parser;
extern const AVCodecParser ff_aac_latm_parser;
extern const AVCodecParser ff_ac3_parser;
extern const AVCodecParser ff_adx_parser;
+extern const AVCodecParser ff_ahx_parser;
extern const AVCodecParser ff_amr_parser;
extern const AVCodecParser ff_apv_parser;
extern const AVCodecParser ff_av1_parser;
--
2.49.1
From 87faa2fa9048f6edd6ed45f285e9dcfa735600b9 Mon Sep 17 00:00:00 2001
From: Paul B Mahol <onemda@gmail.com>
Date: Sun, 1 Aug 2021 21:12:55 +0200
Subject: [PATCH 03/15] avcodec: add ADPCM IMA HVQM4 decoder
Signed-off-by: Paul B Mahol <onemda@gmail.com>
(cherry picked from commit bae3cecfa6f1fbc765d95d84ef4a377aedbca8bb)
---
libavcodec/Makefile | 1 +
libavcodec/adpcm.c | 64 +++++++++++++++++++++++++++++++++++++++++
libavcodec/allcodecs.c | 1 +
libavcodec/codec_desc.c | 7 +++++
libavcodec/codec_id.h | 1 +
5 files changed, 74 insertions(+)
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 3005e4a31a..6311cd1821 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -984,6 +984,7 @@ 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_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
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index 4c15be6207..bc3b0c9730 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -544,6 +544,49 @@ int16_t ff_adpcm_ima_qt_expand_nibble(ADPCMChannelStatus *c, int nibble)
return c->predictor;
}
+static void decode_adpcm_ima_hvqm4(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;
+ unsigned tmp;
+
+ for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++) {
+ switch (frame_format) {
+ case 1: /* combined hist+index */
+ tmp = bytestream2_get_be16(gb);
+ c->status[ch].predictor = sign_extend(tmp & 0xFF80, 16);
+ c->status[ch].step_index = tmp & 0x7f;
+ break;
+ case 2: /* no hist/index (continues from previous frame) */
+ default:
+ break;
+ case 3: /* separate hist+index */
+ tmp = bytestream2_get_be16(gb);
+ c->status[ch].predictor = sign_extend(tmp, 16);
+ c->status[ch].step_index = bytestream2_get_byte(gb);
+ break;
+ }
+
+ c->status[ch].step_index = av_clip(c->status[ch].step_index, 0, 88);
+ }
+
+ if (frame_format == 1 || frame_format == 3) {
+ for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++)
+ *outbuf++ = (int16_t)c->status[st - ch].predictor;
+ samples_to_do--;
+ }
+
+ for (int i = 0; i < samples_to_do; i++) {
+ uint8_t nibble = bytestream2_get_byte(gb);
+
+ *outbuf++ = ff_adpcm_ima_qt_expand_nibble(&c->status[st], nibble & 0xF);
+ *outbuf++ = ff_adpcm_ima_qt_expand_nibble(&c->status[ 0], nibble >> 4);
+ }
+
+ bytestream2_seek(gb, 0, SEEK_END);
+}
+
static inline int16_t adpcm_ms_expand_nibble(ADPCMChannelStatus *c, int nibble)
{
int predictor;
@@ -1100,6 +1143,20 @@ 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_HVQM4:
+ {
+ int frame_format = bytestream2_get_be16(gb);
+ int skip = 6;
+
+ if (frame_format == 1)
+ skip += 2 * ch;
+ if (frame_format == 3)
+ skip += 3 * ch;
+
+ nb_samples = (buf_size - skip) * 2 / ch;
+ bytestream2_seek(gb, 0, SEEK_SET);
+ }
+ break;
case AV_CODEC_ID_ADPCM_IMA_EA_EACS:
has_coded_samples = 1;
*coded_samples = bytestream2_get_le32(gb);
@@ -1686,6 +1743,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_HVQM4,
+ int format = bytestream2_get_be16(&gb);
+
+ bytestream2_skip(&gb, 4);
+ decode_adpcm_ima_hvqm4(avctx, samples, nb_samples, format, &gb);
+ ) /* End of CASE */
CASE(ADPCM_IMA_SSI,
for (int n = nb_samples >> (1 - st); n > 0; n--) {
int v = bytestream2_get_byteu(&gb);
@@ -2636,6 +2699,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_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")
ADPCM_DECODER(ADPCM_IMA_MTF, sample_fmts_s16, adpcm_ima_mtf, "ADPCM IMA Capcom's MT Framework")
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 017d100848..b81dda8161 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -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_hvqm4_decoder;
extern const FFCodec ff_adpcm_ima_iss_decoder;
extern const FFCodec ff_adpcm_ima_moflex_decoder;
extern const FFCodec ff_adpcm_ima_mtf_decoder;
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 284d1861c4..101aabb11c 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -2634,6 +2634,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("ADPCM Sanyo"),
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
},
+ {
+ .id = AV_CODEC_ID_ADPCM_IMA_HVQM4,
+ .type = AVMEDIA_TYPE_AUDIO,
+ .name = "adpcm_ima_hvqm4",
+ .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA HVQM4"),
+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+ },
/* AMR */
{
diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
index 455bc4b839..ee964184a5 100644
--- a/libavcodec/codec_id.h
+++ b/libavcodec/codec_id.h
@@ -427,6 +427,7 @@ enum AVCodecID {
AV_CODEC_ID_ADPCM_XMD,
AV_CODEC_ID_ADPCM_IMA_XBOX,
AV_CODEC_ID_ADPCM_SANYO,
+ AV_CODEC_ID_ADPCM_IMA_HVQM4,
/* AMR */
AV_CODEC_ID_AMR_NB = 0x12000,
--
2.49.1
From 2f541e6f871d801c2b5bb465aea057ffb48e1b0e Mon Sep 17 00:00:00 2001
From: Paul B Mahol <onemda@gmail.com>
Date: Mon, 13 May 2024 10:20:06 +0200
Subject: [PATCH 04/15] avcodec: add ADPCM IMA PDA decoder
(cherry picked from commit ab9f7513d55cfd87d1a1ce22d02abffbfb9bb296)
---
libavcodec/Makefile | 1 +
libavcodec/adpcm.c | 25 +++++++++++++++++++++++++
libavcodec/allcodecs.c | 1 +
libavcodec/codec_desc.c | 7 +++++++
libavcodec/codec_id.h | 1 +
libavcodec/utils.c | 1 +
6 files changed, 36 insertions(+)
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 6311cd1821..5a325bf174 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -988,6 +988,7 @@ OBJS-$(CONFIG_ADPCM_IMA_HVMQ4_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
+OBJS-$(CONFIG_ADPCM_IMA_PDA_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_IMA_OKI_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_IMA_QT_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_IMA_QT_ENCODER) += adpcmenc.o adpcm_data.o
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index bc3b0c9730..55e48d193d 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -1207,6 +1207,11 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
buf_size = FFMIN(buf_size, avctx->block_align);
nb_samples = (buf_size - 4 * ch) * 2 / ch;
break;
+ case AV_CODEC_ID_ADPCM_IMA_PDA:
+ if (avctx->block_align > 0)
+ buf_size = FFMIN(buf_size, avctx->block_align);
+ nb_samples = (buf_size - 4 * ch) * 2 / ch;
+ break;
CASE(ADPCM_IMA_WAV,
int bsize = ff_adpcm_ima_block_sizes[avctx->bits_per_coded_sample - 2];
int bsamples = ff_adpcm_ima_block_samples[avctx->bits_per_coded_sample - 2];
@@ -2202,6 +2207,25 @@ static int adpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame,
}
}
) /* End of CASE */
+ CASE(ADPCM_IMA_PDA,
+ for (int i = 0; i < channels; i++) {
+ c->status[i].predictor = sign_extend(bytestream2_get_le16u(&gb), 16);
+ c->status[i].step_index = bytestream2_get_byteu(&gb);
+ bytestream2_skipu(&gb, 1);
+ if (c->status[i].step_index > 88u) {
+ av_log(avctx, AV_LOG_ERROR, "ERROR: step_index = %i\n",
+ c->status[i].step_index);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ for (int n = nb_samples >> (1 - st); n > 0; n--) {
+ int v = bytestream2_get_byteu(&gb);
+
+ *samples++ = ff_adpcm_ima_qt_expand_nibble(&c->status[0 ], v >> 4 );
+ *samples++ = ff_adpcm_ima_qt_expand_nibble(&c->status[st], v & 0xf);
+ }
+ ) /* End of CASE */
CASE(ADPCM_IMA_SMJPEG,
for (int i = 0; i < channels; i++) {
c->status[i].predictor = sign_extend(bytestream2_get_be16u(&gb), 16);
@@ -2704,6 +2728,7 @@ ADPCM_DECODER(ADPCM_IMA_ISS, sample_fmts_s16, adpcm_ima_iss, "ADPCM IMA
ADPCM_DECODER(ADPCM_IMA_MOFLEX, sample_fmts_s16p, adpcm_ima_moflex, "ADPCM IMA MobiClip MOFLEX")
ADPCM_DECODER(ADPCM_IMA_MTF, sample_fmts_s16, adpcm_ima_mtf, "ADPCM IMA Capcom's MT Framework")
ADPCM_DECODER(ADPCM_IMA_OKI, sample_fmts_s16, adpcm_ima_oki, "ADPCM IMA Dialogic OKI")
+ADPCM_DECODER(ADPCM_IMA_PDA, sample_fmts_s16, adpcm_ima_pda, "ADPCM IMA PlayDate")
ADPCM_DECODER(ADPCM_IMA_QT, sample_fmts_s16p, adpcm_ima_qt, "ADPCM IMA QuickTime")
ADPCM_DECODER(ADPCM_IMA_RAD, sample_fmts_s16, adpcm_ima_rad, "ADPCM IMA Radical")
ADPCM_DECODER(ADPCM_IMA_SSI, sample_fmts_s16, adpcm_ima_ssi, "ADPCM IMA Simon & Schuster Interactive")
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index b81dda8161..2fb3b0c2ea 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -682,6 +682,7 @@ extern const FFCodec ff_adpcm_ima_iss_decoder;
extern const FFCodec ff_adpcm_ima_moflex_decoder;
extern const FFCodec ff_adpcm_ima_mtf_decoder;
extern const FFCodec ff_adpcm_ima_oki_decoder;
+extern const FFCodec ff_adpcm_ima_pda_decoder;
extern const FFCodec ff_adpcm_ima_qt_encoder;
extern const FFCodec ff_adpcm_ima_qt_decoder;
extern const FFCodec ff_adpcm_ima_rad_decoder;
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 101aabb11c..4128bf2ecb 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -2641,6 +2641,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA HVQM4"),
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
},
+ {
+ .id = AV_CODEC_ID_ADPCM_IMA_PDA,
+ .type = AVMEDIA_TYPE_AUDIO,
+ .name = "adpcm_ima_pda",
+ .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA PlayDate"),
+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+ },
/* AMR */
{
diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
index ee964184a5..6e4b215bf1 100644
--- a/libavcodec/codec_id.h
+++ b/libavcodec/codec_id.h
@@ -428,6 +428,7 @@ enum AVCodecID {
AV_CODEC_ID_ADPCM_IMA_XBOX,
AV_CODEC_ID_ADPCM_SANYO,
AV_CODEC_ID_ADPCM_IMA_HVQM4,
+ AV_CODEC_ID_ADPCM_IMA_PDA,
/* AMR */
AV_CODEC_ID_AMR_NB = 0x12000,
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index cfa35d0e04..735edaf7a6 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -675,6 +675,7 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba,
case AV_CODEC_ID_ADPCM_IMA_ACORN:
case AV_CODEC_ID_ADPCM_IMA_DAT4:
case AV_CODEC_ID_ADPCM_IMA_ISS:
+ case AV_CODEC_ID_ADPCM_IMA_PDA:
return (frame_bytes - 4 * ch) * 2 / ch;
case AV_CODEC_ID_ADPCM_IMA_SMJPEG:
return (frame_bytes - 4) * 2 / ch;
--
2.49.1
From 56e5c562a00260dd56e54cabb6a3c181bc5c737b Mon Sep 17 00:00:00 2001
From: Paul B Mahol <onemda@gmail.com>
Date: Mon, 25 Nov 2024 13:01:16 +0000
Subject: [PATCH 05/15] avcodec: add ADPCM Silicon Graphics N64 decoder
(cherry picked from commit 13484237fdf19c9d927b8a64b81d00100a4178c3)
---
libavcodec/Makefile | 1 +
libavcodec/adpcm.c | 89 +++++++++++++++++++++++++++++++++++++++++
libavcodec/allcodecs.c | 1 +
libavcodec/codec_desc.c | 7 ++++
libavcodec/codec_id.h | 1 +
libavcodec/utils.c | 5 +++
6 files changed, 104 insertions(+)
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 5a325bf174..3af81c368e 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1004,6 +1004,7 @@ OBJS-$(CONFIG_ADPCM_IMA_XBOX_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_MS_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_MS_ENCODER) += adpcmenc.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_MTAF_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_N64_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_PSX_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_SANYO_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_SBPRO_2_DECODER) += adpcm.o adpcm_data.o
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index 55e48d193d..49bc2e9e70 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -259,6 +259,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx)
switch(avctx->codec->id) {
case AV_CODEC_ID_ADPCM_IMA_AMV:
+ case AV_CODEC_ID_ADPCM_N64:
max_channels = 1;
break;
case AV_CODEC_ID_ADPCM_SANYO:
@@ -350,6 +351,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx)
case AV_CODEC_ID_ADPCM_MTAF:
case AV_CODEC_ID_ADPCM_ARGO:
case AV_CODEC_ID_ADPCM_IMA_MOFLEX:
+ case AV_CODEC_ID_ADPCM_N64:
avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
break;
case AV_CODEC_ID_ADPCM_IMA_WS:
@@ -1093,6 +1095,9 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
return 0;
nb_samples = 64;
break;
+ case AV_CODEC_ID_ADPCM_N64:
+ nb_samples = (buf_size / 9) * 16;
+ break;
/* simple 4-bit adpcm */
case AV_CODEC_ID_ADPCM_CT:
case AV_CODEC_ID_ADPCM_IMA_APC:
@@ -2491,6 +2496,89 @@ static int adpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame,
bytestream2_seek(&gb, 0, SEEK_SET);
}
) /* End of CASE */
+ CASE(ADPCM_N64,
+ ADPCMChannelStatus *cs = &c->status[0];
+ int coefs[8*2*8] = { 0 };
+
+ if (avctx->extradata) {
+ int version, order, entries;
+ GetByteContext cb;
+
+ bytestream2_init(&cb, avctx->extradata, avctx->extradata_size);
+
+ version = bytestream2_get_be16(&cb);
+ order = bytestream2_get_be16(&cb);
+ entries = bytestream2_get_be16(&cb);
+ if (version != 1 || order != 2 || entries > 8)
+ return AVERROR_INVALIDDATA;
+
+ for (int n = 0; n < order * entries * 8; n++)
+ coefs[n] = sign_extend(bytestream2_get_be16(&cb), 16);
+ }
+
+ for (int block = 0; block < avpkt->size / 9; block++) {
+ int scale, index, codes[16];
+ int16_t hist[8] = { 0 };
+ const int order = 2;
+ int16_t out[16];
+
+ hist[6] = cs->sample2;
+ hist[7] = cs->sample1;
+
+ samples = samples_p[0] + block * 16;
+
+ scale = (buf[0] >> 4) & 0xF;
+ index = (buf[0] >> 0) & 0xF;
+ scale = 1 << scale;
+ index = FFMIN(index, 8);
+
+ for (int i = 0, j = 0; i < 16; i += 2, j++) {
+ int n0 = (buf[j+1] >> 4) & 0xF;
+ int n1 = (buf[j+1] >> 0) & 0xF;
+
+ if (n0 & 8)
+ n0 = n0 - 16;
+ if (n1 & 8)
+ n1 = n1 - 16;
+
+ codes[i+0] = n0 * scale;
+ codes[i+1] = n1 * scale;
+ }
+
+ for (int j = 0; j < 2; j++) {
+ int *sf_codes = &codes[j*8];
+ int16_t *sf_out = &out[j*8];
+
+ for (int i = 0; i < 8; i++) {
+ int sample, delta = 0;
+
+ for (int o = 0; o < order; o++)
+ delta += coefs[o*8 + i] * hist[(8 - order) + o];
+
+ for (int k = i-1; k > -1; k--) {
+ for (int o = 1; o < order; o++)
+ delta += sf_codes[(i-1) - k] * coefs[(o*8) + k];
+ }
+
+ sample = sf_codes[i] * 2048;
+ sample = (sample + delta) / 2048;
+ sample = av_clip_int16(sample);
+ sf_out[i] = sample;
+ }
+
+ for (int i = 8 - order; i < 8; i++)
+ hist[i] = sf_out[i];
+ }
+
+ memcpy(samples, out, sizeof(out));
+
+ cs->sample2 = hist[6];
+ cs->sample1 = hist[7];
+
+ buf += 9;
+ }
+ bytestream2_seek(&gb, 0, SEEK_END);
+ ) /* End of CASE */
CASE(ADPCM_PSX,
for (int block = 0; block < avpkt->size / FFMAX(avctx->block_align, 16 * channels); block++) {
int nb_samples_per_block = 28 * FFMAX(avctx->block_align, 16 * channels) / (16 * channels);
@@ -2739,6 +2827,7 @@ ADPCM_DECODER(ADPCM_IMA_WS, sample_fmts_both, adpcm_ima_ws, "ADPCM IMA
ADPCM_DECODER(ADPCM_IMA_XBOX, sample_fmts_s16p, adpcm_ima_xbox, "ADPCM IMA Xbox")
ADPCM_DECODER(ADPCM_MS, sample_fmts_both, adpcm_ms, "ADPCM Microsoft")
ADPCM_DECODER(ADPCM_MTAF, sample_fmts_s16p, adpcm_mtaf, "ADPCM MTAF")
+ADPCM_DECODER(ADPCM_N64, sample_fmts_s16p, adpcm_n64, "ADPCM Silicon Graphics N64")
ADPCM_DECODER(ADPCM_PSX, sample_fmts_s16p, adpcm_psx, "ADPCM Playstation")
ADPCM_DECODER(ADPCM_SANYO, sample_fmts_s16p, adpcm_sanyo, "ADPCM Sanyo")
ADPCM_DECODER(ADPCM_SBPRO_2, sample_fmts_s16, adpcm_sbpro_2, "ADPCM Sound Blaster Pro 2-bit")
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 2fb3b0c2ea..f3a252e241 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -697,6 +697,7 @@ extern const FFCodec ff_adpcm_ima_xbox_decoder;
extern const FFCodec ff_adpcm_ms_encoder;
extern const FFCodec ff_adpcm_ms_decoder;
extern const FFCodec ff_adpcm_mtaf_decoder;
+extern const FFCodec ff_adpcm_n64_decoder;
extern const FFCodec ff_adpcm_psx_decoder;
extern const FFCodec ff_adpcm_sanyo_decoder;
extern const FFCodec ff_adpcm_sbpro_2_decoder;
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 4128bf2ecb..b758e43f33 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -2648,6 +2648,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA PlayDate"),
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
},
+ {
+ .id = AV_CODEC_ID_ADPCM_N64,
+ .type = AVMEDIA_TYPE_AUDIO,
+ .name = "adpcm_n64",
+ .long_name = NULL_IF_CONFIG_SMALL("ADPCM Silicon Graphics N64"),
+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+ },
/* AMR */
{
diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
index 6e4b215bf1..8930b2957e 100644
--- a/libavcodec/codec_id.h
+++ b/libavcodec/codec_id.h
@@ -429,6 +429,7 @@ enum AVCodecID {
AV_CODEC_ID_ADPCM_SANYO,
AV_CODEC_ID_ADPCM_IMA_HVQM4,
AV_CODEC_ID_ADPCM_IMA_PDA,
+ AV_CODEC_ID_ADPCM_N64,
/* AMR */
AV_CODEC_ID_AMR_NB = 0x12000,
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 735edaf7a6..c5230e646a 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -665,6 +665,11 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba,
return (frame_bytes - 4 * ch) / (128 * ch) * 256;
case AV_CODEC_ID_ADPCM_AFC:
return frame_bytes / (9 * ch) * 16;
+ case AV_CODEC_ID_ADPCM_N64:
+ frame_bytes /= 9 * ch;
+ if (frame_bytes > INT_MAX / 16)
+ return 0;
+ return frame_bytes * 16;
case AV_CODEC_ID_ADPCM_PSX:
case AV_CODEC_ID_ADPCM_DTK:
frame_bytes /= 16 * ch;
--
2.49.1
From dc13da259d28d93cb329f19480076ed0e1967171 Mon Sep 17 00:00:00 2001
From: Paul B Mahol <onemda@gmail.com>
Date: Mon, 25 Nov 2024 19:34:44 +0000
Subject: [PATCH 06/15] avcodec/adpcm: fix overflow in mono ADPCM IMA HVQM4
(cherry picked from commit 6a9b0f7272a0725abbe6f887f766fb5f1f119a66)
---
libavcodec/adpcm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index 49bc2e9e70..3f4c392939 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -579,7 +579,7 @@ static void decode_adpcm_ima_hvqm4(AVCodecContext *avctx, int16_t *outbuf, int s
samples_to_do--;
}
- for (int i = 0; i < samples_to_do; i++) {
+ for (int i = 0; i < samples_to_do; i += 1+(!st)) {
uint8_t nibble = bytestream2_get_byte(gb);
*outbuf++ = ff_adpcm_ima_qt_expand_nibble(&c->status[st], nibble & 0xF);
--
2.49.1
From ac1fbf530503e893946974aed5b0390686eba9f6 Mon Sep 17 00:00:00 2001
From: Paul B Mahol <onemda@gmail.com>
Date: Mon, 25 Nov 2024 19:06:53 +0000
Subject: [PATCH 07/15] avcodec: add ADPCM IMA HVQM2 decoder
(cherry picked from commit 480e36592d5fc27a47e378d62570824613f26b7b)
---
libavcodec/Makefile | 3 ++-
libavcodec/adpcm.c | 47 +++++++++++++++++++++++++++++++++++++++++
libavcodec/allcodecs.c | 1 +
libavcodec/codec_desc.c | 7 ++++++
libavcodec/codec_id.h | 1 +
5 files changed, 58 insertions(+), 1 deletion(-)
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 3af81c368e..0cf8c80b2e 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -984,7 +984,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
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index 3f4c392939..a131088b7c 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -546,6 +546,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)
{
@@ -1148,6 +1185,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);
@@ -1753,6 +1793,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);
@@ -2811,6 +2857,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")
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index f3a252e241..5891c04211 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -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;
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index b758e43f33..ea22c0a668 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -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 */
{
diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
index 8930b2957e..cc22f24ba9 100644
--- a/libavcodec/codec_id.h
+++ b/libavcodec/codec_id.h
@@ -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,
--
2.49.1
From e35ac402c2a9f477b68a038086d72de9c7ea75e3 Mon Sep 17 00:00:00 2001
From: Paul B Mahol <onemda@gmail.com>
Date: Sun, 15 Dec 2024 13:48:11 +0000
Subject: [PATCH 08/15] avcodec/adpcm: explicitly clear 4 upper bits for PSX
when sign extending
(cherry picked from commit 49f6621d88392e21360efc1fb99d1241fa3ce469)
---
libavcodec/adpcm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index a131088b7c..eccb574cd7 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -2651,7 +2651,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame,
scale = sign_extend(byte >> 4, 4);
} else {
byte = bytestream2_get_byteu(&gb);
- scale = sign_extend(byte, 4);
+ scale = sign_extend(byte & 0xF, 4);
}
if (flag < 0x07) {
--
2.49.1
From 37dd4362116f66306954527ece6ff38b39738ce3 Mon Sep 17 00:00:00 2001
From: Paul B Mahol <onemda@gmail.com>
Date: Tue, 21 Jan 2025 17:29:45 +0000
Subject: [PATCH 09/15] avcodec: add ADPCM IMA Magix decoder
(cherry picked from commit 2ec3ad2122484ce2c84f6ba055c5ebc1661c5b14)
---
libavcodec/Makefile | 1 +
libavcodec/adpcm.c | 24 ++++++++++++++++++++++++
libavcodec/allcodecs.c | 1 +
libavcodec/codec_desc.c | 7 +++++++
libavcodec/codec_id.h | 1 +
libavcodec/utils.c | 1 +
6 files changed, 35 insertions(+)
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 0cf8c80b2e..6ab6313412 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -988,6 +988,7 @@ 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_MAGIX_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_IMA_MTF_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_IMA_PDA_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_IMA_OKI_DECODER) += adpcm.o adpcm_data.o
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index eccb574cd7..c641f4bef4 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -1161,6 +1161,7 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
case AV_CODEC_ID_ADPCM_AGM:
case AV_CODEC_ID_ADPCM_IMA_ACORN:
case AV_CODEC_ID_ADPCM_IMA_DAT4:
+ case AV_CODEC_ID_ADPCM_IMA_MAGIX:
case AV_CODEC_ID_ADPCM_IMA_MOFLEX:
case AV_CODEC_ID_ADPCM_IMA_ISS: header_size = 4 * ch; break;
case AV_CODEC_ID_ADPCM_IMA_SMJPEG: header_size = 4 * ch; break;
@@ -1724,6 +1725,28 @@ static int adpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame,
if ((bytestream2_tell(&gb) & 1))
bytestream2_skip(&gb, 1);
) /* End of CASE */
+ CASE(ADPCM_IMA_MAGIX,
+ for (int channel = 0; channel < channels; channel++) {
+ ADPCMChannelStatus *cs = &c->status[channel];
+ cs->predictor = sign_extend(bytestream2_get_le16u(&gb), 16);
+ cs->step_index = sign_extend(bytestream2_get_le16u(&gb), 16);
+ if (cs->step_index > 88u){
+ av_log(avctx, AV_LOG_ERROR, "ERROR: step_index[%d] = %i\n",
+ channel, cs->step_index);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ for (int m = 0; m < avctx->block_align-8; m += 8) {
+ uint32_t v0 = bytestream2_get_le32u(&gb);
+ uint32_t v1 = bytestream2_get_le32u(&gb);
+
+ for (int n = 8; n > 0; n--, v0 >>= 4, v1 >>= 4, samples += 2) {
+ samples[0] = adpcm_ima_expand_nibble(&c->status[0], v0 & 15, 3);
+ samples[1] = adpcm_ima_expand_nibble(&c->status[1], v1 & 15, 3);
+ }
+ }
+ ) /* End of CASE */
CASE(ADPCM_IMA_ISS,
for (int channel = 0; channel < channels; channel++) {
ADPCMChannelStatus *cs = &c->status[channel];
@@ -2860,6 +2883,7 @@ ADPCM_DECODER(ADPCM_IMA_EA_SEAD, sample_fmts_s16, adpcm_ima_ea_sead, "ADPCM IMA
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_MAGIX, sample_fmts_s16, adpcm_ima_magix, "ADPCM IMA Magix")
ADPCM_DECODER(ADPCM_IMA_MOFLEX, sample_fmts_s16p, adpcm_ima_moflex, "ADPCM IMA MobiClip MOFLEX")
ADPCM_DECODER(ADPCM_IMA_MTF, sample_fmts_s16, adpcm_ima_mtf, "ADPCM IMA Capcom's MT Framework")
ADPCM_DECODER(ADPCM_IMA_OKI, sample_fmts_s16, adpcm_ima_oki, "ADPCM IMA Dialogic OKI")
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 5891c04211..9064e470d3 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -680,6 +680,7 @@ 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_magix_decoder;
extern const FFCodec ff_adpcm_ima_moflex_decoder;
extern const FFCodec ff_adpcm_ima_mtf_decoder;
extern const FFCodec ff_adpcm_ima_oki_decoder;
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index ea22c0a668..421ecf6926 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -2662,6 +2662,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA HVQM2"),
.props = AV_CODEC_PROP_LOSSY,
},
+ {
+ .id = AV_CODEC_ID_ADPCM_IMA_MAGIX,
+ .type = AVMEDIA_TYPE_AUDIO,
+ .name = "adpcm_ima_magix",
+ .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Magix"),
+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+ },
/* AMR */
{
diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
index cc22f24ba9..c69e81582a 100644
--- a/libavcodec/codec_id.h
+++ b/libavcodec/codec_id.h
@@ -431,6 +431,7 @@ enum AVCodecID {
AV_CODEC_ID_ADPCM_IMA_PDA,
AV_CODEC_ID_ADPCM_N64,
AV_CODEC_ID_ADPCM_IMA_HVQM2,
+ AV_CODEC_ID_ADPCM_IMA_MAGIX,
/* AMR */
AV_CODEC_ID_AMR_NB = 0x12000,
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index c5230e646a..039315a2ce 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -465,6 +465,7 @@ int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
case AV_CODEC_ID_ADPCM_IMA_APC:
case AV_CODEC_ID_ADPCM_IMA_APM:
case AV_CODEC_ID_ADPCM_IMA_EA_SEAD:
+ case AV_CODEC_ID_ADPCM_IMA_MAGIX:
case AV_CODEC_ID_ADPCM_IMA_OKI:
case AV_CODEC_ID_ADPCM_IMA_WS:
case AV_CODEC_ID_ADPCM_IMA_SSI:
--
2.49.1
From 9970be5a6ddb9d2cb589d9381b19fa92db8672bb Mon Sep 17 00:00:00 2001
From: Paul B Mahol <onemda@gmail.com>
Date: Wed, 19 Feb 2025 20:24:39 +0000
Subject: [PATCH 10/15] avcodec/adpcm: fix non-4bit adpcm ima wav decoding
(cherry picked from commit f4e05abeded46515bd7b4248fc7d65df82d9af2a)
---
libavcodec/adpcm.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index c641f4bef4..a1906ac26c 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -509,7 +509,9 @@ static inline int16_t adpcm_ima_wav_expand_nibble(ADPCMChannelStatus *c, GetBitC
sign = nibble & (1 << shift);
delta = av_zero_extend(nibble, shift);
- diff = ((2 * delta + 1) * step) >> shift;
+ diff = step >> shift;
+ for (int i = 0; i < shift; i++)
+ diff += (step >> (shift-1-i)) * !!(delta & (1 << i));
predictor = c->predictor;
if (sign) predictor -= diff;
else predictor += diff;
--
2.49.1
From cc38ce87b3fb06a8fb75c0fc51fb87b3e57d196b Mon Sep 17 00:00:00 2001
From: Paul B Mahol <onemda@gmail.com>
Date: Mon, 24 Feb 2025 12:19:03 +0000
Subject: [PATCH 11/15] avcodec: add ADPCM PSXC audio decoder
(cherry picked from commit a4055b5cc6d77c26867948e24de6bdfd5c0e6a3b)
---
libavcodec/Makefile | 1 +
libavcodec/adpcm.c | 44 +++++++++++++++++++++++++++++++++++++++++
libavcodec/allcodecs.c | 1 +
libavcodec/codec_desc.c | 7 +++++++
libavcodec/codec_id.h | 1 +
libavcodec/utils.c | 5 +++++
6 files changed, 59 insertions(+)
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 6ab6313412..08c5240a4c 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1008,6 +1008,7 @@ OBJS-$(CONFIG_ADPCM_MS_ENCODER) += adpcmenc.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_MTAF_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_N64_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_PSX_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_PSXC_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_SANYO_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_SBPRO_2_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_SBPRO_3_DECODER) += adpcm.o adpcm_data.o
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index a1906ac26c..9381bdcf2a 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -290,6 +290,11 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx)
avctx->block_align % (16 * avctx->ch_layout.nb_channels))
return AVERROR_INVALIDDATA;
break;
+ case AV_CODEC_ID_ADPCM_PSXC:
+ max_channels = 8;
+ if (avctx->ch_layout.nb_channels <= 0)
+ return AVERROR_INVALIDDATA;
+ break;
case AV_CODEC_ID_ADPCM_IMA_DAT4:
case AV_CODEC_ID_ADPCM_THP:
case AV_CODEC_ID_ADPCM_THP_LE:
@@ -347,6 +352,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx)
case AV_CODEC_ID_ADPCM_AFC:
case AV_CODEC_ID_ADPCM_DTK:
case AV_CODEC_ID_ADPCM_PSX:
+ case AV_CODEC_ID_ADPCM_PSXC:
case AV_CODEC_ID_ADPCM_SANYO:
case AV_CODEC_ID_ADPCM_MTAF:
case AV_CODEC_ID_ADPCM_ARGO:
@@ -1351,6 +1357,9 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
case AV_CODEC_ID_ADPCM_PSX:
nb_samples = buf_size / (16 * ch) * 28;
break;
+ case AV_CODEC_ID_ADPCM_PSXC:
+ nb_samples = ((buf_size - 1) / ch) * 2;
+ break;
case AV_CODEC_ID_ADPCM_ARGO:
nb_samples = buf_size / avctx->block_align * 32;
break;
@@ -2691,6 +2700,40 @@ static int adpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame,
}
}
) /* End of CASE */
+ CASE(ADPCM_PSXC,
+ for (int block = 0; block < avpkt->size / avctx->block_align; block++) {
+ int nb_samples_per_block = ((avctx->block_align - 1) / channels) * 2;
+ for (int channel = 0; channel < channels; channel++) {
+ int filter, shift, byte;
+
+ samples = samples_p[channel] + block * nb_samples_per_block;
+ av_assert0((block + 1) * nb_samples_per_block <= nb_samples);
+
+ filter = bytestream2_get_byteu(&gb);
+ shift = filter & 0xf;
+ filter = filter >> 4;
+ if (filter >= FF_ARRAY_ELEMS(xa_adpcm_table))
+ return AVERROR_INVALIDDATA;
+
+ for (int n = 0; n < nb_samples_per_block; n++) {
+ int sample = 0, scale;
+
+ if (n & 1) {
+ scale = sign_extend(byte >> 4, 4);
+ } else {
+ byte = bytestream2_get_byteu(&gb);
+ scale = sign_extend(byte & 0xF, 4);
+ }
+
+ scale = scale * (1 << 12);
+ sample = (int)((scale >> shift) + (c->status[channel].sample1 * xa_adpcm_table[filter][0] + c->status[channel].sample2 * xa_adpcm_table[filter][1]) / 64);
+ *samples++ = av_clip_int16(sample);
+ c->status[channel].sample2 = c->status[channel].sample1;
+ c->status[channel].sample1 = sample;
+ }
+ }
+ }
+ ) /* End of CASE */
CASE(ADPCM_SANYO,
int (*expand)(ADPCMChannelStatus *c, int bits);
GetBitContext g;
@@ -2902,6 +2945,7 @@ ADPCM_DECODER(ADPCM_MS, sample_fmts_both, adpcm_ms, "ADPCM Mic
ADPCM_DECODER(ADPCM_MTAF, sample_fmts_s16p, adpcm_mtaf, "ADPCM MTAF")
ADPCM_DECODER(ADPCM_N64, sample_fmts_s16p, adpcm_n64, "ADPCM Silicon Graphics N64")
ADPCM_DECODER(ADPCM_PSX, sample_fmts_s16p, adpcm_psx, "ADPCM Playstation")
+ADPCM_DECODER(ADPCM_PSXC, sample_fmts_s16p, adpcm_psxc, "ADPCM Playstation C")
ADPCM_DECODER(ADPCM_SANYO, sample_fmts_s16p, adpcm_sanyo, "ADPCM Sanyo")
ADPCM_DECODER(ADPCM_SBPRO_2, sample_fmts_s16, adpcm_sbpro_2, "ADPCM Sound Blaster Pro 2-bit")
ADPCM_DECODER(ADPCM_SBPRO_3, sample_fmts_s16, adpcm_sbpro_3, "ADPCM Sound Blaster Pro 2.6-bit")
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 9064e470d3..67e02ef7bb 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -701,6 +701,7 @@ extern const FFCodec ff_adpcm_ms_decoder;
extern const FFCodec ff_adpcm_mtaf_decoder;
extern const FFCodec ff_adpcm_n64_decoder;
extern const FFCodec ff_adpcm_psx_decoder;
+extern const FFCodec ff_adpcm_psxc_decoder;
extern const FFCodec ff_adpcm_sanyo_decoder;
extern const FFCodec ff_adpcm_sbpro_2_decoder;
extern const FFCodec ff_adpcm_sbpro_3_decoder;
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 421ecf6926..1493f34730 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -2669,6 +2669,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Magix"),
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
},
+ {
+ .id = AV_CODEC_ID_ADPCM_PSXC,
+ .type = AVMEDIA_TYPE_AUDIO,
+ .name = "adpcm_psxc",
+ .long_name = NULL_IF_CONFIG_SMALL("ADPCM Playstation C"),
+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+ },
/* AMR */
{
diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
index c69e81582a..975ebbe880 100644
--- a/libavcodec/codec_id.h
+++ b/libavcodec/codec_id.h
@@ -432,6 +432,7 @@ enum AVCodecID {
AV_CODEC_ID_ADPCM_N64,
AV_CODEC_ID_ADPCM_IMA_HVQM2,
AV_CODEC_ID_ADPCM_IMA_MAGIX,
+ AV_CODEC_ID_ADPCM_PSXC,
/* AMR */
AV_CODEC_ID_AMR_NB = 0x12000,
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 039315a2ce..b65e10827e 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -677,6 +677,11 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba,
if (frame_bytes > INT_MAX / 28)
return 0;
return frame_bytes * 28;
+ case AV_CODEC_ID_ADPCM_PSXC:
+ frame_bytes = (frame_bytes - 1) / ch;
+ if (frame_bytes > INT_MAX / 2)
+ return 0;
+ return frame_bytes * 2;
case AV_CODEC_ID_ADPCM_4XM:
case AV_CODEC_ID_ADPCM_IMA_ACORN:
case AV_CODEC_ID_ADPCM_IMA_DAT4:
--
2.49.1
From c1bb24c3f29b1bf78ec36e0d5270ed22e9d901a5 Mon Sep 17 00:00:00 2001
From: Paul B Mahol <onemda@gmail.com>
Date: Fri, 28 Feb 2025 16:05:05 +0000
Subject: [PATCH 12/15] avcodec: add ADPCM Circus decoder
(cherry picked from commit cdd3d794c7e01e4d6f485e7b975a4b9107d3f2fd)
---
libavcodec/Makefile | 1 +
libavcodec/adpcm.c | 31 +++++++++++++++++++++++++++++++
libavcodec/allcodecs.c | 1 +
libavcodec/codec_desc.c | 7 +++++++
libavcodec/codec_id.h | 1 +
libavcodec/utils.c | 1 +
6 files changed, 42 insertions(+)
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 08c5240a4c..1e6e00b154 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -956,6 +956,7 @@ OBJS-$(CONFIG_ADPCM_AGM_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_AICA_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_ARGO_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_ARGO_ENCODER) += adpcm.o adpcm_data.o adpcmenc.o
+OBJS-$(CONFIG_ADPCM_CIRCUS_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_CT_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_DTK_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_EA_DECODER) += adpcm.o adpcm_data.o
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index 9381bdcf2a..76404bcf08 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -738,6 +738,27 @@ static inline int16_t adpcm_mtaf_expand_nibble(ADPCMChannelStatus *c, uint8_t ni
return c->predictor;
}
+static inline int16_t adpcm_circus_expand_nibble(ADPCMChannelStatus *c, uint8_t nibble)
+{
+ int32_t sample = c->predictor;
+ int32_t scale = c->step;
+ int32_t code = sign_extend(nibble, 8);
+
+ sample += code * (1 << scale);
+ if (code == 0) {
+ scale--;
+ } else if (code == 127 || code == -128) {
+ scale++;
+ }
+ scale = av_clip(scale, 0, 8);
+ sample = av_clip_int16(sample);
+
+ c->predictor = sample;
+ c->step = scale;
+
+ return sample;
+}
+
static inline int16_t adpcm_zork_expand_nibble(ADPCMChannelStatus *c, uint8_t nibble)
{
int16_t index = c->step_index;
@@ -1363,6 +1384,7 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
case AV_CODEC_ID_ADPCM_ARGO:
nb_samples = buf_size / avctx->block_align * 32;
break;
+ case AV_CODEC_ID_ADPCM_CIRCUS:
case AV_CODEC_ID_ADPCM_ZORK:
nb_samples = buf_size / ch;
break;
@@ -2794,6 +2816,14 @@ static int adpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame,
}
}
) /* End of CASE */
+ CASE(ADPCM_CIRCUS,
+ for (int n = 0; n < nb_samples; n++) {
+ for (int ch = 0; ch < channels; ch++) {
+ int v = bytestream2_get_byteu(&gb);
+ *samples++ = adpcm_circus_expand_nibble(&c->status[ch], v);
+ }
+ }
+ ) /* End of CASE */
CASE(ADPCM_ZORK,
for (int n = 0; n < nb_samples * channels; n++) {
int v = bytestream2_get_byteu(&gb);
@@ -2907,6 +2937,7 @@ ADPCM_DECODER(ADPCM_AFC, sample_fmts_s16p, adpcm_afc, "ADPCM Nin
ADPCM_DECODER(ADPCM_AGM, sample_fmts_s16, adpcm_agm, "ADPCM AmuseGraphics Movie")
ADPCM_DECODER(ADPCM_AICA, sample_fmts_s16p, adpcm_aica, "ADPCM Yamaha AICA")
ADPCM_DECODER(ADPCM_ARGO, sample_fmts_s16p, adpcm_argo, "ADPCM Argonaut Games")
+ADPCM_DECODER(ADPCM_CIRCUS, sample_fmts_s16, adpcm_circus, "ADPCM Circus")
ADPCM_DECODER(ADPCM_CT, sample_fmts_s16, adpcm_ct, "ADPCM Creative Technology")
ADPCM_DECODER(ADPCM_DTK, sample_fmts_s16p, adpcm_dtk, "ADPCM Nintendo Gamecube DTK")
ADPCM_DECODER(ADPCM_EA, sample_fmts_s16, adpcm_ea, "ADPCM Electronic Arts")
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 67e02ef7bb..77a13d9b0c 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -649,6 +649,7 @@ extern const FFCodec ff_adpcm_agm_decoder;
extern const FFCodec ff_adpcm_aica_decoder;
extern const FFCodec ff_adpcm_argo_decoder;
extern const FFCodec ff_adpcm_argo_encoder;
+extern const FFCodec ff_adpcm_circus_decoder;
extern const FFCodec ff_adpcm_ct_decoder;
extern const FFCodec ff_adpcm_dtk_decoder;
extern const FFCodec ff_adpcm_ea_decoder;
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 1493f34730..30793a2a26 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -2676,6 +2676,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("ADPCM Playstation C"),
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
},
+ {
+ .id = AV_CODEC_ID_ADPCM_CIRCUS,
+ .type = AVMEDIA_TYPE_AUDIO,
+ .name = "adpcm_circus",
+ .long_name = NULL_IF_CONFIG_SMALL("ADPCM Circus"),
+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+ },
/* AMR */
{
diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
index 975ebbe880..feb4d61708 100644
--- a/libavcodec/codec_id.h
+++ b/libavcodec/codec_id.h
@@ -433,6 +433,7 @@ enum AVCodecID {
AV_CODEC_ID_ADPCM_IMA_HVQM2,
AV_CODEC_ID_ADPCM_IMA_MAGIX,
AV_CODEC_ID_ADPCM_PSXC,
+ AV_CODEC_ID_ADPCM_CIRCUS,
/* AMR */
AV_CODEC_ID_AMR_NB = 0x12000,
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index b65e10827e..d89e886a08 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -488,6 +488,7 @@ int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
case AV_CODEC_ID_CBD2_DPCM:
case AV_CODEC_ID_DERF_DPCM:
case AV_CODEC_ID_WADY_DPCM:
+ case AV_CODEC_ID_ADPCM_CIRCUS:
return 8;
case AV_CODEC_ID_PCM_S16BE:
case AV_CODEC_ID_PCM_S16BE_PLANAR:
--
2.49.1
From da35b4f120683790e5c1dbaf2998d1b46dc5b6aa Mon Sep 17 00:00:00 2001
From: Paul B Mahol <onemda@gmail.com>
Date: Sat, 8 Mar 2025 19:40:46 +0000
Subject: [PATCH 13/15] avcodec: add ADPCM IMA Escape audio decoder
(cherry picked from commit 4a663e78c4421da226e7d480d6767de803ee2122)
---
libavcodec/Makefile | 1 +
libavcodec/adpcm.c | 32 ++++++++++++++++++++++++++++++++
libavcodec/allcodecs.c | 1 +
libavcodec/codec_desc.c | 7 +++++++
libavcodec/codec_id.h | 1 +
libavformat/rpl.c | 2 +-
6 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 1e6e00b154..6c2412df0d 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -985,6 +985,7 @@ 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_ESCAPE_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
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index 76404bcf08..c782ed007e 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -418,6 +418,29 @@ static inline int16_t adpcm_agm_expand_nibble(ADPCMChannelStatus *c, int8_t nibb
return pred;
}
+static inline int16_t adpcm_ima_escape_expand_nibble(ADPCMChannelStatus *c, int8_t nibble)
+{
+ int step_index;
+ int predictor;
+ int sign, delta, diff, step;
+
+ step = ff_adpcm_step_table[c->step_index];
+ step_index = c->step_index + ff_adpcm_index_table[(unsigned)nibble];
+ step_index = av_clip(step_index, 0, 88);
+
+ sign = nibble & 8;
+ delta = nibble & 7;
+ diff = (delta * step) >> 2;
+ predictor = c->predictor;
+ if (sign) predictor -= diff;
+ else predictor += diff;
+
+ c->predictor = av_clip_int16(predictor);
+ c->step_index = step_index;
+
+ return (int16_t)c->predictor;
+}
+
static inline int16_t adpcm_ima_expand_nibble(ADPCMChannelStatus *c, int8_t nibble, int shift)
{
int step_index;
@@ -1169,6 +1192,7 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
case AV_CODEC_ID_ADPCM_IMA_APC:
case AV_CODEC_ID_ADPCM_IMA_CUNNING:
case AV_CODEC_ID_ADPCM_IMA_EA_SEAD:
+ case AV_CODEC_ID_ADPCM_IMA_ESCAPE:
case AV_CODEC_ID_ADPCM_IMA_OKI:
case AV_CODEC_ID_ADPCM_IMA_WS:
case AV_CODEC_ID_ADPCM_YAMAHA:
@@ -2013,6 +2037,13 @@ static int adpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame,
bytestream2_skip(&gb, bytes_remaining);
}
) /* End of CASE */
+ CASE(ADPCM_IMA_ESCAPE,
+ for (int n = nb_samples >> (1 - st); n > 0; n--) {
+ int byte = bytestream2_get_byteu(&gb);
+ *samples++ = adpcm_ima_escape_expand_nibble(&c->status[0], byte >> 4);
+ *samples++ = adpcm_ima_escape_expand_nibble(&c->status[st], byte & 0xF);
+ }
+ ) /* End of CASE */
CASE(ADPCM_IMA_EA_EACS,
for (int i = 0; i <= st; i++) {
c->status[i].step_index = bytestream2_get_le32u(&gb);
@@ -2956,6 +2987,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_ESCAPE, sample_fmts_s16, adpcm_ima_escape, "ADPCM IMA Acorn Escape")
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")
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 77a13d9b0c..ae48c414e8 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -678,6 +678,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_escape_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;
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 30793a2a26..526a85e262 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -2683,6 +2683,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("ADPCM Circus"),
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
},
+ {
+ .id = AV_CODEC_ID_ADPCM_IMA_ESCAPE,
+ .type = AVMEDIA_TYPE_AUDIO,
+ .name = "adpcm_ima_escape",
+ .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Acorn Escape"),
+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+ },
/* AMR */
{
diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
index feb4d61708..8c98ac6335 100644
--- a/libavcodec/codec_id.h
+++ b/libavcodec/codec_id.h
@@ -434,6 +434,7 @@ enum AVCodecID {
AV_CODEC_ID_ADPCM_IMA_MAGIX,
AV_CODEC_ID_ADPCM_PSXC,
AV_CODEC_ID_ADPCM_CIRCUS,
+ AV_CODEC_ID_ADPCM_IMA_ESCAPE,
/* AMR */
AV_CODEC_ID_AMR_NB = 0x12000,
diff --git a/libavformat/rpl.c b/libavformat/rpl.c
index b30d769efb..781dabf7ba 100644
--- a/libavformat/rpl.c
+++ b/libavformat/rpl.c
@@ -250,7 +250,7 @@ static int rpl_read_header(AVFormatContext *s)
// are all unsigned.
ast->codecpar->codec_id = AV_CODEC_ID_PCM_U8;
} else if (ast->codecpar->bits_per_coded_sample == 4) {
- ast->codecpar->codec_id = AV_CODEC_ID_ADPCM_IMA_EA_SEAD;
+ ast->codecpar->codec_id = AV_CODEC_ID_ADPCM_IMA_ESCAPE;
}
break;
}
--
2.49.1
From 5ea4971647978ff29d12ed89ee8106ee6ff795ac Mon Sep 17 00:00:00 2001
From: Paul B Mahol <onemda@gmail.com>
Date: Mon, 17 Mar 2025 21:01:16 +0000
Subject: [PATCH 14/15] avcodec/adpcm: improve decooding output for 4-bit ADPCM
IMA WAV
(cherry picked from commit f11422f1a6251e2b3c42b4044efbc722b863778d)
---
libavcodec/adpcm.c | 4 ++--
tests/ref/acodec/adpcm-ima_wav | 4 ++--
tests/ref/acodec/adpcm-ima_wav-trellis | 4 ++--
tests/ref/fate/adpcm-ima_wav-stereo | 2 +-
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index c782ed007e..13003db760 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -1549,8 +1549,8 @@ static int adpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame,
samples = &samples_p[i][1 + n * 8];
for (int m = 0; m < 8; m += 2) {
int v = bytestream2_get_byteu(&gb);
- samples[m ] = adpcm_ima_expand_nibble(cs, v & 0x0F, 3);
- samples[m + 1] = adpcm_ima_expand_nibble(cs, v >> 4 , 3);
+ samples[m ] = ff_adpcm_ima_qt_expand_nibble(cs, v & 0x0F);
+ samples[m + 1] = ff_adpcm_ima_qt_expand_nibble(cs, v >> 4);
}
}
}
diff --git a/tests/ref/acodec/adpcm-ima_wav b/tests/ref/acodec/adpcm-ima_wav
index 44ca53a565..b2cc518b1e 100644
--- a/tests/ref/acodec/adpcm-ima_wav
+++ b/tests/ref/acodec/adpcm-ima_wav
@@ -1,4 +1,4 @@
af0b82a719762cc6e1a952a6081231cf *tests/data/fate/acodec-adpcm-ima_wav.wav
267324 tests/data/fate/acodec-adpcm-ima_wav.wav
-78a2af1c895792d0c221d127bdd48ece *tests/data/fate/acodec-adpcm-ima_wav.out.wav
-stddev: 903.51 PSNR: 37.21 MAXDIFF:34026 bytes: 1058400/ 1061748
+a57d7b0ca564b5fed4bf78fc9f91d8e2 *tests/data/fate/acodec-adpcm-ima_wav.out.wav
+stddev: 903.56 PSNR: 37.21 MAXDIFF:34029 bytes: 1058400/ 1061748
diff --git a/tests/ref/acodec/adpcm-ima_wav-trellis b/tests/ref/acodec/adpcm-ima_wav-trellis
index 29c28edddf..008d1e4b62 100644
--- a/tests/ref/acodec/adpcm-ima_wav-trellis
+++ b/tests/ref/acodec/adpcm-ima_wav-trellis
@@ -1,4 +1,4 @@
6f0df0f3275f833c341d63b9054caebb *tests/data/fate/acodec-adpcm-ima_wav-trellis.wav
267324 tests/data/fate/acodec-adpcm-ima_wav-trellis.wav
-26a9b280c14737b159c56e60181f1170 *tests/data/fate/acodec-adpcm-ima_wav-trellis.out.wav
-stddev: 710.03 PSNR: 39.30 MAXDIFF:25944 bytes: 1058400/ 1061748
+1af83218cde84bd7cd2297c04ef97f79 *tests/data/fate/acodec-adpcm-ima_wav-trellis.out.wav
+stddev: 710.09 PSNR: 39.30 MAXDIFF:25941 bytes: 1058400/ 1061748
diff --git a/tests/ref/fate/adpcm-ima_wav-stereo b/tests/ref/fate/adpcm-ima_wav-stereo
index cb6a481999..2a36800951 100644
--- a/tests/ref/fate/adpcm-ima_wav-stereo
+++ b/tests/ref/fate/adpcm-ima_wav-stereo
@@ -1 +1 @@
-1ee96f1efc09251a732621049dc5b66e
+b4697f4f64c12afb37acfebd5f7a756c
--
2.49.1
From 02ea6cf9a8fb678bb36322b9b71d5a8d43427440 Mon Sep 17 00:00:00 2001
From: asivery <asivery@protonmail.com>
Date: Sat, 15 Jun 2024 07:47:40 +0200
Subject: [PATCH 15/15] avformat/aeadec, avcodec/atrac1: Fix 8 and 4-channel
ATRAC1 support
Signed-off-by: asivery <asivery@protonmail.com>
(cherry picked from commit 81cdf42222961c2959f1ede2d86fea0d1dcbbfcb)
---
libavcodec/atrac1.c | 12 ++++++------
libavformat/aeadec.c | 2 +-
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c
index f0bef9b9e6..b708c31897 100644
--- a/libavcodec/atrac1.c
+++ b/libavcodec/atrac1.c
@@ -49,7 +49,7 @@
#define AT1_SU_SAMPLES 512 ///< number of samples in a sound unit
#define AT1_FRAME_SIZE AT1_SU_SIZE * 2
#define AT1_SU_MAX_BITS AT1_SU_SIZE * 8
-#define AT1_MAX_CHANNELS 2
+#define AT1_MAX_CHANNELS 8
#define AT1_QMF_BANDS 3
#define IDX_LOW_BAND 0
@@ -339,7 +339,7 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx)
AVFloatDSPContext *fdsp;
int channels = avctx->ch_layout.nb_channels;
float scale = -1.0 / (1 << 15);
- int ret;
+ int ret, ch;
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
@@ -380,10 +380,10 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx)
q->bands[2] = q->high;
/* Prepare the mdct overlap buffers */
- q->SUs[0].spectrum[0] = q->SUs[0].spec1;
- q->SUs[0].spectrum[1] = q->SUs[0].spec2;
- q->SUs[1].spectrum[0] = q->SUs[1].spec1;
- q->SUs[1].spectrum[1] = q->SUs[1].spec2;
+ for (ch = 0; ch < AT1_MAX_CHANNELS; ch++) {
+ q->SUs[ch].spectrum[0] = q->SUs[ch].spec1;
+ q->SUs[ch].spectrum[1] = q->SUs[ch].spec2;
+ }
return 0;
}
diff --git a/libavformat/aeadec.c b/libavformat/aeadec.c
index be18e7b725..0a3d09a89d 100644
--- a/libavformat/aeadec.c
+++ b/libavformat/aeadec.c
@@ -84,7 +84,7 @@ static int aea_read_header(AVFormatContext *s)
st->codecpar->sample_rate = 44100;
st->codecpar->bit_rate = 146000 * channels;
- if (channels != 1 && channels != 2) {
+ if (channels < 1 || channels > 8) {
av_log(s, AV_LOG_ERROR, "Channels %d not supported!\n", channels);
return AVERROR_INVALIDDATA;
}
--
2.49.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2025-08-24 3:02 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-08-24 3:01 [FFmpeg-devel] [PATCH] A few new decoders and a parser from almpeg (PR #20325) michaelni via ffmpeg-devel
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git