FVF is a format used for cutscenes in Star Trek: The Next Generation - "A Final Unity" game.
All data is little-endian. Data is grouped into frames that are grouped into blocks aligned to at least 2048 bytes. Audio is stored as unpacked PCM, video is compressed with its own method.
4 bytes - "FVF " 4 bytes - unknown 4 bytes - unknown 4 bytes - unknown 4 bytes - first block offset 4 bytes - last block offset 4 bytes - image header (should be 0x60) 4 bytes - audio header (usually 0xB5) 64 bytes - unknown
2 bytes - header size? (usually 40) 2 bytes - always 1? 2 bytes - always 16? 2 bytes - width 2 bytes - height 4 bytes - delay in milliseconds 4 bytes - unknown 4 bytes - number of frames 4 bytes - unknown 2 bytes - unknown 1 byte - palette something 1 byte - number of palette entries (usually 15) 4 bytes - palette offset (usually 0x88) 6 bytes - unknown
2 bytes - compression? (usually it's 1 and raw PCM) 2 bytes - number of channels? 2 bytes - bits per sample (usually 8) 2 bytes - sampling rate 8 bytes - unknown
2 bytes - header size (should be 16) 2 bytes - flags 4 bytes - previous block size 4 bytes - current block size 4 bytes - next block size
2 bytes - header size (should be 24) 4 bytes - full size 4 bytes - always 24? 4 bytes - video part size 4 bytes - audio part size 6 bytes - unknown
Video frame part
Video frame part starts with 32-bit size and two 16-bit fields (one of those is used to signal palette change, another one is for motion vector table size). Compression method seems to work by painting tiles using colour combinations generated from the palette colours. Bitstream is little-endian, low three bits signal tile opcode and it's aligned to the byte boundary before each next opcode:
- code 0 -- get 7-bit value, get 14-bit value, paint 4x4 tile using them;
- code 1 -- the same as above but tile is painted flipped horizontally;
- code 2 -- same as code 0 but tile is flipped vertically;
- code 3 -- same as above but tile is flipped horizontally as well;
- code 4 -- get 5-bit run value, copy the provided amount of 4x4 tiles from the previous frame (presumably);
- code 5 -- get 1-bit run flag and then 4-bit MV table index. Run flags means reading 8-bit run value and performing the operations that many additional times, zero flag means doing motion compensation on 4x4 tile just once (motion vector table is stored at the beginning of the frame);
- code 6 -- skip 5 bits (to byte align) and copy 16 bytes from the input to the tile data;
- code 7 -- this is large tile mode, the next 4 bits signal the operation:
- case 0 -- skip 1 bit, get 7-bit index, get 1-bit flag, get 14-bit index, paint 8x8 tile;
- cases 1-7 -- same but with various flipping modes;
- cases 8-11, 13-14 -- should not be present;
- case 12 -- special 4x4 tile copy run with long values;
- case 14 -- raw 2x2 tile.