微软的 AVI 文 件格式是一种用于捕获、编辑和回放audio-video序列的RIFF文件规范。总体上讲,AVI文件包含多个针对不同数据的流。大部分AVI序列使用 audio和video流。一个简单的AVI序列特例可以只包含video数据而不包含audio 数据。
AVI 文件使用FOURCC码标示流的类型、数据chunk、index元素和其他的信息。FOURCC( four-character code,4字符码)是4个ASCII码字符串的32位的无符号整型数据。
AVI 文件格式是基于RIFF ( resource interchange file format ) 文档格式的。一个RIFF文件包含一个RIFF 头, 以及其后的多个list和chunk。
RIFF头的格式:"RIFF"+文件大小+文件类型+(数据)。这边的"RIFF"是指FOURCC码表示的"RIFF",文件大小包含的是文件类型以及其后数据的大小,不包含FOURCC码'RIFF'和文件大小本身所占的空间。文件类型是用FOURCC表示的文件类型值。
块(chunk)的格式:ckID+ckSize+ckData。ckID是一个说明该chunk中所包含的数据的FOURCC码,ckSize是表示ckData中数据大小的4字节数值,ckData是0个或多个字节的数据。数据总是填充到就近的WORD边界。ckSize表示的是chunk中有效数据的大小,它不包括填充部分的大小,以及ckID和ckSize所占的空间。
List格式:"LSIT"+listSize+listType+listData。"LIST"就是FOURCC码"LIST"。listSize是表示list大小的4字节数值。listType是一个FOURCC码。listData中是以任意顺序排列的多个list和chunk。listSize包含的是listType和listData的大小,而不包含FOURCC码'LIST'和文件大小本身所占的空间。
AVI文件在RIFF头中用FOURCC码"AVI "标示。所有的AVI文件都被强制要求包含两个LIST 类型的chunk,分别定义了stream的格式和stream的数据。一个AVI文件还可能包含一个index chunk,其中包含了数据chunk在文件中的位置。
包含以上部分的AVI文件的格式为:
RIFF ('AVI '
LIST ('hdrl' ... )
LIST ('movi' ... )
['idx1' (<AVI Index>) ]
)
'hdrl'list定义了数据的格式,是第一个必须的LIST chunk。'movi'list包含了AVI序列中的数据,是第二个必须的LIST chunk。'idx1'list包含了index数据。这三部分在AVI文件中的顺序是特定的。
'hdrl' list和'movi' list用subchunk来表示它们的数据。下面的例子列出了AVI RIFF文件的结构, 其中的list需要包含相应的chunk。
RIFF ('AVI '
LIST ('hdrl'
'avih'(<Main AVI Header>)
LIST ('strl'
'strh'(<Stream header>)
'strf'(<Stream format>)
[ 'strd'(<Additional header data>) ]
[ 'strn'(<Stream name>) ]
...
)
...
)
LIST('movi'
{SubChunk | LIST ('rec '
SubChunk1
SubChunk2
...
)
...
}
...
)
['idx1' (<AVI Index>) ]
)
'hdrl' list的开头部分是一个包含MainAVI header的'avih' chunk。MainAVI header中包含了AVI文件的一些全局信息,如:文件中包含多少个流,AVI序列的宽高等等。
typedef struct
{
DWORD dwMicroSecPerFrame ; //显示每桢所需的时间ns,定义avi的显示速率
DWORD dwMaxBytesPerSec; // 最大的数据传输率
DWORD dwPaddingGranularity; //记录块的长度需为此值的倍数,通常是2048
DWORD dwFlages; //AVI文件的特殊属性,如是否包含索引块,音视频数据是否交叉存储
DWORD dwTotalFrame; //文件中的总桢数
DWORD dwInitialFrames; //说明在开始播放前需要多少桢
DWORD dwStreams; //文件中包含的数据流种类
DWORD dwSuggestedBufferSize; //建议使用的缓冲区的大小,
//通常为存储一桢图像以及同步声音所需要的数据之和
DWORD dwWidth; //图像宽
DWORD dwHeight; //图像高
DWORD dwReserved[4]; //保留值
}MainAVIHeader
MainAVIHeader后面跟的是一个或多个'strl' list。每一个数据流都需要有一个'strl' list。每一个'strl' list都必须包含文件中一种流的信息,并且必须包含该流的header chunk('strh')和format chunk('strf')。另外,一个'strl' list还可能包含一个流的头数据chunk('strd')和一个流的名称chunk('strh')。
流的header chunk ('strh')可以用结构体AVISTREAMHEADER表示。
typedef struct
{
FOURCC fccType; //4字节,表示数据流的种类 vids 表示视频数据流
//auds 音频数据流
FOURCC fccHandler;//4字节 ,表示数据流解压缩的驱动程序代号
DWORD dwFlags; //数据流属性
WORD wPriority; //此数据流的播放优先级
WORD wLanguage; //音频的语言代号
DWORD dwInitalFrames;//说明在开始播放前需要多少桢
DWORD dwScale; //数据量,视频每桢的大小或者音频的采样大小
DWORD dwRate; //dwScale /dwRate = 每秒的采样数
DWORD dwStart; //数据流开始播放的位置,以dwScale为单位
DWORD dwLength; //数据流的数据量,以dwScale为单位
DWORD dwSuggestedBufferSize; //建议缓冲区的大小
DWORD dwQuality; //解压缩质量参数,值越大,质量越好
DWORD dwSampleSize; //音频的采样大小
RECT rcFrame; //视频图像所占的矩形
}AVIStreamHeader;
流的format chunk('strf')一定要跟在header chunk的后面。Format chunk描述了流中数据的格式。Format chunk中包含什么数据,依赖于流的类型。对于video流,其中的数据是一个BITMAPINFO结构体。BITMAPINFO 结构体由一个BITMAPINFOHEADER 结 构体以及一个跟在其后面的RGBQUAD 数值数组构成。
typedef struct tagBITMAPINFO
{
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1]; //颜色表
}BITMAPINFO;
typedef struct tagBITMAPINFOHEADER
{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
}BITMAPINFOHEADER;
对于audio流,其中的数据是一个WAVEFORMATEX结构体。
typedef struct
{
WORD wFormatTag;
WORD nChannels; //声道数
DWORD nSamplesPerSec; //采样率
DWORD nAvgBytesPerSec; //WAVE声音中每秒的数据量
WORD nBlockAlign; //数据块的对齐标志
WORD biSize; //此结构的大小
}WAVEFORMAT
可选的'strn'chunk包含一个描述流的,以空字符为结尾的文本字符串。
'hdrl'list中流的头信息,按照其中'strl'chunk的顺序,与'movi'list中的流数据关联起来。