Indeo 5
- FOURCCs: IV50
- Company: Intel, then Ligos
- Samples: http://samples.mplayerhq.hu/V-codecs/IV50/
General description
Frame layout
The general indeo5 frames layout is composed of one global header, followed by the content of the three YUV plans.
In this document, the global header is split into 3 parts:
- Frame header: describe the kind of frame (I/P/B)
- GOP header: some data which is true for all the frame in this GOP (present only in the first (I) frame of the GOP)
- More header: some more data which is true only for this single frame
Each YUV plan begin with a Plan header, containing values which are valid only for this single plan.
Encoding
This codec is based on the slant transform. Other used standard techniques are huffman coding and motion compensation.
Conventions
Headers are described in some tables. Each row of those tables describes a value which may be read from the frame. Those tables and rows are presented in the order of appearance in the frame.
Here are the meaning of each columns:
- size: The size of this value in bits. Bits are counted in LSB to MSB order. As an example, with the byte 01110000b, reading 3 bits then 5 bits will return 000b then 01110b. Reading more than 8 bits thus reads as a little-endian value. Think of the get_bits function as filling up the return value from its LSB, using the bits from each byte starting from their LSB.
- name: Kind of variable name, used to reference the value. When a value is named valueX, it generally means we don't know it's purpose. Lines named alignmentX means that bits reader need to skip bits until next byte boundary.
- condition: The value is present in the frame only if this condition is matched. No condition means that the value is always present.
- nb times: How many times the value is repeated.
- comments: Some details about the content of the value. It may also explain that a value is repeated until a certain condition is reached.
Headers
Frame header
size | name | condition | nb times | comments |
---|---|---|---|---|
5 | const1 | = 0x1F always | ||
3 | frame_flags |
common values:
| ||
8 | id_in_gop | frame number in GOP (0 for I frame) |
null frames don't contain anything else than this header.
GOP header
This header is present in I frames only. The values in this header are valid during the whole GOP starting at this frame.
size | name | condition | nb times | comments |
---|---|---|---|---|
8 | gh_flags | gh_flags & 0x02 => YV12 (default YVU9) | ||
16 | value1 | gh_flags & 0x01 | discard in decoding | |
32 | value2 | gh_flags & 0x20 | ||
2 | value3 | gh_flags & 0x40 | ||
3 | value4 | legal values are 0, 1, 2 and 6 | ||
4 | res_id | see Resolution table | ||
13 | height | res_id == 15 | frame height | |
13 | width | frame width | ||
6 | value5 | 2*n (n == 1 always?) | ||
2 | value6 | value5 >> 3 | need to be = 0 | |
4 | value7 | gh_flags & 0x08 | ||
24 | value8 | |||
?? | alignment1 | align bits reader on next byte | ||
24 | value9 | |||
16 | value10 | value9 & 0x800000 | loops while value10 & 0x8000 (probably some kind of VLC ?) |
More header
This header is present in all kinds of frame except null.
size | name | condition | nb times | comments |
---|---|---|---|---|
8 | mh_flags | |||
24 | frame_size | mh_flags & 0x01 | tolal size of frame data | |
16 | value11 | mh_flags & 0x10 | ||
8 | counter1 | mh_flags & 0x20 | this whole block loops while counter1 != 0 | |
8 | value12 | counter1 | ||
3 | value13 | mh_flags & 0x40 | ||
4 | counter2 | value13 == 7 | ||
4 | value14 | counter2 | ||
3 | value15 | |||
?? | alignment2 | align bits reader on next byte |
Plane header
This header is present at the beginning of every plane.
size | name | condition | nb times | comments |
---|---|---|---|---|
8 | ph_flags | |||
24 | plan_size | mh_flags & 0x80 | tolal size of plan data | |
8 | counter3 | ph_flags & 0x10 | must be < 0x3E | |
8 | value16 | counter3 | ||
8 | value17 | |||
3 | value18 | ph_flags & 0x40 | ||
3 | table1_id | ph_flags & 0x80 | see Table 1 | |
4 | counter4 | table1_id == 7 | used instead of Table1 | |
4 | value19 | counter4 | ||
1 | value20 | |||
16 | value21 | value20 | ||
5 | value22 | |||
?? | alignment3 | align bits reader on next byte | ||
8 | counter5 | ph_flags & 0x20 | all of this is repeated as long as value23 is true | |
8 | skip1 | counter5 | ||
1 | value23 | |||
?? | alignment4 | align bits reader on next byte |
Planes
Plane data
Needs more analysis. Follows plane header.
size | name | condition | nb times | comments |
---|---|---|---|---|
1 | value24 | |||
1 | value25 | ! value24 | plan_data_size = value25 | |
8 | value26 | value25 == 1 | plan_data_size = value26 | |
24 | value27 | value26 == 0xFF | plan_data_size = value27 |
Block header
One of these for each block after plane data. Conditions/loops not yet investigated.
size | name | condition | nb times | comments |
---|---|---|---|---|
1 | value28 | |||
vlc | value29 | |||
1 | value30 | |||
4 | value31 | |||
1 | value32 | |||
vlc | value33 | |||
vlc | value34 | |||
vlc | value35 |
Block data
Follows block header. One of these for each plane that has 'plane_flags&1'. The variable 'run' starts at -1 and carries over from one coded plane to the next. I don't really know what I'm doing with vlc's so the names might not be correct... but their functional description is.
size | name | condition | nb times | comments |
---|---|---|---|---|
vlc | vlc | while (vlc != vlcEnd) | ||
vlc | run_add | vlc == vlcEsc | run += run_add + 1 | |
vlc | lindex_lo | lindex = lindex_lo | (lindex_hi<<6) | ||
vlc | lindex_hi |
If vlc != vlcEsc then run_add is run_table[vlc], lindex is lindex_table[vlc].
After each loop, stored coefficient is: block[ scan_table[run] ] = level_tables[run][lindex-1].
The values of vlcEnd and vlcEsc are variable, as is the vlc table itself. However, they are all fixed for all the planes in the same block. run_table, lindex_table, scan_table are also fixed-per-block. level_tables is per-plane.
Annexes
Resolution table
res_id | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
width | 640 | 320 | 160 | 704 | 352 | 352 | 176 | 240 | 640 | 704 | 80 | 88 |
height | 480 | 240 | 120 | 224 | 240 | 288 | 144 | 180 | 240 | 240 | 60 | 72 |
Table 1
table1_id | 0 | 1 | 2 | 3 | 4 | 5 | 6 | default | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
counter4 | 10 | 11 | 12 | 13 | 11 | 13 | 13 | 9 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
value19 |
|
|
|
|
|
|
|
|
default is used when !(ph_flags & 0x80)