From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.ffmpeg.org (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id 536E74ABBC for ; Thu, 28 Aug 2025 08:37:03 +0000 (UTC) Authentication-Results: ffbox; dkim=fail (body hash mismatch (got b'rpcTrLOgNTQJuDqV62sOXTzPIHiE3WgSzpjVpgWy50E=', expected b'V+2pUHm1NOXA8aiBAtkp+B9+Sh6ZxlVqCIDkt2jweGM=')) header.d=ffmpeg.org header.i=@ffmpeg.org header.a=rsa-sha256 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ffmpeg.org; i=@ffmpeg.org; q=dns/txt; s=mail; t=1756370204; h=mime-version : to : message-id : reply-to : subject : list-id : list-archive : list-archive : list-help : list-owner : list-post : list-subscribe : list-unsubscribe : from : cc : content-type : content-transfer-encoding : from; bh=rpcTrLOgNTQJuDqV62sOXTzPIHiE3WgSzpjVpgWy50E=; b=h3lL0+mObmCeKBovdrLJdtSHIdoVpQifnojza4Pl9gWKsWscGmROHUtCb8HYo7ecv4OZd ynmBWmYVtCQP2MKiK9058QDMyJ+EP7R1lvp1XzDk1CK1Nne6sw+PzgtSxGAqzB2QfZwziaZ PH6iR8Xm22/F3tFPdNhEg9zJg39fb53+XFc0C53k19A8dJM1xYo4JkgHD2TmCP37BfWUIVr v0ZeAZ5Oye+sSrvgt7zDB7nmGAseCuWsJKPWK4q3dHa23aFnWq0snD964XkpVggQUuPVXDX vD+hp5ooBufg8eigEfMBbOZxINNDD6dFBQvmxNIXLjYo9oLrkIIQGIdc7htQ== Received: from [172.19.0.4] (unknown [172.19.0.4]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id 2BD9F68C8E4; Thu, 28 Aug 2025 11:36:44 +0300 (EEST) ARC-Seal: i=1; cv=none; a=rsa-sha256; d=ffmpeg.org; s=arc; t=1756370194; b=XvWfsei6bd16ZAuXPTRiM1WU5MXRMrsX3c6ZTpdZI6EGv50eKoeUEUMeUPZTDfhzXIqXA cesw1lx+gjNhStjYoo6tE/68J7jLcA21LPPrhIumN+nfXCZ+5nBhLesXcU3nXi0QUk+MTB9 t3g6VO+9ToTUEIzq5iJi5PZCSVyNhEhe/Rdu4aQCkk443xMxDaap65kYra2jLB6VIUM0cOi V052erxeobXD3zNdiXMhxvwyTqdDnIEV5X6JjdknxqttgS2XbA5SqeOCp4DZhJJb+ZUADSj TyFDqZqv2/pTffTIIR5K17Ri8sxRcHCQRqnTQPkLiJMFB7p43251XhOoaM1w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=ffmpeg.org; s=arc; t=1756370194; h=from : sender : reply-to : subject : date : message-id : to : cc : mime-version : content-type : content-transfer-encoding : content-id : content-description : resent-date : resent-from : resent-sender : resent-to : resent-cc : resent-message-id : in-reply-to : references : list-id : list-help : list-unsubscribe : list-subscribe : list-post : list-owner : list-archive; bh=AX3SNGzXZ1+SUFh3BSL0wi3d50p2GsqqXtL/L/v1J4o=; b=KdgPbCrxNhycb6JrV3tw1RcrOZr7Ln2pinsZInv/LcKXQm2onFm0NC7yIUBsOdCYvLmfm YblhUXRignx3MIa/k5RSLHMUTs+DN18/fIy1njl107IYWzaUwax/9v+ZOlBGGCJU9yM7iP6 wmkU9H7XqnyF/HRaNxI6CEyUF6s92PpRK9/cbtKzU7MzRhyOJ5IyOxxUmYffkngP0X6lyM1 YMy52K/lylReHkrQ6+LPSZyciicG9sUNxtBX9iJ3RitC5VYa904TZBSXFOEYNOAL01UZPpM UZuKkkU0qacz/Fr9oraMtCiST4JNktXH6xlL8MUv5N/EolCrVnxoSJVAULGw== ARC-Authentication-Results: i=1; ffmpeg.org; dkim=pass header.d=ffmpeg.org header.i=@ffmpeg.org; arc=none; dmarc=none Authentication-Results: ffmpeg.org; dkim=pass header.d=ffmpeg.org header.i=@ffmpeg.org; arc=none (Message is not ARC signed); dmarc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ffmpeg.org; i=@ffmpeg.org; q=dns/txt; s=mail; t=1756370182; h=content-type : mime-version : content-transfer-encoding : from : to : reply-to : subject : from; bh=V+2pUHm1NOXA8aiBAtkp+B9+Sh6ZxlVqCIDkt2jweGM=; b=lNlSpanN+r80us824s6UMSLT888EROSVJ2sAThQTo0rDc4pZwoOXky1iwdTaGp1CS2Ml5 Bcy6ZlCGntprEkQx9m3+xhlU6trY8JWpsKng9kp1hzmYucqOAagI1As6cnIIDqldwqvmmg8 LnNEyfIKtKny1PXsAaiIgf4fITvCv17YrII6VoT3vEFA/Z5UeN+m76cRWVpmYaKTHFgdLco JU+bnfoRFoq4oXct3KV2m2khSCI25u8qYkwLuRIJo8y+bWYum+KoxDHub6J606ZuAfNCQN+ hv+M2LnYlP7kC3CABUnDzj7Zd/HD/6w6SPRjDDA7mGxzC1b6wyntdntwJPtA== Received: from 5d8f51c41678 (code.ffmpeg.org [188.245.149.3]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTPS id 1C00A6802BD for ; Thu, 28 Aug 2025 11:36:22 +0300 (EEST) MIME-Version: 1.0 To: ffmpeg-devel@ffmpeg.org Message-ID: <175637018236.25.16069003597252911746@463a07221176> Message-ID-Hash: JMNRNVQXE2XNMJNJD4NP3MCYZ7QB7ZA4 X-Message-ID-Hash: JMNRNVQXE2XNMJNJD4NP3MCYZ7QB7ZA4 X-MailFrom: code@ffmpeg.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-ffmpeg-devel.ffmpeg.org-0; header-match-ffmpeg-devel.ffmpeg.org-1; header-match-ffmpeg-devel.ffmpeg.org-2; header-match-ffmpeg-devel.ffmpeg.org-3; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list Reply-To: FFmpeg development discussions and patches Subject: [FFmpeg-devel] [PATCH] Bink 2 Audio decoder and demuxer (PR #20359) List-Id: FFmpeg development discussions and patches Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Peter Ross via ffmpeg-devel Cc: Peter Ross Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Archived-At: List-Archive: List-Post: 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 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 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 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 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