MUX: Difference between revisions

From MultimediaWiki
Jump to navigation Jump to search
No edit summary
 
(add some information)
 
(11 intermediate revisions by 7 users not shown)
Line 1: Line 1:
* Extensions: mux
* Extension: mux
* Samples: [http://samples.mplayerhq.hu/game-formats/chaoscontrol-mux/ http://samples.mplayerhq.hu/game-formats/chaoscontrol-mux/]


In 1995, Philips/Infogrames/I-Motion published a game called [http://www.mobygames.com/game/dos/chaos-control Chaos Control]. Its CD-ROM contains 4 files: A game executable, an installation executable, a readme.txt file, and a 200 MB chaos.gb resource file which contains the game's data. Some of the data files have the extension .mux. These are apparently FMV files.
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.


All multi-byte number are little endian. The file format is laid out as follows:
== File Format ==


  bytes 0-27      unknown
All multi-byte numbers are little endian. The file format is laid out as follows:
  bytes 28-29      video width
  bytes 30-31      video height
  bytes 32-16383  frame offset table


Each frame offset is 32 bits. There is enough space in the chunk offset table for 4087 media chunks. The top 2 bits of each offset always appear to be 1 (so the top byte of the chunk is always 0xC0), so these are probably flags of some sort. The last entry in the table is all 1s (0xFFFFFFFF) and the remainder of the table is all 0s.
  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


Frames contain 1 or more chunks, each of which are formatted in a manner that is reminiscent of the Autodesk FLIC format:
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.


   bytes 0-1   chunk type
Frames contain 1 or more chunks, each of which are formatted in a manner that is reminiscent of the [[Flic Video|Autodesk FLIC format]]:
 
   byte  0     chunk type
  byte  1     chunk subtype
   bytes 2-5    chunk size, not including this 6-byte header
   bytes 2-5    chunk size, not including this 6-byte header
   bytes 6..    chunk payload
   bytes 6..    chunk payload
Line 20: Line 33:
Known chunk types appear to include:
Known chunk types appear to include:


   0007   unsigned, 8-bit PCM audio
   06,
   0070   apparently a palette chunk, 0x300 (768) bytes, and each  
  07   unsigned, 8-bit [[PCM]] audio (type 07 is used just for the first audio chunk)
          component is 8 bits (not 6 bits, like VGA palettes are  
  65,
          normally stored)
   70   palette chunk, 0x300 (768) bytes/256 [[RGB]] components, and each component is 8 bits
   006F   video chunk
        (not 6 bits, like VGA palettes are normally stored)
   0005   frame count: 2-byte payload contains frame number
   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):
 
* <code>0</code> - get colour from colours stream, output it
* <code>10</code> - long run, get nibble, if it's not zero then <code>len = nibble + 4</code>, otherwise <code>len</code> is next byte from control bits stream plus twenty. Get colour, repeat it <code>len</code> times
* <code>110</code> - get colour, repeat it twice
* <code>1110</code> - get colour, repeat it three times
* <code>1111</code> - get colour, repeat it four times
 
Codes for inter:
 
* <code>0</code> - get colour from colours stream, output it
* <code>10</code> - long run, get nibble, if it's not zero then <code>len = nibble + 4</code>, otherwise <code>len</code> is next byte from control bits stream plus twenty. Get colour, repeat it <code>len</code> times
* <code>110</code> - get colour, repeat it twice
* <code>1110</code> - get colour, repeat it three times
* <code>11110</code> - get colour, repeat it four times
* <code>11111</code> - 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 <code>0x2A</code> 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:


The corresponding video coding format is presently unknown.
* [http://www.mobygames.com/game/dos/chaos-control Chaos Control]
* [http://www.mobygames.com/game/dos/prisoner-of-ice Prisoner of Ice]
* [http://www.mobygames.com/game/dos/time-gate-knights-chase Time Gate: Knight's Chase]


[[Category:Video Codecs]]
[[Category:Incomplete Video Codecs]]
[[Category:Game Formats]]
[[Category:Game Formats]]

Latest revision as of 07:27, 20 March 2021

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 it
  • 10 - long run, get nibble, if it's not zero then len = nibble + 4, otherwise len is next byte from control bits stream plus twenty. Get colour, repeat it len times
  • 110 - get colour, repeat it twice
  • 1110 - get colour, repeat it three times
  • 1111 - get colour, repeat it four times

Codes for inter:

  • 0 - get colour from colours stream, output it
  • 10 - long run, get nibble, if it's not zero then len = nibble + 4, otherwise len is next byte from control bits stream plus twenty. Get colour, repeat it len times
  • 110 - get colour, repeat it twice
  • 1110 - get colour, repeat it three times
  • 11110 - get colour, repeat it four times
  • 11111 - 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: