Electronic Arts TGQ
- Extension: tgq, uv
- Company: Electronic Arts
- Samples: http://samples.mplayerhq.hu/game-formats/ea-tgq-uv/
TGQ is a video codec seen on some Electronic Arts games for the Sega Saturn and PC. It was the first in a series of MPEG-like codecs used by EA.
Chunk Types
The codec payload has been observed in the TGQs and pQGT chunk types. See Electronic Arts Formats for file format description. The ordering of multibyte values varies, but is optimised for the target platform.
Frame Description
Each chunk represents one video frame, and frame rate is fixed to 15fps. 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 4:2:0 block ordering is used.
Y Cb Cr [ 0 | 1 ] [ ] [ ] ----+---- | 4 | | 5 | [ 2 | 3 ] [ ] [ ]
The frame begins with an eight byte header, indicating image dimensions and the frame quantizer, and is followed by macroblock coefficient data.
Offset Data_type Name Description 0x0000 u16 width image width (pixels) 0x0002 u16 height image height (pixels) 0x0004 u8 quantizer frame quantizer 0x0005 3 x u8 unknown always zero
for each vertical macroblock for each horizontal macroblock u8 N macroblock data length (N bytes) N x u8 data macroblock data
The macroblock data length value determines how the data is to be interpretted.
When length is 1, the data byte is a motion vector where the high nibble is mv_x and low nibble is mv_y. Motion vector are expressed in luma pixels.
When length is 3, each datga byte equates to a signed DC coefficient. The first coefficient is applied to all luma blocks. The second and third coefficients are applied to each chroma block. All AC coefficients are assumed to be zero.
When length is 6, each data byte equates to a signed DC coefficient for each block (IAW block ordering rules). All AC coefficients are assumed to be zero.
When length is 12, each *even* data byte equates to a signed AC coefficient for each block. The purpose of the odd data bytes is unknown. All DC coefficients are assumed to be zero.
Length>12 Coefficient Decoding
When length is greater than 12, the macroblock data bytes refers to a bitstream containing coefficients for each block. Symbols within the bitstream are encoded using little-endian least-to-most-significant bit packing. <FIXME: explain bit packing>. Coefficients are decoded using a run-length VLC algorithm, and ordered using a zigzag scan pattern.
for each block dc_level = show_bits(8) i = 1 while i<64 switch get_vlc() 11b: value = get_sbits(6) if value == 111111b ac_coeff = get_sbits(8) else ac_coeff = value 010b: coeff = 1 110b: coeff = -1 000b: zero run of 1 (that is, coeff = 0) 101b: zero run of 2 001b: zero run of 2*get_bits(5) 101b: zero run of 2*get_bits(5) + 1
Dequantization is peformed by multipling the coeffs by a dequantization table. This table is calculated for each frame using the frame quantizer.
Q = 100 – frame_quant A = 0.28*frame_quant + 2 B = 0.22*frame_quant + 8 for j equals 0 through 7 for i equals 0 through 7 dequant_table[j][i] = (A*(j+i)/(7+7) + B) * base_table[j][i] where, base_table[8][8] = { 8192, 5906, 6270, 6967, 8192, 10426, 15137, 29692, 5906, 4258, 4520, 5023, 5906, 7517, 10913, 21407, 6270, 4520, 4799, 5332, 6270, 7980, 11585, 22725, 6967, 5023, 5332, 5925, 6967, 8867, 12873, 25251, 8192, 5906, 6270, 6967, 8192, 10426, 15137, 29692, 10426, 7517, 7980, 8867, 10426, 13270, 19266, 37791, 15137, 10913, 11585, 12873, 15137, 19266, 27969, 54864, 29692, 21407, 22725, 25251, 29692, 37791, 54864, 107619, }
Inverse DCT and Clipping
An IDCT-based alogirithm is applied to each block. An implementation of this algorithm can be found in FFmpeg (http://svn.mplayerhq.hu/ffmpeg/trunk/libavcodec/eaidct.c). The resulting values are offset by 128, and clipped to 0, 255 to give 8-bit luma and chroma pixel levels.
Games Using TGQ
See Electronic Arts Formats for full listing.