Sunday, March 1, 2009

AVI File Format - Open-DML Index

The general structure of an Open-DML-Index-Chunk is the following:

typedef struct _aviindex_chunk
{
FOURCC fcc;
DWORD cb;
WORD wLongsPerEntry;
BYTE bIndexSubType;
BYTE bIndexType;
DWORD nEntriesInUse;
DWORD dwChunkId;
DWORD dwReserved[3];

struct _aviindex_entry
{
DWORD adw[wLongsPerEntry];
} aIndex [ ];

} AVIINDEXCHUNK;

Every subtype of Open-DML index structures is compatible to this one. The elements have the following meaning:

• fcc, cb: Chunk header, same as dwFourCC and dwSize in the CHUNK structure

• wLongsPerEntry: every aIndex[i] has a size of 4*wLongsPerEntry bytes. (the struc-ture of each aIndex[i] depends on the special type of index)

• bIndexType, bIndexSubType: defines the type of the index

• nEntriesInUse: aIndex[0]..aIndex[nEntriesInUse-1] are valid

• dwChunkId: ID of the stream the index points into, for example '00dc'.Consequently, one such index chunk can only point to data of one and the same stream.

Upper Level Index ('Super Index')

The upper level index ('super index') points to other index chunks and has the following structure:

typedef struct _avisuperindex_chunk
{
FOURCC fcc;
DWORD cb;
WORD wLongsPerEntry;
BYTE bIndexSubType;
BYTE bIndexType;
DWORD nEntriesInUse;
DWORD dwChunkId;
DWORD dwReserved[3];

struct _avisuperindex_entry
{
__int64 qwOffset;
DWORD dwSize;
DWORD dwDuration;
} aIndex[ ];

} AVISUPERINDEX;

The following values are now defined more specifically:

• bIndexType = AVI_INDEX_OF_INDEXES

• bIndexSubType = [ AVI_INDEX_2FIELD 0 ]

• wLongsPerEntry = 4

As you can see, the aIndex array now consists of 4 DWORDs per entry. The values have the following meaning:

qwOffset: Position of the index chunk this entry points to in the file

dwSize: The size of the standard or field index chunk the entry is pointing to

dwDuration: The duration, measured in stream ticks as indicated in the AVI stream header. In case of video or VBR audio, that usually refers to the number of frames.
Important: VirtualDub 1.4.10 and earlier versions wrote b0rked values for this member in theaudio stream. Thus, an AVI parser should be able to handle files without using this value!

The Standard Index

This index type contains pointers to video, audio or subtitle chunks. It also is a special form of the general Open-DML Index and looks like this:

typedef struct _avistdindex_chunk
{
FOURCC fcc;
DWORD cb;
WORD wLongsPerEntry;
BYTE bIndexSubType;
BYTE bIndexType;
DWORD nEntriesInUse;
DWORD dwChunkId;
__int64 qwBaseOffset;
DWORD dwReserved3;

struct _avistdindex_entry
{
DWORD dwOffset;
DWORD dwSize;
} aIndex[ ];

} AVISTDINDEX;

wLongsPerEnrty: As you can see easily, each aIndex[i] takes 8 bytes,so wLongsPerEntry = 2

bIndexSubType: = 0

bIndexType:= AVI_INDEX_OF_CHUNKS

qwBaseOffset: This value is added to each dwOffset value of the AVISTDINDEX.

dwOffset, dwSize: These elements define the position (qwBaseOffset + dwOffset) of the data section of the corresponding CHUNK (NOT the chunk header!) and its length. There are nEntriesInUse such pairs, each one describing one video/audio frame. Note that Bit 31 of dwSize indicates the frametype: If this bit is set, this frame is not a keyframe.

Low-overhead mode

The Open-DML specication does not explicitly require that each "data section" the index contains an entry to be preceded by a chunk header. Thus, several frames can be put into one chunk, while having one index entry per frame. This way, only few frames have a chunkheader, reducing the overhead by 50% compared to normal Open-DML files. This means, ofcourse, that the AVIF_MUSTUSEINDEX again the main AVI header must be set, to force any parser to use the index. Files created this way will be called "low overhead AVI files".

This is not an AVI file type on its own. Any parser handling that flag, as well as the Open-DML index correctly, should be compatible to such files. Microsoft's AVI splitter, as well as VirtualDub(Mod) can handle such files without problems, without having been updated todo so.

Using the Open-DML Index

The preceding section described what the Open-DML Index looks like. This section will deal with using it.

Each stream contains an 'indx' chunk in its stream header list ('strl'). This chunk is a Super Index chunk.

As each Standard Index contains one 64 bit offset and then a list of 32 bit offsets relatively to the 64 bit offset, one Standard Index chunk can only point to data within one 4 GB segment.Thus you need one Standard Index per 4 GB file size per stream.

Unfortunately, it seems that Microsoft did not read the specification properly: If a file contains more than 3 audio streams, then the Microsoft AVI Splitter will not recognize files using such large Standard Index chunks. It is required to use smaller pieces. Tests have shown that pieces with 15000 entries each are small enough to be processed correctly byMicrosoft's AVI splitter.

No comments:

Post a Comment