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_sizeandnum_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_headerelement 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[i] 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.
- data[i]
- Vorbis (or speex?) header packets
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 0 have the following structure:
chunk_1() {
video_length v
audio_length v
video_data d(video_length)
do {
end_of_packet[i] v
unknown v
} while(end_of_packet != 0)
for(int i=0;i<n_packets;i++)
audio_data[i] d(end_of_packet[i] - end_of_packet[i-1])
}
- video_data
- VP6-encoded video packet (always a keyframe?)
- audio_data
- multiple Vorbis(or speex?)-encoded audio packets
The chunks for which flag is 1 have the following structure:
chunk_1() {
length v
video_data d(length)
}
- video_data
- VP6-encoded video packet (always non-keyframe?)
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