Skip to content

Commit ab3e061

Browse files
XJDHDRpaxcut
andauthored
Add Bink Video Container pattern (#513)
Add pattern for Bink Container format Co-authored-by: paxcut <53811119+paxcut@users.noreply.github.com>
1 parent d709e6f commit ab3e061

3 files changed

Lines changed: 144 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
5151
| BLF | | [`patterns/blf.hexpat`](patterns/blf.hexpat) | Vector BLF Frame Logging Files |
5252
| BMP | `image/bmp` | [`patterns/bmp.hexpat`](patterns/bmp.hexpat) | OS2/Windows Bitmap files |
5353
| BIN | | [`patterns/selinux.hexpat`](patterns/selinux.pat) | SE Linux modules |
54+
| BINK Container | `video/vnd.radgamettools.bink` | [`patterns/bink_container.hexpat`](patterns/bink_container.hexpat) | [RAD Game Tools Bink Video Container files](https://en.wikipedia.org/wiki/Bink_Video) |
5455
| BINKA | | [`patterns/binka.hexpat`](patterns/binka.pat) | RAD Game Tools Bink Audio (BINKA) files |
5556
| BSON | `application/bson` | [`patterns/bson.hexpat`](patterns/bson.hexpat) | BSON (Binary JSON) format |
5657
| BTRFS Send Stream | | [`patterns/btrfs_send_stream.hexpat`](patterns/btrfs_send_stream.hexpat) | BTRFS Send Stream format |

patterns/bink_container.hexpat

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
2+
// If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
3+
4+
5+
#pragma endian little
6+
#pragma magic [42 49 4B] @ 0x00
7+
#pragma MIME video/vnd.radgamettools.bink
8+
9+
#pragma author Xavier "XJDHDR" du Hecquet de Rauville
10+
#pragma description Bink Video Container - RAD Game Tools
11+
12+
13+
// GLOBALS
14+
u32 CurrentFrame = 0;
15+
16+
17+
// ENUMS
18+
enum WidthHeightScaling : u8
19+
{
20+
NoScaling = 0,
21+
HeightDoubled = 1,
22+
HeightInterlaced = 2,
23+
WidthDoubled = 3,
24+
WidthHeightDoubled = 4,
25+
WidthHeightInterlaced = 5,
26+
};
27+
28+
enum AudioAlgorithm : bool
29+
{
30+
DCT = 0,
31+
FFT = 1,
32+
};
33+
34+
35+
// BITFIELDS
36+
bitfield VideoFlags
37+
{
38+
Unknown1 : 16;
39+
bool Greyscale : 1;
40+
Unknown2 : 2;
41+
bool HasAlphaPLane : 1;
42+
Unknown3 : 7;
43+
WidthHeightScaling Scaling : 4;
44+
};
45+
46+
bitfield AudioPropertyFlags
47+
{
48+
Unknown1 : 11;
49+
AudioAlgorithm Algorithm : 1;
50+
bool IsStereo : 1;
51+
bool HasAlphaPLane : 1;
52+
Unknown2 : 2;
53+
};
54+
55+
fn maskFirstBit(u32 originalValue) {
56+
return (originalValue & 0xFFFFFFFE);
57+
};
58+
59+
bitfield FrameAddressData {
60+
bool IsKeyframe: 1 [[no_unique_address]];
61+
FrameAddress: 32 [[transform("maskFirstBit")]];
62+
};
63+
64+
65+
// STRUCTS
66+
struct AudioChannelData
67+
{
68+
u16 Unknown;
69+
u16 NotAuthoritativeAudioChannelQty;
70+
};
71+
72+
struct AudioChannelProperties
73+
{
74+
u16 SampleRate;
75+
AudioPropertyFlags NotAuthoritativeAudioChannelQty;
76+
};
77+
78+
struct BinkHeader
79+
{
80+
char MagicNumber[3];
81+
char BinkVersion;
82+
u32 SizeOfRemainingBytes;
83+
u32 NumberOfFrames;
84+
u32 LargestFrameSize;
85+
u32 NumberOfFramesAgain;
86+
u32 VideoFrameWidth;
87+
u32 VideoFrameHeight;
88+
u32 VideoFPSDividend;
89+
u32 VideoFPSDivisor;
90+
VideoFlags VideoFlags;
91+
u32 AudioTrackQty;
92+
AudioChannelData AudioChannelData[AudioTrackQty];
93+
AudioChannelProperties AudioChannelProperties[AudioTrackQty];
94+
u32 AudioTrackIDs[AudioTrackQty];
95+
};
96+
97+
struct BinkAudioTrack
98+
{
99+
u32 LengthOfRemainingTrackData;
100+
101+
if (LengthOfRemainingTrackData > 0)
102+
{
103+
u32 SamplesQty;
104+
u8 AudioPacket[LengthOfRemainingTrackData - 4];
105+
}
106+
};
107+
108+
fn calculateVideoPacketSize(BinkHeader header, ref FrameAddressData frameAddresses, ref BinkAudioTrack audioTracks)
109+
{
110+
u32 thisFrameTotalSize = frameAddresses[CurrentFrame + 1].FrameAddress - frameAddresses[CurrentFrame].FrameAddress;
111+
112+
u32 sizeOfAllAudioTracks = 0;
113+
for (u8 i = 0, i < header.AudioTrackQty, i += 1)
114+
{
115+
sizeOfAllAudioTracks += audioTracks[i].LengthOfRemainingTrackData + 4;
116+
}
117+
118+
u32 videoPacketSize = thisFrameTotalSize - sizeOfAllAudioTracks;
119+
return videoPacketSize;
120+
};
121+
122+
struct BinkFrame
123+
{
124+
BinkAudioTrack AudioTracks[parent.Header.AudioTrackQty];
125+
u8 VideoPacket[calculateVideoPacketSize(parent.Header, parent.FrameAddresses, AudioTracks)];
126+
127+
CurrentFrame += 1;
128+
$ = parent.FrameAddresses[CurrentFrame].FrameAddress;
129+
};
130+
131+
struct BinkFile
132+
{
133+
BinkHeader Header;
134+
FrameAddressData FrameAddresses[Header.NumberOfFrames + 1];
135+
136+
$ = FrameAddresses[0].FrameAddress;
137+
138+
BinkFrame Frames[Header.NumberOfFrames];
139+
};
140+
141+
142+
// ENTRYPOINT
143+
BinkFile binkFile @ 0x0;
2.35 MB
Binary file not shown.

0 commit comments

Comments
 (0)