Bink Video: Difference between revisions
(→1) |
|||
Line 88: | Line 88: | ||
=== 1 === | === 1 === | ||
Unlike other blocks, this seem to work with 16x16 block. It has a subcode for different real block types: | |||
0 - pattern fill | 0 - pattern fill (like block type 3) | ||
2 - "lossless" | 2 - "lossless" IDCT )looks like scaled 8x8 IDCT though) | ||
3 - fill | 3 - fill | ||
5 - masked fill | 5 - masked fill (like block type 8) | ||
6 - raw coded 8x8 block scaled twice | |||
=== 2 === | === 2 === |
Revision as of 07:00, 29 June 2009
- FourCC: BINK (note that some FourCC lists assert that BINK is a FourCC for general-purpose multimedia containers; however, Bink data is always known to be encapsulated in a custom container format)
- Company: RAD Game Tools
- Samples: http://samples.mplayerhq.hu/game-formats/bink/, countless video games
Bink is a video codec that purports to use every video coding technique (DCT, FFT, Wavelet Coding, Vector Quantization, Motion Compensation) under the sun and used in a large number of computer and console games. The video is packaged in custom Bink files.
Each plane is coded separately. The Y plane is always coded first in each frame.
Format
Bitstream is read LSB from 32-bit little-endian words.
Frame is coded as three planes.
Each plane starts with Huffman codebooks: two 4-bit ones, one 8-bit (which really consists of seventeen (16 plus one special) 4-bit codebooks) and four 4-bit ones.
Huffman trees
There are 16 predefined Huffman trees, Bink frame only stores tree number and sophisticated coding of leaves values.
- 4 bits - huffman tree type.
First tree is actually raw nibbles, so no additional data for it. For other trees leaves symbols should be coded.
- 1 bits - symbols are coded explicitly (by selection)
If that flag is one, read 3 additional bits which determine number of symbols out of order, then read those symbols (4 bits per each symbol), the rest of symbols should go in normal order.
Example: read {5} [1] (3) <9> <1> <7> tree type: 5 symbols order: 9 1 7 0 2 3 4 5 6 8 A B C D E F
In other case symbols are coded by shuffling:
- 2 bits - shuffle depth
First divide all symbols into pairs and read 1 bit for each pair to decide whether swap this pair or not.
Example: original data: (0 1) (2 3) (4 5) (6 7) ... read bits: 0 1 1 0 ... output: (0 1) (3 2) (5 4) (6 7) ...
if shuffle depth is zero, end operation; otherwise perform merging.
void merge(uint8_t *dst, uint8_t *src1, uint8_t *src2, int size) { int size1 = size, size2 = size; do{ if(getbit()){ *dst++ = *src2++; size2--; }else{ *dst++ = *src1++; size1--; } }while(size1 && size2); while(size1--) *dst++ = *src1++; while(size2--) *dst++ = *src2++; }
If depth is one, divide symbols into pairs and merge neighbouring pairs (i.e. [0 1] and [2 3], [4 5] and [6 7], etc.) If depth is two, divide result into quartets and merge quartet 0 with quartet 1 and quartet 2 with quartet 3. For depth = 3 additionally divide result into two halves and merge them too.
Or, more clearly:
depth = getbits(2); for (i = 0; i <= depth; i++) { int size = 1 << i; int skip = size * 2; for (j = 0; j < 16; j += skip) merge(tmp + j, symbols + j, symbols + j + size, size); memcpy(symbols, tmp, 16); }
Bundle reading
8-bit values are decoded with bundles. Bundle consists of 17 Huffman trees - one to decode upper 4 bits and 16 trees that are used to decode lower 4 bits. Those lower 4 bits are used as tree number to decode next low nibble.
Decoding
Block types
NOTE: This section is incomplete
0
Copy 8x8 block from previous frame to current frame
1
Unlike other blocks, this seem to work with 16x16 block. It has a subcode for different real block types:
0 - pattern fill (like block type 3) 2 - "lossless" IDCT )looks like scaled 8x8 IDCT though) 3 - fill 5 - masked fill (like block type 8) 6 - raw coded 8x8 block scaled twice
2
Copy 8x8 block from previous frame with some offset (previous motion vector?)
3
Fill 8x8 block with pattern 4 bits - pattern index 63 bits - pattern
4
"lossy"-coded DCT coefficients with motion vector
5
"losslessly"-coded DCT coefficients and 4 bits quantizer
6
Fill 8x8 block with one byte
7
"losslessly"-coded DCT coefficients and 4 bits quantizer and "motion"(in DCT code)
8
Fill block using masks
9
Copy 8x8 block from some other frame?