Expression Encoder Screen Capture Codec
- Company: Microsoft
- FourCC: MTS2
- Other names: Titanium Screen Codec 2
- Binary Codec: http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=71895f93-d804-4b70-8440-6b726ea0f12c
- Encoder 2.0: http://download.microsoft.com/download/4/7/B/47B6E0F3-EF66-4A38-AA36-3C6ECF690F36/Media_en.msi
- Encoder 2.0: http://download.microsoft.com/download/5/0/d/50da7510-3c8c-4ebf-8d83-d8c8e403da0b/Encoder_Trial_en.exe
- Samples: http://samples.mplayerhq.hu/V-codecs/MTS2/
This is fast codec used primarily as an intermediate between screen capture and encoding for delivery with Microsoft Expression Encoder. It was originally part of MSR's "Project Titanium". It is most commonly seen in ASF files with the .xesc extension.
Frame format
Every frame seems to start with this header (all numbers are big-endian):
0-1 width 2-3 height 4 2 - intra, 3 - inter) 5 should be always zero 6 should be in range 0-100 7 should be in range 0-2, maybe frame type too? (0 - intra, 1 - inter and 2 - skip frames)
Frame consists of macroblocks in YUV 4:2:0 format. Static VLCs are employed for coding block data.
for (mb_y = 0; mb_y < mb_width; mb_y++) { for (mb_x = 0; mb_x < mb_height; mb_x++) { mb_type = get_vlc(); if (mb_type == 2) decode_dct_mb(); else if (mb_type == 1) decode_vq_mb(); } }
Block type VLC:
0 - 0 (skip) 10 - 2 (DCT) 11 - 1 VQ)
Decoding long coefficients
val = get_vlc(); if (val > 0) { len = val; val = get_bits(len); if (val < (1 << (len - 1))) val -= (1 << len) - 1; }
DCT coding
In general DCT coding is the same as in MS ATC Screen codec except for bitstream format.
DC coefficient is coded as long coefficient with prediction from its neighbours.
AC coefficients use codebook with entries like (skip << 4) | coef_len
.
coef_len = 0
means end of block.
Decoding AC is similar to decoding long coefficient:
val = get_bits(coef_len); if (val < (1 << (coef_len - 1))) val -= (1 << coef_len) - 1;
There are four VLCs — for luma and chroma blocks DC and for luma and chroma block coded AC information.
VQ coding
Decoding macroblock properties:
vec_len[0] = get_vlc(luma_block_vlc); // in 1-4 range for (i = 0; i < vec_len[0]; i++) vec[0][i] = get_long_coef(luma_entry_vlc); vec_len[1] = get_vlc(chroma_block_vlc); // in 1-4 range for (i = 0; i < vec_len[1]; i++) vec[1][i] = get_long_coef(chroma_entry_vlc); vec_len[2] = get_vlc(chroma_block_vlc); // in 1-4 range for (i = 0; i < vec_len[2]; i++) vec[2][i] = get_long_coef(chroma_entry_vlc); for (i = 0; i < 3; i++) { flags[i] = vec_len[i] > 0; blens[i] = vec_len[i] > 2 ? vec_len[i] - 2 : 0; }
Decoding macroblock coefficients:
TODO