* [FFmpeg-devel] [PATCH] Bink 2 Audio decoder and demuxer (PR #20359)
@ 2025-08-28 8:37 Peter Ross via ffmpeg-devel
0 siblings, 0 replies; only message in thread
From: Peter Ross via ffmpeg-devel @ 2025-08-28 8:37 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Peter Ross
PR #20359 opened by Peter Ross (pross)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20359
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20359.patch
Sample: https://github.com/vgmstream/vgmstream/files/11607386/Jumbo_Josh_1.zip
This was a contribution I made to librempeg last year.
>From d16f2ec99ec83472d039e5b32012fd1f90cb612d Mon Sep 17 00:00:00 2001
From: Peter Ross <pross@xvid.org>
Date: Tue, 10 Dec 2024 23:16:08 +1100
Subject: [PATCH 1/4] avcodec/binkaudio: Bink Audio 2 decoder
(cherry picked from librempeg commit fd1dcfe5f4fb6e2ff4332d161a23c6786084ddd1)
---
libavcodec/binkaudio.c | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
index 265f93a822..c77f2bf828 100644
--- a/libavcodec/binkaudio.c
+++ b/libavcodec/binkaudio.c
@@ -50,6 +50,7 @@
typedef struct BinkAudioContext {
GetBitContext gb;
int version_b; ///< Bink version 'b'
+ int version_2; ///< Bink Audio 2
int first;
int channels;
int ch_offset;
@@ -94,6 +95,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
av_channel_layout_default(&avctx->ch_layout, channels);
s->version_b = avctx->extradata_size >= 4 && avctx->extradata[3] == 'b';
+ s->version_2 = avctx->extradata_size >= 1 && avctx->extradata[0] == '2';
if (avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) {
// audio is already interleaved for the RDFT format variant
@@ -176,6 +178,7 @@ static int decode_block(BinkAudioContext *s, float **out, int use_dct,
int ch, i, j, k;
float q, quant[25];
int width, coeff;
+ int quant_idx_size = s->version_2 ? 7 : 8;
GetBitContext *gb = &s->gb;
LOCAL_ALIGNED_32(float, coeffs, [4098]);
@@ -195,10 +198,10 @@ static int decode_block(BinkAudioContext *s, float **out, int use_dct,
coeffs[1] = get_float(gb) * s->root;
}
- if (get_bits_left(gb) < s->num_bands * 8)
+ if (get_bits_left(gb) < s->num_bands * quant_idx_size)
return AVERROR_INVALIDDATA;
for (i = 0; i < s->num_bands; i++) {
- int value = get_bits(gb, 8);
+ int value = get_bits(gb, quant_idx_size);
quant[i] = s->quant_table[FFMIN(value, 95)];
}
@@ -229,6 +232,21 @@ static int decode_block(BinkAudioContext *s, float **out, int use_dct,
while (s->bands[k] < i)
q = quant[k++];
} else {
+ if (s->version_2) {
+ for (int m = i; m < j; m++)
+ coeffs[m] = get_bits(gb, width);
+ while (i < j) {
+ if (s->bands[k] == i)
+ q = quant[k++];
+ if (coeffs[i] > 0) {
+ if (get_bits1(gb))
+ coeffs[i] *= -q;
+ else
+ coeffs[i] *= q;
+ }
+ i++;
+ }
+ } else {
while (i < j) {
if (s->bands[k] == i)
q = quant[k++];
@@ -245,6 +263,7 @@ static int decode_block(BinkAudioContext *s, float **out, int use_dct,
}
i++;
}
+ }
}
}
--
2.49.1
>From 964ad792bb8315717a615e27cbb2f6ec9aa544e4 Mon Sep 17 00:00:00 2001
From: Peter Ross <pross@xvid.org>
Date: Tue, 10 Dec 2024 23:25:49 +1100
Subject: [PATCH 2/4] avcodec/binkaudio: reindent
(cherry picked from librempeg commit 262ef722056fd654acae83eaba0765c47ce2cbe1)
---
libavcodec/binkaudio.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
index c77f2bf828..d791dba00b 100644
--- a/libavcodec/binkaudio.c
+++ b/libavcodec/binkaudio.c
@@ -247,22 +247,22 @@ static int decode_block(BinkAudioContext *s, float **out, int use_dct,
i++;
}
} else {
- while (i < j) {
- if (s->bands[k] == i)
- q = quant[k++];
- coeff = get_bits(gb, width);
- if (coeff) {
- int v;
- v = get_bits1(gb);
- if (v)
- coeffs[i] = -q * coeff;
- else
- coeffs[i] = q * coeff;
- } else {
- coeffs[i] = 0.0f;
+ while (i < j) {
+ if (s->bands[k] == i)
+ q = quant[k++];
+ coeff = get_bits(gb, width);
+ if (coeff) {
+ int v;
+ v = get_bits1(gb);
+ if (v)
+ coeffs[i] = -q * coeff;
+ else
+ coeffs[i] = q * coeff;
+ } else {
+ coeffs[i] = 0.0f;
+ }
+ i++;
}
- i++;
- }
}
}
}
--
2.49.1
>From 93bc6ee639bfbf4ccc91c8eee7e3bf14fcdae0df Mon Sep 17 00:00:00 2001
From: Peter Ross <pross@xvid.org>
Date: Tue, 10 Dec 2024 23:26:11 +1100
Subject: [PATCH 3/4] avcodec/binkaudio: drop a variable
(cherry picked from librempeg commit 3aecc96b32db4f271f0b4c70733b79a440bf9b68)
---
libavcodec/binkaudio.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
index d791dba00b..f392759424 100644
--- a/libavcodec/binkaudio.c
+++ b/libavcodec/binkaudio.c
@@ -252,9 +252,7 @@ static int decode_block(BinkAudioContext *s, float **out, int use_dct,
q = quant[k++];
coeff = get_bits(gb, width);
if (coeff) {
- int v;
- v = get_bits1(gb);
- if (v)
+ if (get_bits1(gb))
coeffs[i] = -q * coeff;
else
coeffs[i] = q * coeff;
--
2.49.1
>From 79023bae6340cdd72bd3b37b64aa7903baee6869 Mon Sep 17 00:00:00 2001
From: Peter Ross <pross@xvid.org>
Date: Tue, 10 Dec 2024 20:54:15 +1100
Subject: [PATCH 4/4] avformat: add Unreal Engine Bink Audio demuxer
(cherry picked from librempeg commit 8bddfb01dcf4641d560a9c2bf03603cb77f767ae)
---
libavformat/Makefile | 1 +
libavformat/allformats.c | 1 +
libavformat/ueba.c | 108 +++++++++++++++++++++++++++++++++++++++
3 files changed, 110 insertions(+)
create mode 100644 libavformat/ueba.c
diff --git a/libavformat/Makefile b/libavformat/Makefile
index ab5551a735..3ab52ec70d 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -606,6 +606,7 @@ OBJS-$(CONFIG_TTML_MUXER) += ttmlenc.o
OBJS-$(CONFIG_TTY_DEMUXER) += tty.o sauce.o
OBJS-$(CONFIG_TY_DEMUXER) += ty.o
OBJS-$(CONFIG_TXD_DEMUXER) += txd.o
+OBJS-$(CONFIG_UEBA_DEMUXER) += ueba.o
OBJS-$(CONFIG_UNCODEDFRAMECRC_MUXER) += uncodedframecrcenc.o framehash.o
OBJS-$(CONFIG_USM_DEMUXER) += usmdec.o
OBJS-$(CONFIG_V210_DEMUXER) += rawvideodec.o
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index e39eab8e85..6bf1945a6d 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -482,6 +482,7 @@ extern const FFOutputFormat ff_ttml_muxer;
extern const FFInputFormat ff_txd_demuxer;
extern const FFInputFormat ff_tty_demuxer;
extern const FFInputFormat ff_ty_demuxer;
+extern const FFInputFormat ff_ueba_demuxer;
extern const FFOutputFormat ff_uncodedframecrc_muxer;
extern const FFInputFormat ff_usm_demuxer;
extern const FFInputFormat ff_v210_demuxer;
diff --git a/libavformat/ueba.c b/libavformat/ueba.c
new file mode 100644
index 0000000000..b1ce23d03c
--- /dev/null
+++ b/libavformat/ueba.c
@@ -0,0 +1,108 @@
+/*
+ * 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
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "avformat.h"
+#include "demux.h"
+#include "internal.h"
+
+static int ueba_probe(const AVProbeData *p)
+{
+ if (AV_RL32(p->buf) == MKBETAG('U','E','B','A') && p->buf[4] == 1 &&
+ (p->buf[5] == 1 || p->buf[5] == 2) && AV_RL32(p->buf + 8))
+ return AVPROBE_SCORE_MAX / 2;
+ return 0;
+}
+
+static int ueba_read_header(AVFormatContext *s)
+{
+ AVIOContext *pb = s->pb;
+ AVStream *st;
+ int nb_seek_entries, ret;
+
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ avio_skip(pb, 5);
+ st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codecpar->codec_id = AV_CODEC_ID_BINKAUDIO_DCT;
+ st->codecpar->ch_layout.nb_channels = avio_r8(pb);
+ avio_skip(pb, 2);
+ st->codecpar->sample_rate = avio_rl32(pb);
+ st->duration = avio_rl32(pb);
+ avio_skip(pb, 8);
+ nb_seek_entries = avio_rl16(pb);
+ avio_skip(pb, 2 + nb_seek_entries * 2);
+
+ avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
+
+ if ((ret = ff_alloc_extradata(st->codecpar, 1)) < 0)
+ return ret;
+ st->codecpar->extradata[0] = '2';
+
+ return 0;
+}
+
+static int ueba_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ AVIOContext *pb = s->pb;
+ AVStream *st = s->streams[0];
+ int64_t pos;
+ int magic, size, duration, ret;
+
+ pos = avio_tell(pb);
+
+ magic = avio_rl16(pb);
+ if (avio_feof(pb))
+ return AVERROR_EOF;
+ if (magic != 0x9999)
+ return AVERROR_INVALIDDATA;
+
+ size = avio_rl16(pb);
+ if (size == 0xFFFF) {
+ size = avio_rl16(pb);
+ duration = avio_rl16(pb);
+ } else {
+ duration = av_get_audio_frame_duration2(st->codecpar, 0);
+ }
+ if (size <= 0)
+ return AVERROR(EIO);
+
+ ret = av_new_packet(pkt, size + 4);
+ if (ret < 0)
+ return ret;
+
+ AV_WL32(pkt->data, size);
+ avio_read(pb, pkt->data + 4, size);
+
+ pkt->pos = pos;
+ pkt->stream_index = 0;
+ pkt->duration = duration;
+
+ return 0;
+}
+
+const FFInputFormat ff_ueba_demuxer = {
+ .p.name = "ueba",
+ .p.long_name = NULL_IF_CONFIG_SMALL("Unreal Engine Bink Audio"),
+ .p.flags = AVFMT_GENERIC_INDEX,
+ .read_probe = ueba_probe,
+ .read_header = ueba_read_header,
+ .read_packet = ueba_read_packet,
+};
--
2.49.1
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2025-08-28 8:37 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-08-28 8:37 [FFmpeg-devel] [PATCH] Bink 2 Audio decoder and demuxer (PR #20359) Peter Ross 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