MUX
- Extension: mux
- Samples: http://samples.mplayerhq.hu/game-formats/chaoscontrol-mux/
MUX is a full motion video format used in a small number of computer games. The format packages raw, unsigned, 8-bit PCM audio along with a custom video coding format.
File Format
All multi-byte numbers are little endian. The file format is laid out as follows:
dword signature - file signature, 0xAA07 word headersize - size of the whole header, including frames table word num_entries - number of filled entries in frame table word unknown2 word unknown3 word framerate - movie playback rate, direct PIC initializer word soundfrequency - audio playback frequency dword videobuffer_size - suggested size of the single video buffer word soundbuffer_size - suggested size of the single audio buffer dword chunkbuffer_size - suggested size of the chunk load buffer word sound_buffers - suggested number of sound buffers word width - width of the frame word height - height of the frame
Then followed by frame offsets table. Each frame offset is 32 bits. The top 2 bits of each offset contains flags (completely ignored by original player) the rest is an absolute offset of the frame chunks. The last entry in the table is all 1s (0xFFFFFFFF) and the remainder of the table is all 0s. Note, that table contains offset to the first chunk of each frame. There are usually several frame chunks, e.g. a sequence of audio data, palette, video data and frame end marker, but individual chunks do not appear in offsets table.
Frames contain 1 or more chunks, each of which are formatted in a manner that is reminiscent of the Autodesk FLIC format:
byte 0 chunk type byte 1 chunk subtype bytes 2-5 chunk size, not including this 6-byte header bytes 6.. chunk payload
Known chunk types appear to include:
06, 07 unsigned, 8-bit PCM audio (type 07 is used just for the first audio chunk) 65, 70 palette chunk, 0x300 (768) bytes/256 RGB components, and each component is 8 bits (not 6 bits, like VGA palettes are normally stored) 64, 6F video chunks 05 sync chunk. usually the last chunk of the frame, 2-byte payload contains frame number 04 eof-chunk, indicates end of the movie
Video Format
Each video chunk begins with the following header
byte - flags dword - output start dword - bits part size dword - colours part size
Flags meaning:
- 0 - frame is intra coded
- 2 - frame is inter coded
- 1 - frame uses partial LZ compression and intra coding
- 3 - frame uses partial LZ compression and inter coding
- 4 - frame uses full LZ compression and intra coding
- 6 - frame uses full LZ compression and inter coding
- 8 - frame is compressed using method 8
Method 8 is a separate coding method, other formats split data into control bits part and colours part. Depending on frame flags this data may be transmitted as is, compressed using LZ77-like scheme or only colours part is compressed.
All compression methods pack various bits together. For bit reading you need to read 32-bit LE word from the stream in the beginning and when it's exhausted and you need another bit you read the whole word again. Similarly for nibbles you read the whole byte, use top nibble immediately and save low nibble for the next call (and in subsequent call you refill it again).
Buffer compression
In case of full LZ compression the following algorithm is used:
while there's still data to decode { flags = get_32le(); for (;;) { bit = flags >> 31; flags <<= 1; if (!flags) break; if (bit) { let = get_nibble() + 1; copy len bytes from input to output } else { offset = get_byte(); len = get_nibble() + 2; copy len bytes from output - offset } } }
When we use partial LZ, first we decode colours data with the following algorithm and then use the rest of input for control bits:
while there is still colour data to decode { val = (int8_t)get_byte(); if (val >= 0) *dst++ = val else { len = get_nibble() + 2; copy len bytes from output + val (it is a negative offset already) } }
Video coding
The intra and inter compression are almost the same. They employ variable-length codes to code runs. Bit groups may be interspersed with nibble groups or full byte. Only colours belong to the second part.
Codes for intra (they are decoded bit by bit):
0
- get colour from colours stream, output it10
- long run, get nibble, if it's not zero thenlen = nibble + 4
, otherwiselen
is next byte from control bits stream plus twenty. Get colour, repeat itlen
times110
- get colour, repeat it twice1110
- get colour, repeat it three times1111
- get colour, repeat it four times
Codes for inter:
0
- get colour from colours stream, output it10
- long run, get nibble, if it's not zero thenlen = nibble + 4
, otherwiselen
is next byte from control bits stream plus twenty. Get colour, repeat itlen
times110
- get colour, repeat it twice1110
- get colour, repeat it three times11110
- get colour, repeat it four times11111
- skip the amount of pixels equal to the next byte from control bits stream
Method 8 coding
This method is used is some of the videos in <emph>Chaos Control</emph>. It seems to be some kind of 2D RLE since it codes several pixels on several lines at once with varying widths too (e.g. it can issue a command "add 2 copies of pixel 0x2A
on line 0, 1 copy of it on line 1 and 2 copies of it on line 2). Bytestream for this format consists of packed commands telling which pixel to add on how many lines and with which widths (which may be coded independent or relative to the previous one as well).
Games That Use MUX
These games are known to use MUX files for FMV: