AVI文件采用的是RIFF文件结构方式。波形音频wave,MIDI和数字视频AVI都采用这种格式存储。
AVI文件的整体结构如下图所示
构造RIFF文件的基本单元叫做数据块(Chunk),每个数据块包含3个部分
整个RIFF文件可以看成一个RIFF块。一个RIFF文件中只允许存在一个RIFF块。RIFF块中包含一系列的子块,其中有一种子块的ID为“LIST”称为LIST,LIST块中可以再包含一系列的子块,但除了LIST块外的其他所有的子块都不能再包含子块。
RIFF和LIST块分别比普通的数据块多一个被称为形式类型(Form Type)和列表类型(List Type)的数据域,其组成如下
- //Chunks
- typedef struct {
- DWORD dwFourCC
- DWORD dwSize //data
- BYTE data[dwSize] // contains headers or video/audio data
- } CHUNK;
-
- //Lists
- typedef struct {
- DWORD dwList
- DWORD dwSize //dwFourcc + data
- DWORD dwFourCC
- BYTE data[dwSize-4] // contains Lists and Chunks
- } LIST;
整个AVI文件是一个类型码为为"AVI "的RIFF块,其主要有三个subchunk构成:
AVI文件的展开结构大致如下:
avih块用于描述avi文件信息
其结构如下
- typedef struct
- {
- FourCC fcc; // 必须为 avih
- DWORD cb; // 本数据结构的大小,不包括最初的8个字节(fcc和cb两个域)
- DWORD dwMicroSecPerFrame; // 视频帧间隔时间(以毫秒为单位)
- DWORD dwMaxBytesPerSec; // 这个AVI文件的最大数据率
- DWORD dwPaddingGranularity; // 数据填充的粒度
- DWORD dwFlags; // AVI文件的全局标记,比如是否含有索引块等
- DWORD dwTotalFrames; // 总帧数
- DWORD dwInitialFrames; // 为交互格式指定初始帧数(非交互格式应该指定为0)
- DWORD dwStreams; // 本文件包含的流的个数
- DWORD dwSuggestedBufferSize; // 建议读取本文件的缓存大小(应能容纳最大的块)
- DWORD dwWidth; // 视频图像的宽(以像素为单位)
- DWORD dwHeight; // 视频图像的高(以像素为单位)
- DWORD dwReserved[4]; // 保留
- } AVIMainHeader;
strh用于描述流的头信息
- // AVI流头部
- typedef struct
- {
- FourCC fcc; // 必须为 strh
- DWORD cb; // 本数据结构的大小,不包括最初的8个字节(fcc和cb两个域)
- FourCC fccType; // 流的类型: auds(音频流) vids(视频流) mids(MIDI流) txts(文字流)
- FourCC fccHandler; // 指定流的处理者,对于音视频来说就是解码器
- DWORD dwFlags; // 标记:是否允许这个流输出?调色板是否变化?
- WORD wPriority; // 流的优先级(当有多个相同类型的流时优先级最高的为默认流)
- WORD wLanguage; // 语言
- DWORD dwInitialFrames; // 为交互格式指定初始帧数
- DWORD dwScale; // 每帧视频大小或者音频采样大小
- DWORD dwRate; // dwScale/dwRate,每秒采样率
- DWORD dwStart; // 流的开始时间
- DWORD dwLength; // 流的长度(单位与dwScale和dwRate的定义有关)
- DWORD dwSuggestedBufferSize;// 读取这个流数据建议使用的缓存大小
- DWORD dwQuality; // 流数据的质量指标(0 ~ 10,000)
- DWORD dwSampleSize; // Sample的大小
- RECT rcFrame; // 指定这个流(视频流或文字流)在视频主窗口中的显示位置,视频主窗口由AVIMAINHEADER结构中的dwWidth和dwHeight决定
- } AVIStreamHeader;
该块用于描述流的具体信息。如果是视频流(vids,由strh块得知),用一个BitmapInfo结构体表示,如果是音频流(auds),用WaveFormatEx结构体表示。
数据块中存储视频和音频数据流,数据可直接存于“movi LIST”中。数据块中音视频数据按不同的子块存放,其结构如下所述
音频子块
"##wb"
Wave 数据流
视频子块中存储DIB数据,又分为压缩或者未压缩DIB
"##db"
RGB数据流
"##dc"
压缩数据流
索引块包含数据块在文件中的位置索引,能提高avi文件的读写速度。这个块不是必需的。