Escape 130

From MultimediaWiki
Jump to: navigation, search

Surprisingly, unlike previous ESCAPE codecs, Escape 130 was completely redesigned. Now it operates in mixed YUV/RGB colorpace and employs simple differential coding. In short, the source RGB image broken into 2x2 blocks. The average value of each pixel quad is interpolated, converted to YUV colorspace and stored together with quantized neighboring pixel differences. The decoder, operating in reverse, unpacks interpolated pixel values, convert them to RGB colorspace, then requantizes 4 pixels using supplied or pre-defined coefficient set. Compression works well for full-motion video, but static images experience visible blocking.

The following is a spec for the Escape 130 codec; this is accurate as far as I know, but it is possible there are errors.

Container

All known video clips using the Escape 130 video codec are contained in the ARMovie/RPL container format. ARMovie is a general video/sound container; the only feature worth mentioning here is that the video and audio are contained in pairs of opaque chunks of arbitrary size. All known Escape 130 clips have only one video frame per chunk, though, which means the demuxer doesn't have to parse the video frame headers.

Note that functionally, this format is mostly unrelated to the Escape 122 and Escape 124 codecs; the only real similarity is the skip code, block code organization of the blocks.

The audio alongside Escape 130 samples is either 16-bit signed linear PCM, or an IMA ADPCM variant.

See the ARMovie page for a list of games using this codec.

Bit order

All numbers in this format are little-endian; this format is bit-oriented, and the bitstream is parsed in little-endian order. Multi-bit quantities are stored smallest bit first.

Header

The header is 16 bytes long; decoding doesn't require any information from this header.

The first two bytes are always 0x0130. The second two bytes are 0x0001 for most frames and 0x8001 for keyframes (i.e. frames not dependent on the previous frame). The only way that a keyframe is different from a normal frame is that the only legal skip code in a keyframe is the code with the value zero. Most clips are not seekable anyway due to the audio using an ADPCM format without any keyframes (XXX is it really unseekable?). The next 4 bytes contain the size of the video frame, which is the same as the chunk size in the index of the container. The next 8 bytes are always zero.

Colorspace and Organization

Each frame is conceptually a series of 2x2 blocks of pixels, encoded from left to right, top to bottom. The colors are encoded in the file using a YCbCr colorspace. Y samples use 6 bits, Cb and Cr samples use 5 bits. There is always one Cb and one Cr sample per 2x2 block of pixels. There is always one base Y sample for any given block, plus there can be a adjustment pattern on top of the base sample, which provides more resolution.

XXXFIXME: The information I have indicates that for blocks without an adjustment pattern, there is a special pattern applied after conversion to 8-bit RGB: (top left) green+6, (top right) red+6 blue+6, (bottom left) red+4 blue+4 green+2, (bottom right) red+2 blue+2 green+4. However, I have no idea what the purpose is; possibly to reduce blockiness? That said, I think this adjustment is too small to be visible.

XXXFIXME: Is there more than one potential colorspace? Some information I have indicates that there is a flag in bit 17 of the header that allows selecting an alternate colorspace, but I don't know of any samples.

Encoding

Each frame is enocoded as a series of skip codes and block codes. A frame consists of a skip code, then a block code, then a skip code, etc. A frame ends when every block in the frame has been either explicitly encoded or skipped.

A skip code is a number, encoded with a variable length encoding. It indicates some number of blocks to copy over from the previous frame. The blocks are "skipped" from left to right, top to bottom, starting with the block after the last block explicitly encoded (starting with the block in the top left for the first skip code).

A block code explicitly encodes the color of a block. Most blocks are dependent in some way on the previous block; the "previous block" is the block in the current frame processed immediately before the current block. Visually, the previous block is the block to the immediate right of the current block. Note that the previous block may have been copied from the previous frame by a skip code. (XXXWhat about the block in the top left?)

A block code consists of two parts: the first part encodes the Y value(s), and the second part encodes the Cb and Cr values.

There are four formats for the Y value(s): one encodes a base value for the block plus an intensity pattern for the individual pixels, one just encodes a base value, one encodes a difference from the previous block's base value, and one is just an indicator to use the previous block's base value.

There are three formats for the Cb and Cr values: one encodes the values for the block, one encodes an adjustment from the previous block's values, and one is just an indicator to use the previous block's values.

Encoding details

Skip codes

Binary Value
000000000000XXXXXXXXXXXXXXX
(12 zero bits followed by 15 data bits)
X + 262
0000XXXXXXXX
(4 zero bits followed by 8 data bits)
X + 7
0XXX
(1 zero bit followed by 3 data bits)
X
1
(1 one bit)
0

Block code, Y part

1SSSSSSDDBBBBB
B is half of the base value, D is the code for the strength of the pattern, and S is the code for the pattern.

011BBBBBB
B is the base value

010AAA
A is the code for the adjustment from the previous block's values

00
Indicator to use the values from the previous block

Block code, Cb/Cr part

11BBBBBRRRRR
B is the Cb value, R is the Cr value

10AAA
A is the code for the adjustment from the previous block's values

0
Indicator to use the values from the previous block

Table for Y adjustment codes

Code Adjustment
(relative to 6-bit sample)
000 -4
001 -3
010 -2
011 -1
100 1
101 2
110 3
111 4

Table for Cb/Cr adjustment codes

Code Cb Adjustment
(relative to 5-bit sample)
Cr Adjustment
(relative to 5-bit sample)
000 1 0
001 1 1
010 0 1
011 -1 1
100 -1 0
101 -1 -1
110 0 -1
111 1 -1

Tables for intensity-pattern encoding

The formula for the luma of each pixel is BaseValue + PatternStrength * PatternValue, where PatternStrength and PatternValue are from the following two tables.

Pattern strength codes (adjustments strengths relative to 6-bit sample):
Code Strength
00 2
01 4
10 10
11 20
Pattern codes

This table can be dynamically generated; the way this table is generated is just using a pattern of 0, 1, then -1, for the pixels from the top left to the bottom right, with the restrictions that any code with the bottom 4 bits zero is zero, and any potential row without both a 1 and a -1 is skipped. This algorithm will leave the bottom ten cells untouched.

Code Top left Top right Bottom left Bottom right
000000 0 0 0 0
000001 -1 1 0 0
000010 1 -1 0 0
000011 -1 0 1 0
000100 -1 1 1 0
000101 0 -1 1 0
000110 1 -1 1 0
000111 -1 -1 1 0
001000 1 0 -1 0
001001 0 1 -1 0
001010 1 1 -1 0
001011 -1 1 -1 0
001100 1 -1 -1 0
001101 -1 0 0 1
001110 -1 1 0 1
001111 0 -1 0 1
010000 0 0 0 0
010001 1 -1 0 1
010010 -1 -1 0 1
010011 -1 0 1 1
010100 -1 1 1 1
010101 0 -1 1 1
010110 1 -1 1 1
010111 -1 -1 1 1
011000 0 0 -1 1
011001 1 0 -1 1
011010 -1 0 -1 1
011011 0 1 -1 1
011100 1 1 -1 1
011101 -1 1 -1 1
011110 0 -1 -1 1
011111 1 -1 -1 1
100000 0 0 0 0
100001 -1 -1 -1 1
100010 1 0 0 -1
100011 0 1 0 -1
100100 1 1 0 -1
100101 -1 1 0 -1
100110 1 -1 0 -1
100111 0 0 1 -1
101000 1 0 1 -1
101001 -1 0 1 -1
101010 0 1 1 -1
101011 1 1 1 -1
101100 -1 1 1 -1
101101 0 -1 1 -1
101110 1 -1 1 -1
101111 -1 -1 1 -1
110000 0 0 0 0
110001 1 0 -1 -1
110010 0 1 -1 -1
110011 1 1 -1 -1
110100 -1 1 -1 -1
110101 1 -1 -1 -1
110110 0 0 0 0
110111 0 0 0 0
111000 0 0 0 0
111001 0 0 0 0
111010 0 0 0 0
111011 0 0 0 0
111100 0 0 0 0
111101 0 0 0 0
111110 0 0 0 0
111111 0 0 0 0