Vividas VIV
- Extension: viv
- MIME type: video/vividas
- Company: Vividas Pty Ltd
- Samples: TBD
Overview
A Vividas file consists of one or more "tracks", each comprising one or more audio and/or video elementary streams.
Encryption
All data relating to a track is encoded using a 32-bit key given in obfuscated form in the file header.
Keys
The header contains, for each track, a 187-byte block, 32 bits of which form the key. The following C function will extract a key from such a block.
const unsigned short keybits[32] = { 163, 416, 893, 82, 223, 572, 1137, 430, 659, 1104, 13, 626, 695, 972, 1465, 686, 843, 1216, 317, 1122, 1383, 92, 513, 1158, 1243, 48, 573, 1306, 1495, 396, 1009, 350, }; uint32_t decode_key(uint8_t *buf) { uint32_t key = 0; int i; for (i = 0; i < 32; i++) { unsigned p = keybits[i]; key |= !!(buf[p>>3] & (1<<(p&7))) << i; } return key; }
Decoding
To decode a data block with a given key, this C function can be used:
void decode(uint32_t *d, unsigned size, uint32_t key) { uint32_t k = key; size >>= 2; while (size--) { *d++ ^= k; k += key; } }
File Format
Data Types
The following data types are used in the syntax description below.
- u(n)
- n-byte unsigned little endian integer.
- v
- Variable-length integer, the 7 low bits of each byte being data bits, and the MSB indicating whether more bytes follow.
- a(n)
- n-byte ASCII string.
- z
- NUL-terminated ASCII string.
- d(n)
- n bytes unspecified data.
- 'x'
- Literal byte with hex value
x
. - "s"
- Literal ASCII string.
Overall Structure
vividas_file() { signature a(7) version a(2) file_header() if (skin_size > 0) { skin() } for (i = 0; i < num_tracks; i++) { reset_key() track_header() track_index() } for (;;) { reset_key() sb_block() } }
- signature
- The string
vividas
. - version
- File version as two decimal digits. All known samples have the value
03
. - file_header()
- Sets
skin_size
andnum_tracks
. - reset_key()
- The decoding key is reset to the value from the file_header.
File Header
file_header() { header_length v num_tracks u(1) for (i = 0; i < num_tracks; i++) { title_length u(1) track_title a(title_length) track_key d(187) track_header_length d(4) } for (;;) { block_length v block_type u(1) if (block_type == 15) { key d(187) for (;;) { descriptor() } } else if (block_type == 22) { skin_key d(187) skin_size d(4) } } }
- header_length
- Total length of the
file_header
element in bytes. - num_tracks
- Number of tracks in the file.
- title_length
- Number of bytes in the immediately following title.
- track_title
- Title of track
i
. - track_key
- Scrambled key for track
i
. - track_header_length
- Total size in bytes of track_header and track_index for track
i
. - block_length
- Size in bytes of the following block, including this field.
Skin
skin() { length v 'd' u(1) for (;;) { size v tag u(1) data d(size) } }
- length
- Total size of skin data including length field.
- size
- Size of data chunk.
- tag
- Unique identifier for data chunk.
- data
- XML or JPEG data.
Track Header
track_header() { track_header_length v '1' u(1) val_1 u(1) for (i = 0; i < val_1; i++) { val_2 u(1) for (j = 0; j < val_2; j++) { val_3 u(1) val_4 u(1) } } num_streams u(1) size_1 v '2' u(1) num_video u(1) def_video u(1) for (i = 0; i < num_video; i++) { length v '3' u(1) val_7 u(1) frame_rate_den u(4) frame_rate_num u(4) num_frames u(4) width u(2) height u(2) val_8 u(1) val_9 u(4) } size_2 v '4' u(1) num_audio u(1) def_audio u(1) for (i = 0; i < num_audio; i++) { length v '5' u(1) codec_id u(1) codec_subid u(2) channels u(2) sample_rate u(4) data_1 d(10) len_2 u(1) data_2 d(len_2) junk d(1) val_13 v '19' u(1) len_3 v num_data u(1) for (i = 0; i < num_data; i++) { data_len[i] v } for (i = 0; i < num_data; i++) { data d(data_len[i]) } } }
- track_header_length
- Length in bytes of track header including this field. Matches element of same name in file_header.
- num_streams
- Number of elementary streams in track.
- size_1
- Number of bytes preceding video streams loop, including this field.
- num_video
- Number of video streams.
- def_video_stream
- Default video stream number.
- size_2
- Number of bytes preceding audio streams loop, including this field.
- num_audio
- Number of audio streams.
- def_audio_stream
- Default audio stream number.
Track Index
track_index() { length v 'c' u(1) num_sb_blocks v for (i = 0; i < count; i++) { size v num_chunks v } }
- length
- Length in bytes of track index.
- num_sb_blocks
- Number of entries in following table.
- size
- Size of a block.
- num_chunks
- Number of chunks in block.
"SB" Block
sb_block() { "SB" a(2) size v junk d(1) start_chunk v do { chunk_size v flag u(1) } while (chunk_size != 0) }
- size
- Total size of this block.
The chunks for which flag
is 1 have the following structure:
chunk_1() { length v unknown_1 d(length) unknown_2 unknown do { offset v unknown_3 v } while (offset != 0) }
- offset
- offset from end of table to start of elementary stream packet
Tools
A decrypter and parser is available from git://git.mansr.com/vividas (gitweb http://git.mansr.com/?p=vividas).
External Resources
Extended company and product description is available on Wikipedia.
"Vividas Licenses TrueMotion VP7 for Mass Distribution of High Quality Video" January 13th, 2005