This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 0d64b5ad6c93f4abc153b0e572a9ffe475b2269d Author: James Almer <[email protected]> AuthorDate: Thu Sep 4 17:24:12 2025 +1000 Commit: Peter Ross <[email protected]> CommitDate: Fri Sep 25 22:12:25 2026 +0000 avformat/binka: support Unreal Engine Bink Audio format variant --- libavformat/binka.c | 55 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 11 deletions(-) diff --git a/libavformat/binka.c b/libavformat/binka.c index e8a8efae3d..cadb7238d4 100644 --- a/libavformat/binka.c +++ b/libavformat/binka.c @@ -24,16 +24,24 @@ #include "demux.h" #include "internal.h" +typedef struct BinkaDemuxContext { + int is_ueba; +} BinkaDemuxContext; + static int binka_probe(const AVProbeData *p) { if (AV_RB32(p->buf) == MKBETAG('1', 'F', 'C', 'B') && (p->buf[4] == 1 || p->buf[4] == 2)) return AVPROBE_SCORE_MAX; + 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; return 0; } static int binka_read_header(AVFormatContext *s) { + BinkaDemuxContext *binka = s->priv_data; AVIOContext *pb = s->pb; AVStream *st; int entries, offset; @@ -42,12 +50,20 @@ static int binka_read_header(AVFormatContext *s) if (!st) return AVERROR(ENOMEM); - avio_skip(pb, 5); + binka->is_ueba = avio_rl32(pb) == MKBETAG('U','E','B','A'); + + avio_skip(pb, 1); 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); - st->codecpar->sample_rate = avio_rl16(pb); + if (binka->is_ueba) { + avio_skip(pb, 2); + st->codecpar->sample_rate = avio_rl32(pb); + if (st->codecpar->sample_rate <= 0) + return AVERROR_INVALIDDATA; + } else + st->codecpar->sample_rate = avio_rl16(pb); st->duration = avio_rl32(pb); avio_skip(pb, 8); @@ -58,37 +74,53 @@ static int binka_read_header(AVFormatContext *s) avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); + if (binka->is_ueba) { + int ret = ff_alloc_extradata(st->codecpar, 1); + if (ret < 0) + return ret; + st->codecpar->extradata[0] = '2'; + } + return 0; } static int binka_read_packet(AVFormatContext *s, AVPacket *pkt) { + BinkaDemuxContext *binka = s->priv_data; AVIOContext *pb = s->pb; AVStream *st = s->streams[0]; - int64_t pos; + int64_t pos, duration; int pkt_size; int ret; + pos = avio_tell(pb); + avio_skip(pb, 2); + if (avio_feof(pb)) return AVERROR_EOF; - pos = avio_tell(pb); - avio_skip(pb, 2); - pkt_size = avio_rl16(pb) + 4; - if (pkt_size <= 4) + pkt_size = avio_rl16(pb); + if (!pkt_size) return AVERROR_INVALIDDATA; - ret = av_new_packet(pkt, pkt_size); + + if (binka->is_ueba && pkt_size == 0xFFFF) { + pkt_size = avio_rl16(pb); + duration = avio_rl16(pb); + } else + duration = av_get_audio_frame_duration2(st->codecpar, 0); + + ret = av_new_packet(pkt, pkt_size + 4); if (ret < 0) return ret; - ret = ffio_read_size(pb, pkt->data + 4, pkt_size - 4); + ret = ffio_read_size(pb, pkt->data + 4, pkt_size); if (ret < 0) return ret; AV_WL32(pkt->data, pkt_size); pkt->pos = pos; pkt->stream_index = 0; - pkt->duration = av_get_audio_frame_duration2(st->codecpar, 0); + pkt->duration = duration; return 0; } @@ -96,8 +128,9 @@ static int binka_read_packet(AVFormatContext *s, AVPacket *pkt) const FFInputFormat ff_binka_demuxer = { .p.name = "binka", .p.long_name = NULL_IF_CONFIG_SMALL("Bink Audio"), - .p.flags = AVFMT_GENERIC_INDEX, + .p.flags = AVFMT_GENERIC_INDEX | AVFMT_NOTIMESTAMPS, .p.extensions = "binka", + .priv_data_size = sizeof(BinkaDemuxContext), .read_probe = binka_probe, .read_header = binka_read_header, .read_packet = binka_read_packet, -- To stop receiving notification emails like this one, please contact [email protected]. _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
