AVI文件格式包括两种类型的Index:Old Style Index和Open-DML Index。他们在AVI文件中对应的fourcc分别为‘idx1’和‘indx’
一、Old Style Index
这种Index结构比较简单,包括每个chunk的偏移量和类型。通过这个Index可以有效的实现playback和seek功能。每个entry的结构如下所示:
typedef struct {
DWORD ckid;
DWORD dwFlags;
DWORD dwChunkOffset;
DWORD dwChunkLength;
}AVIINDEXENTRY;
Index table即是以AVIINDEXENTRY结构体类型为元素的数组,即
AVIINDEXENTRY index_entry[n]。
ckid:标识chunk数据的chunk ID,用一个四位字符码表示;
dwFlags:标识chunk的类型;
dwChunkOffset:标识chunk的偏移量,这个偏移量可以是在文件中的绝对位置,也可以是相对于‘movi’的第一个字节的位置;
dwChunkLength:标识chunk的大小,以字节为单位。
这种Index存在下面三个方面的问题:
(1)Allow Field Indexing
(2)Allow Incremental Growth of Files
(3)Minimize Disk Seeks
二、Open-DML Index
为了克服‘idx1’存在的几个方面的问题,提出了一种新的Index结构‘indx’。这种新的Index结构主要包括以下几个方面的特性:
(1)这种Index结构可以是单Index结构,也可以分层布局的Index结构;
(2)可以精确到每一帧中场的位置;
(3)不受4G文件大小的限制;
(4)在必要的情况下,可以为每个stream分配一个Index。
与‘idx1’相比,‘indx’有以下几个方面的优势:
(1)‘indx’可以精确到每个场的位置,而‘idx1’只能精确到帧;
(2)在‘movi’中,‘indx’是交叉的结构,可以很容易的实现增量扩展,而‘idx1’是放在文件的末尾,为了实现增量扩展,必须先移除;
(3)‘indx’的Index段比‘idx1’的小,因此,为了访问某个特定的帧,需要read的数据比较少,而且,如果index是交叉在数据之前的,那么playback的效率会更高;
(4)‘indx’的Index list会分配给每一个stream,访问list就像访问数组一样,而‘idx1’则是包含所有的stream的所有chunk。
‘indx’包括三种Index结构:Upper Level Index(Super Index)、Standard Index和Field Index。
1、Upper Level Index
Upper Level Index也被称为Super Index,用来指向其他类型的index chunk。其结构如下所示:
typedef struct _avisuperindex_chunk {
FOURCC fcc;
DWORD cb;
WORD wLongsPerEntry;
BYTE bIndexSubType;
BYTE bIndexType;
DWORD nEntriesInUse;
DWORD dwChunkId;
DWORD dwReserved[3];
struct _avisuperindex_entry {
QUADWORD qwOffset;
DWORD dwSize;
DWORD dwDuration;
} aIndex[ ];
} AVISUPERINDEX;
(1)bIndexType被设置为AVI_INDEX_OF_INDEXES。
(2)bIndexSubType被设置为0或者AVI_INDEX_2FIELD。如果其所指向的sub Index为Standard Index,则设置为0;如果指向的sub Index为Field Index,则设置为AVI_INDEX_2FIELD。
(3)nEntriesInUse表示aIndex数组中被使用的entry的个数。
(4)dwOffset表示其所指向的sub index chunk的位置。
(5)dwSize表示其所指向的sub index chunk的大小。
(6)dwDuration表示其所指向的sub index chunk的时长,以stream的ticks为单位。
2、Standard Index
Standard Index指向video, audio或者subtitle chunks,即AVI文件的帧数据。其结构如下所示:
typedef struct _avistdindex_chunk {
FOURCC fcc;
DWORD cb;
WORD wLongsPerEntry;
BYTE bIndexSubType;
BYTE bIndexType;
DWORD nEntriesInUse;
DWORD dwChunkId;
QUADWORD qwBaseOffset;
DWORD dwReserved3;
struct _avistdindex_entry {
DWORD dwOffset;
DWORD dwSize;
} aIndex[ ];
} AVISTDINDEX;
(1)bIndexSubType设置为0;bIndexType设置为AVI_INDEX_OF_CHUNKS。
(2)dwOffset是一个相对于qwBaseOffset偏移量,其对应的绝对位置是qwBaseOffset + dwOffset。该变量表示了该chunk的数据段的位置。
(3)dwSize表示了该chunk的数据段的长度。
3、Field Index
Field Index和Standard Index类似,不同的是它精确到场。其结构如下所示:
typedef struct _avifieldindex_chunk {
FOURCC fcc;
DWORD cb;
WORD wLongsPerEntry;
BYTE bIndexSubType;
BYTE bIndexType;
DWORD nEntriesInUse;
DWORD dwChunkId;
QUADWORD qwBaseOffset;
DWORD dwReserved3;
struct _avifieldindex_entry {
DWORD dwOffset;
DWORD dwSize;
DWORD dwOffsetField2;
} aIndex[ ];
} AVIFIELDINDEX;
(1)其结构与Standard Index类似,只是在aIndex中多了一个变量dwOffsetField2。该变量表示第二个场的偏移量。
(2)bIndexSubType设置为AVI_INDEX_2FIELD;bIndexType设置为AVI_INDEX_OF_CHUNKS。
(3)dwOffset是一个相对于qwBaseOffset偏移量,其对应的绝对位置是qwBaseOffset + dwOffset。该变量表示了该chunk的数据段的位置。
(4)dwSize表示了该chunk的数据段的长度。