Duck TrueMotion 2 Realtime
- FOURCCs: TR20
- Company: On2 (formerly Duck)
Duck TrueMotion 2 Realtime relies on differential coding of samples in a YUV colorspace. There's no interframe coding or Huffman codes for speed considerations.
Internally frame is coded as YUV410:
R = Y + Cr * 1.370705 G = Y + Cr * -0.698 + Cb * -0.337633 B = Y + Cb * 1.732446
Header
Frame header is obfuscated --- frame size if obtained from the first byte by cyclically rotating it right and masking size = rcr(src[0], 5) & 0x7F;
Header data is expected to be at least 8 bytes.
byte 0 --- (meaningless) byte 1 --- should be 0x11 byte 2 --- delta mode byte 3 --- should be 0x05 byte 4 --- horizontal flag (should be either0x00
- no scaling or0x01
- 2x scale) byte 5 --- unused bytes 6-7 --- frame height bytes 8-9 --- frame width
Delta mode selects which delta table will be used by signalling number of bits it uses (only 2-, 3- and 4-bit delta tables are known). Data should be treated as 32-bit little endian words and should be read LSB first.
Right after the header and 4-byte packed data size compressed data for Y, U and V plane follows.
Each plane is coded as the cumulative difference from the top neighbour (i.e. you update delta value for the line and add it to the top neighbour value), delta value is kept internally but is clipped on output.
Luma plane
for (y = 0; y < height; y++) { diff = 0; for (x = 0; x < width; x++) { // or maybe width / 2 when scaling flag is 1 diff += delta_tab[delta_mode][get_bits(delta_size)]; dst[x + y * stride] = clip_uint8((y ? dst[x + (y - 1) * stride] : 0) + diff); } }
Chroma planes
for (y = 0; y < height / 4; y++) { diff = 0; for (x = 0; x < width / 4; x++) { diff += delta_tab[delta_mode][get_bits(delta_size)]; dst[x + y * stride] = clip_uint8((y ? dst[x + (y - 1) * stride] : 0x80) + diff); } }
Delta tables
4-bit:
1, -1, 2, -3, 8, -8, 0x12, -0x12, 0x24, -0x24, 0x36, -0x36, 0x60, -0x60, 0x90, -0x90
3-bit:
2, -3, 8, -8, 0x12, -0x12, 0x24, -0x24
2-bit:
5, -7, 0x24, -0x24