Archive for the ‘TrueMotion’ Category

TM2: Almost Complete

Tuesday, October 4th, 2005

My TrueMotion 2 decoder is almost complete. It just has some problems with chroma decoding in intraframes. I suspect this is because of some rounding errors and such. Original TM2 decoder used to store chroma in pairs – one 4 double word for 16-bit Cr and Cb and all calculations were done on those pairs.

For now, I’ll leave this decoder for some time and will post pieces of information about other codecs.

TM2 Format Part 2: Blocks

Friday, September 9th, 2005

TM2 frame is divided into blocks 4×4 and YUV420 colorspace is used, so for each 4×4 blocks of luminance there is two 2×2 blocks of chroma.
There are 7 types of blocks:

  • Hi-res block (hi-res luma and chroma)
  • Med-res block (hi-res luma and low-res chroma)
  • Low res block (low-res chroma and luma)
  • Null-res block (nothing changes from previous block)
  • Still block (just copied from previous frame)
  • Update block (copied from the same place in previous frame and then modified)
  • Motion block

Every intraframe block (first four types in the list) uses such logic:

| | | |
D0 -> +d00 +d10 +d20 +d30 -> D0
D1 -> +d01 +d11 +d21 +d31 -> D1
D2 -> +d02 +d12 +d22 +d32 -> D2
D3 -> +d03 +d13 +d23 +d33 -> D2
| | | |

It means that every block use last 4 pixels from top block as reference and deltas D (differences between right pixel in this line and previous line) from left neighbour.
In case of low-res chroma or luma last elements and deltas are modified before processing, they are replaced with their average values.
For interframe blocks there is one additional operation – to calculate new deltas and last values from block data after opying is done.

TM2 Format Part 1: Global Structure

Thursday, September 8th, 2005

TM2 differs from many modern and not modern codecs in aspect it uses different streams for different type of data – look at the scheme below:

[Global Header]
[Stream 0 - High-res chroma values]
[Stream 1 - Low-res chroma values]
[Stream 2 - High-res luminance values]
[Stream 3 - Low-res luminance values]
[Stream 4 - Update deltas values]
[Stream 5 - Motion vectors]
[Stream 6 - Block types]

Global header can be one of two types: old header type – all values are stored in 4-byte or 2-byte integers and new header type – header fields are stored in bitstream (9 bits for width and the same for height, 31 bits for flags, etc.).
One thing worth to mention – a mixture of big- and little-endian 4-byte integers in header values and use big-endian dwords in bitstream output.

Streams are huffman-coded array of values (called ‘tokens’) and consist of header, non-compulsory delta table (in this case tokens are just indices in that table), compressed Huffman tree and compressed tokens. Stream also can be empty (in case of intra-frames – that streams 4 and 5).

Decoder must decompress all these streams into memory and read tokens from one or another stream. Decoding process will be described in Part 2.

Duck TrueMotion 2

Thursday, September 8th, 2005

Duck Corp. (now On2) released GPLed source of their solution VPVision (capturing software for Windows), and it contains sources of their two codecs – TrueMotion 1 and TrueMotion 2 (predecessors of VP3-7 family).
TrueMotion 1 decoder is already present in FFmpeg, now it’s time to add TrueMotion 2.
The bad thing is that codec source code is poorly-documented and optimised for performance (optimisation is a form of obfuscation and vice-versa – look at The International Obfuscated C Code Contest for examples).