Origin Xan Codec

From MultimediaWiki
Jump to navigation Jump to search

The Xan codec is a codec used in various multimedia-heavy titles from early in the FMV-era of PC computer games. The video was packaged in AVI files along with a custom DPCM audio codec.

While not all of the details have been reverse engineered, the Xan codec is known to use the same byte unpacking algorithm as used in the custom video codec developed for Wing Commander III. Further, it uses Huffman coding and bit packing, though using a slightly different algorithm than its predecessor codec, and it appears to have been designed to easily accommodate a number of video output and scaling modes.

Trivia: All Xan-encoded AVI files contain very interesting comment string inside. 'Xxan video stream, Blue Mu Productions.' What could possible that Blue Mu be? A subdivision of Origin or real codec authors?

Format

This codec is similar to Wing Commander III MVE Video Codec and employs the same packing algorithm. The main difference is that this codec stores information in YUV colorspace (6 bits for Y component, 5 bits for U and V components).

Frame format:

 header:
  bytes  0-3  - frame type
  bytes  4-7  - offset to chroma data
  bytes  8-11 - offset to some luma differences?
  bytes 12-? - luma Huffman-coded data for frame type 0
 or
  bytes 12-15 - offset to some chroma differences?
  bytes 16-? - luma Huffman-coded data for frame type 1
 chroma data:
  bytes 0-1 - chroma data is YUV420 or YUV410
  bytes 2-3 - offset to Huffman-coded chroma indexes
  bytes 4-? - possible chroma values

Luma reconstruction for frame type 0

Reconstruction of the first line:

   byte_l = *unpacked++;
   byte_h = byte_l;
   byte_l *= 2;
   *out++ = byte_l;
   width_counter = (width - 2) / 2;
   
   while (width_counter--) {
       byte_l = byte_h;
       byte_h += *unpacked++;
       byte_h &= 0x1F;
       byte_l += byte_h;
       *out++ = byte_l;
       byte_l = byte_h;
       byte_l *= 2;
       *out++ = byte_l;
   }
   *out++ = byte_l;

Reconstruction of the rest of the lines:

   while (height_counter--) {
       byte_l = out[-width];
       byte_l /= 2;
       byte_l += *unpacked++;
       byte_l &= 0x1F;
       byte_h = byte_l;
       byte_h *= 2;
       *out++ = byte_h;
       byte_h = byte_l;
       mod_width = (-width + 2) >> 1;
      
       while (mod_width < 0) {
           byte_l = out[-width + 1];
           byte_l /= 2;
           byte_l += *unpacked++;
           byte_l &= 0x1F;
           byte_h += byte_l;
           *out++ = byte_h;
           byte_h = byte_l;
           byte_l *= 2;
           *out++ = byte_l;
           mod_width++;
       }
       *out++ = byte_l;
   }

Games Using Xan Video