UDocumentation
UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
binka_ue_file_header.h
Go to the documentation of this file.
1
// Copyright Epic Games, Inc. All Rights Reserved.
2
3
#pragma once
4
#include <stdint.h>
5
6
typedef
uint32_t
uint32
;
7
typedef
uint16_t
uint16
;
8
typedef
uint8_t
uint8
;
9
10
struct
BinkAudioFileHeader
11
{
12
uint32
tag
;
// UEBA
13
uint8
version
;
14
uint8
channels
;
15
uint16
PADDING
;
// unused atm.
16
uint32
rate
;
17
uint32
sample_count
;
18
19
// the max for a bink audio block - includes all streams, but does _not_ include
20
// the block header info.
21
uint16
max_comp_space_needed
;
22
23
// unused in UE (holds whether it's BA2 or not, which is always true for UE)
24
uint16
flags
;
25
26
// bytes for the whole file
27
uint32
output_file_size
;
28
29
// number of encoded seek table entries stored directly after the file header.
30
// each one is 16 bits, and is the delta from the last entry.
31
uint16
seek_table_entry_count
;
32
33
// number of bink audio blocks for a single entry in the seek table. Encoding
34
// keeps seek tables under 4k, so larger files will correspondingly have more
35
// distance between seek table lookup points. Note that while you could consider
36
// each bink audio stream decode a single block, this is referring to the set
37
// of low level bink audio blocks for a given timepoint (so for 6 channels, you
38
// have 3 low level bink streams, but the set of those 3 is referred to as one
39
// block for the purposes of this.)
40
uint16
blocks_per_seek_table_entry
;
41
};
42
43
#define BLOCK_HEADER_MAGIC 0x9999
44
45
static
bool
BinkAudioBlockSize(
uint32
header_max_comp_space_needed
,
uint8
const
*
input_reservoir
,
uint32
input_reservoir_len
,
uint32
*
out_block_size
)
46
{
47
//
48
// Returns true if the current input buffer can be decoded
49
//
50
if
(
input_reservoir_len
< 4)
51
{
52
// need an unknown amount of data - fill the reservoir
53
return
false
;
54
}
55
56
// Check for the frame header.
57
uint32
FrameHeaderSize
= 4;
58
uint32
FrameCheck
= *(
uint32
*)(
input_reservoir
);
59
60
if
((
FrameCheck
& 0xffff) !=
BLOCK_HEADER_MAGIC
)
61
{
62
return
false
;
63
}
64
65
uint32
FrameSize =
FrameCheck
>> 16;
66
if
(FrameSize == 0xffff)
67
{
68
// Trimmed frame - size & sample next.
69
if
(
input_reservoir_len
< 8)
70
{
71
return
false
;
72
}
73
74
uint32
TrimmedFrameHeader
= *(
uint32
*)(
input_reservoir
+ 4);
75
FrameSize =
TrimmedFrameHeader
& 0xffff;
76
FrameHeaderSize
= 8;
77
}
78
79
if
(FrameSize >
header_max_comp_space_needed
)
80
{
81
// Invalid frame.
82
return
false
;
83
}
84
85
*
out_block_size
= FrameSize +
FrameHeaderSize
;
86
return
true
;
87
}
88
89
#define BINK_AUDIO_BLOCK_VALID 0
// The buffer can be passed to Bink.
90
#define BINK_AUDIO_BLOCK_INCOMPLETE 1
// The buffer looks good but needs more data
91
#define BINK_AUDIO_BLOCK_INVALID 2
// Buffer consistency checks failed.
92
static
uint8
BinkAudioValidateBlock(
uint32
header_max_comp_space_needed
,
uint8
const
*
input_reservoir
,
uint32
input_reservoir_len
)
93
{
94
//
95
// Returns true if the current input buffer can be decoded,
96
// doesn't affect BcfStr at all.
97
//
98
uint8
const
*
input_buffer
=
input_reservoir
;
99
uint8
const
*
input_end
=
input_reservoir
+
input_reservoir_len
;
100
101
if
(
input_reservoir_len
< 4)
102
return
BINK_AUDIO_BLOCK_INCOMPLETE
;
// no space for header.
103
104
// Check for the frame header.
105
uint32
FrameCheck
= *(
uint32
const
*)(
input_buffer
);
106
input_buffer
+= 4;
107
if
((
FrameCheck
& 0xffff) !=
BLOCK_HEADER_MAGIC
)
108
{
109
return
BINK_AUDIO_BLOCK_INVALID
;
110
}
111
112
uint32
FrameSize =
FrameCheck
>> 16;
113
if
(FrameSize == 0xffff)
114
{
115
// Trimmed frame - size & sample next.
116
if
(
input_reservoir_len
< 8)
117
return
BINK_AUDIO_BLOCK_INCOMPLETE
;
// no space for header
118
119
uint32
TrimmedFrameHeader
= *(
uint32
const
*)(
input_buffer
);
120
input_buffer
+= 4;
121
FrameSize =
TrimmedFrameHeader
& 0xffff;
122
}
123
124
if
(FrameSize >
header_max_comp_space_needed
)
125
{
126
// Invalid frame.
127
return
BINK_AUDIO_BLOCK_INVALID
;
128
}
129
130
uint8
const
*
frame_end
=
input_buffer
+ FrameSize;
131
if
(
frame_end
>
input_end
)
132
return
BINK_AUDIO_BLOCK_INCOMPLETE
;
// frame isn't resident
133
134
if
(
frame_end
==
input_end
)
135
return
BINK_AUDIO_BLOCK_VALID
;
// we assume it's valid, even though it's possible that it's a fake.
136
137
if
(
frame_end
+ 4 <=
input_end
)
138
{
139
// we have enough to double check.
140
if
((*(
uint32
const
*)(
frame_end
) & 0xffff) !=
BLOCK_HEADER_MAGIC
)
141
{
142
// This was a fake!
143
return
BINK_AUDIO_BLOCK_INVALID
;
144
}
145
}
146
147
return
BINK_AUDIO_BLOCK_VALID
;
148
}
149
150
// input_reservoir MUST have passed BinkAudioValidateBlock
151
static
void
BinkAudioCrackBlock(
uint8
const
*
input_reservoir
,
uint8
const
**
out_block_start
,
uint8
const
**
out_block_end
,
uint32
*
out_trim_to_sample_count
)
152
{
153
uint8
const
*
input_buffer
= (
uint8
const
*)
input_reservoir
;
154
uint32
FrameCheck
= *(
uint32
const
*)(
input_buffer
);
155
input_buffer
+= 4;
156
157
uint32
TrimToSampleCount
= ~0U;
158
uint32
FrameBytes =
FrameCheck
>> 16;
159
if
(FrameBytes == 0xffff)
160
{
161
// Trimmed frame - # of output samples after.
162
uint32
TrimmedFrameHeader
= *(
uint32
const
*)(
input_buffer
);
163
input_buffer
+= 4;
164
165
FrameBytes =
TrimmedFrameHeader
& 0xffff;
166
TrimToSampleCount
=
TrimmedFrameHeader
>> 16;
167
}
168
169
*
out_block_start
=
input_buffer
;
170
*
out_block_end
=
input_buffer
+ FrameBytes;
171
*
out_trim_to_sample_count
=
TrimToSampleCount
;
172
}
StaticCastSharedRef
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition
SharedPointer.h:127
BINK_AUDIO_BLOCK_VALID
#define BINK_AUDIO_BLOCK_VALID
Definition
binka_ue_file_header.h:89
uint8
uint8_t uint8
Definition
binka_ue_file_header.h:8
BINK_AUDIO_BLOCK_INVALID
#define BINK_AUDIO_BLOCK_INVALID
Definition
binka_ue_file_header.h:91
uint16
uint16_t uint16
Definition
binka_ue_file_header.h:7
uint32
uint32_t uint32
Definition
binka_ue_file_header.h:6
BINK_AUDIO_BLOCK_INCOMPLETE
#define BINK_AUDIO_BLOCK_INCOMPLETE
Definition
binka_ue_file_header.h:90
BLOCK_HEADER_MAGIC
#define BLOCK_HEADER_MAGIC
Definition
binka_ue_file_header.h:43
BinkAudioFileHeader
Definition
binka_ue_file_header.h:11
BinkAudioFileHeader::seek_table_entry_count
uint16 seek_table_entry_count
Definition
binka_ue_file_header.h:31
BinkAudioFileHeader::channels
uint8 channels
Definition
binka_ue_file_header.h:14
BinkAudioFileHeader::blocks_per_seek_table_entry
uint16 blocks_per_seek_table_entry
Definition
binka_ue_file_header.h:40
BinkAudioFileHeader::tag
uint32 tag
Definition
binka_ue_file_header.h:12
BinkAudioFileHeader::sample_count
uint32 sample_count
Definition
binka_ue_file_header.h:17
BinkAudioFileHeader::PADDING
uint16 PADDING
Definition
binka_ue_file_header.h:15
BinkAudioFileHeader::rate
uint32 rate
Definition
binka_ue_file_header.h:16
BinkAudioFileHeader::version
uint8 version
Definition
binka_ue_file_header.h:13
BinkAudioFileHeader::flags
uint16 flags
Definition
binka_ue_file_header.h:24
BinkAudioFileHeader::output_file_size
uint32 output_file_size
Definition
binka_ue_file_header.h:27
BinkAudioFileHeader::max_comp_space_needed
uint16 max_comp_space_needed
Definition
binka_ue_file_header.h:21
Engine
Source
Runtime
BinkAudioDecoder
SDK
BinkAudio
Include
binka_ue_file_header.h
Generated by
1.9.8