Origin Flic Codec

From MultimediaWiki
Jump to navigation Jump to search

Please rename this codec name to something more original

Origin Flic Codec is a relatively simple palettized video codec used in PC version of Crusader: No Remorse game. Data is packaged inside standard AVI container and employs relatively simple RLE compression. Audio stored in uncompressed PCM form. It is rumored that codec's FourCCs are actually based on game developer's names (The Crusader: No Regret credits include a line "Special thanks for the video system and its integration: Jason Yenawine", who also receives a generic thanks in No Remorse. Another developer credited in No Remorse is Ramon Renteria)

Video Codec

A video movie uses fixed palette, stored in corresponding AVI Stream Format chunk.

Video frame is encoded in a series of slices, where each slice encodes a number of horizontal lines of picture. Number of slices depends on FourCC and is:

  • JYV1, RRV1 - 5 slices
  • RRV2 - 15 slices

Therefore, each slice contains VideoHeight/slices raster lines.

Frame chunk consist of the following parts:

u32 slicetable[num_slices]
-- for each slice --
u32 codes_size;
u8 codes[codes_size]
u8 raster[]
--------------------

where each entry of slicetable points to corresponding codes/raster block (offsets are relative to beginning of the chunk.)

Video decompression is performed as follows (for each slice):

flipflop = flip
while slice is not complete
 idx = GetBits(4);
 blocksize = BaseLength[idx];
 if idx != 0 and idx != 8
   blocksize += GetBits(FineLengthBits[idx]);
 if flipflop == flip
   leave blocksize pixels unchanged
 else
   draw blocksize pixels from raster[]
 flip flop
 BaseLength[]     = {0, 1<<7, 1<<3, 0, 1<<1,  0, 1<<5, 0,
                     1, 1<<8, 1<<4, 0, 1<<2,  0, 1<<6, 0};
 FineLengthBits[] = {0,    7,    3, 0,    1, 16,    5, 0,
                     1,    8,    4, 0,    2, 24,    6, 0};

GetBits() reads variable number of bits from codes[], highest bits of lowest byte first. For RRV* FourCCs 'leave' and 'draw' command skips/doubles each pixel when decoding a keyframe (i.e. a keyframe should be upscaled horizontally.)