Electronic Arts MAD
- Extension: mad
- Company: Electronic Arts
- Samples: http://samples.mplayerhq.hu/game-formats/ea-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".
Chunk Types
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 Decoding
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 & (1<<i) mc_offset = GetVector() motion_compensation else decode_coeffs
Full-pel 8x8 block motion compensation is performed using the motion vector. Following the compensation step, each pixel in the block is offset by the mc_offset value and clipped to 0, 255.
GetVector Definition
Vector values are read from the bitstream using the following algorithm.
value = 0 if (get_bits(1)) if (get_bits(1)) value = -17 value += get_bits(4) + 1
Coefficient Decoding
All coefficients, including DC, are decoded using the MPEG-1 AC run-length VLC technique. The RLVLC table is identical to that used for the TGQ codec and coefficients are ordered using the EA zigzag scan pattern. Dequantization is performed by multiplying the coefficients by a dequantization table. This table is calculated for each frame using the frame quantizer.
dequant_table[0] = base_table[0] * base_table2[0] for i equals 0 through 63 dequant_table[i] = (base_table[i]*base_table2[i]*frame_quant + 4) / 8 where base_table and base_table2 are defined in TGQ and TQI respectively.
Inverse DCT and Clipping
An IDCT-based algorithm is applied to each block. <FIXME: hyperlink to implementation>. The resulting values are offset by 128, and clipped to 0, 255 to give 8-bit luma and chroma pixel levels.
Games Using MAD
See Electronic Arts Formats for listing.