Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [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