From: Peter Ross via ffmpeg-devel <ffmpeg-devel@ffmpeg.org> To: ffmpeg-devel@ffmpeg.org Cc: Peter Ross <code@ffmpeg.org> Subject: [FFmpeg-devel] [PATCH] Bink 2 Audio decoder and demuxer (PR #20359) Message-ID: <175637018236.25.16069003597252911746@463a07221176> (raw) 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
reply other threads:[~2025-08-28 8:37 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=175637018236.25.16069003597252911746@463a07221176 \ --to=ffmpeg-devel@ffmpeg.org \ --cc=code@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
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