Electronic Arts TGQ

From MultimediaWiki
Jump to navigation Jump to search

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 equates to a signed DC coefficient that is applied to all blocks within the macroblock. All AC coefficients are assumed to be zero.

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.