Electronic Arts MAD
MAD is a video codec used in various games published by companies under the Electronic Arts umbrella. The codec is an evolution of the earlier TGQ and TQI codecs, adding motion compensation and low-quality frame concepts. MAD is an abbreviation for "Madcow Movie".
See Electronic Arts Formats for file format description. Each MADk, MADm and MADe chunk corresponds to a video frame, where MADk is an intra-frame, MADm is an inter-frame and MADe is a low-quality-inter frame. Low-quality-inter frames are identical to inter frames, but are not used for motion compensation and are discarded immediately after presentation. Each frame is divided into 16x16 pixel macroblocks, with each macroblock further divided into with four 8x8 luma and two half-resolution 8x8 chroma blocks. Standard MPEG-1 block ordering is used.
Each chunk begins with a 16 byte header, followed by a bitstream. Symbols within the header are encoded using 16-bit little-endian most-to-least-significant bit packing. <FIXME: explain bit packing>. Although frame type is reported within the header, the field is not valid in some samples, and is therefore unreliable. Frame type should be inferred from the chunk type.
Offset Data_type Name Description 0x0000 four bytes unknown always zero 0x0000 le_u16 unknown 0x0006 le_u16 frame_rate milliseconds per frame 0x0008 le_u16 width image width (pixels) 0x000a le_u16 height image height (pixels) 0x000c u8 unknown 0x000d u8 quantizer frame quantizer 0x000e u8 frame_type not valid for all samples 0x000f u8 unknown for each vertical macroblock for each horizontal macroblock decode_mb
Macroblock composition is based on a 6-bit block type, where each bit indicates the type of an 8x8 block within macroblock. The least-significant-bit corresponds to the first block. A clear bit indicates an intra-block, and a set bit indicates a motion-compensated block.
For intra frames, the block type is assumed to be all clear. For inter and low-quality inter frames, the block type is derived from a VLC. If the block type is none zero, then a full-pel motion vector is read from the bitstream. A description of the block_type VLC and decoding algorithm is provided below.
if (intra frame) block_type = 000000b else // inter or low-quality-inter frame switch get_vlc() case 1b : block_type = 111111b case 01b : block_type = get_bits(6); case 00b : block_type = 000000b if (block_type != 0) x = GetVector(); y = GetVector(); for i = 0 through 5 // for each block if block_type