文档来源:MSDN Library->Win32 and COM Development->Graphics and Multimedia->Audio and Video->DirectShow->Appendixes->AVI File Format-> AVI RIFF File Reference
微软的AVI文件格式是一种用于拍摄,编辑和播放音频,视频序列的RIFF文件格式。一般情况下, AVI文件包含多个流的不同类型的数据。大多数的AVI序列同时使用音频和视频数据流。一个简单的变种AVI序列使用视频数据而不需要音频流。
本节不描述OpenDML AVI文件格式的扩展。如需进一步关于这些扩展的资料,见AVI OpenDML的M-JPEG文件格式的小组委员会所发表的OpenDML AVI文件格式的扩展
FOURCCs
一个FOURCC(四字符代码)是一个由32位无符号整数所连接的四个ASCII字符。例如,FOURCC 'abcd'代表的小端(译者注:一种存放二进制数据的格式,所有数字的低位放在前面)系统为0x64636261。FOURCCs可以包含空格,' abc'是合法的FOURCC。在AVI文件格式中使用FOURCC码来识别流类型,数据块,索引项目,以及其他信息。
RIFF文件格式
AVI文件格式是基于RIFF(资源交换文件格式)文件格式的。一个RIFF文件包括一个RIFF头,后跟零个或多个list和chunk。
RIFF头格式如下:
'RIFF' fileSize fileType (data)
其中,'RIFF'是FOURCC的字面值,fileSize是4字节值表示的数据在文件中的大小,fileType是一个FOURCC表示的文件类型。fileSize的值包括fileType和data,并不包括'RIFF'和fileSize本身。Data由chunk和list以任意顺序组成。
Chunk格式如下:
CkID ckSize ckData
其中,ckID是FOURCC表示的chunk中数据的标识。ckSize是4字节标识的ckData中数据的大小,ckData是大于等于零的数据,都要填充到最接近的词边界。ckSize是chunk中有效数据的大小;并不包括填充,ckID和ckSize。
List格式如下:
'LIST' listSize listType listData
其中,'LIST'是FOURCC的字面值,listSize是4字节值表示的数据在文件中的大小,listType是FOURCC码,listData以任意顺序包含chunk和list。listSize包含listType和listData的大小,并不包括'LIST'和listSize本身。
本节余下的部分使用下例符号来描述RIFF chunk:
ckID ( ckData )
chunkSize被隐藏。使用下例符号来描述RIFF list:
'LIST' (listType (listData))
可选元素是放在括号中:[可选元素]
AVI RIFF格式:
AVI文件定义一个'AVI '的FOURCC在RIFF header中。所有的AVI文件包括两个强制性的list块,分别定义格式流和数据流。一个AVI文件可能还包括一个索引块,用于定位数据chunk在文件中的位置。一个AVI文件的组件如下:
RIFF ('AVI '
LIST ('hdrl' ...)
LIST ('movi' ...)
['idx1' (<AVI Index>)]
)
'hdrl'定义数据格式,是第一个需要的list块。'movi'包含AVI序列的数据,是第二个需要的list块。'idx1'包含索引。AVI文件必须保持这三个部分的顺序。
注意:OpenDML扩展定义另一种类型的索引,用FOURCC 'indx'表示。
'hdrl' and 'movi'用子chunk来存储数据。下面的例子展现了AVI RIFF所需要完成的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>) ]
)
AVI头:
AVI 头以'hdrl'列表开始,包含一个'avih'块。头包括AVI文件的全局信息,如文件中包含的流的数量,AVI序列的高和宽。头chunk由一个AVIMAINHEADER结构组成。
typedef struct _avimainheader {
FOURCC fcc;
DWORD cb;
DWORD dwMicroSecPerFrame;
DWORD dwMaxBytesPerSec;
DWORD dwPaddingGranularity;
DWORD dwFlags;
DWORD dwTotalFrames;
DWORD dwInitialFrames;
DWORD dwStreams;
DWORD dwSuggestedBufferSize;
DWORD dwWidth;
DWORD dwHeight;
DWORD dwReserved[4];
} AVIMAINHEADER;
AVI流头:
一个或多个'strl'列表跟在AVI头后面。每一个数据流需要一个'strl'列表,每一个'strl'列表包含一个流的信息,它必须包含'strh'的流头块和'strf'的流格式块。此外,'strl'可以包含'strd'的流头数据块和'strn'的流名称块。
'strh'流头块可以用AVISTREAMHEADER结构表示。
typedef struct _avistreamheader {
FOURCC fcc;
DWORD cb;
FOURCC fccType;
FOURCC fccHandler;
DWORD dwFlags;
WORD wPriority;
WORD wLanguage;
DWORD dwInitialFrames;
DWORD dwScale;
DWORD dwRate;
DWORD dwStart;
DWORD dwLength;
DWORD dwSuggestedBufferSize;
DWORD dwQuality;
DWORD dwSampleSize;
struct {
short int left;
short int top;
short int right;
short int bottom;
} rcFrame;
} AVISTREAMHEADER;
'strf'流格式块必须跟在流头块的后面。流格式块描述流中的数据格式。这个块中的数据决定于流的类型。视频流由BITMAPINFO结构表示,如果适合会包括调色板信息。音频流由WAVEFORMATEX结构表示。
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;
typedef struct {
WORD wFormatTag;
WORD nChannels;
DWORD nSamplesPerSec;
DWORD nAvgBytesPerSec;
WORD nBlockAlign;
WORD wBitsPerSample;
WORD cbSize;
} WAVEFORMATEX;
如果'strd'流头数据块存在,它将跟在流格式块后面。它的格式和内容决定于编解码器驱动程序。通常情况下,驱动用它做配置信息。应用程序,读取和写入AVI文件不需要解释此信息;他们可以简单的传输到驱动作为一个内存区块。
可选的'strn'块包含一个以空字符结尾的文本描述流。
'hdrl'列表中的流头和'movi'列表中通过'strl'块相关联。第一个'strl'块使用Stream 0,第二个使用Stream 1,如此等等。
流数据 ('movi' 列表)
在头信息之后是'movi'列表包含真实的数据流,视频帧和音频样本。数据可以直接存放在'movi'列表中,也可以组织在'rec '列表中。组织在'rec '列表中意味着数据块应该一次性从硬盘读入,使得文件可以在CD-ROM中播放。
表示每个数据块的FOURCC由两字节的流编号和两字节的信息类型。
两字节代码 | 描述 |
db | 非压缩视频帧 |
dc | 压缩视频帧 |
pc | 调色板更改 |
wb | 音频数据 |
例如,如果Stream 0 包含音频,这个数据块应该是FOURCC '00wb'。如果Stream 1包含视频,这个数据块应该是FOURCC '01db'或'01dc'。视频数据块也可以定义新的调色板更新调色板中的AVI序列。每一个palette-change块('xxpc')包含一个AVIPALCHANGE结构。如果一个流包含调色板改变,设置AVISTREAMHEADER 结构中的dwFlags 的AVISF_VIDEO_PALCHANGES标志
typedef struct {
BYTE bFirstEntry;
BYTE bNumEntries;
WORD wFlags;
PALETTEENTRY peNew[];
} AVIPALCHANGE
文本流可以使用任意两个字符代码。
AVI 索引
可选的'idx1'索引块出现在'movi'列表的后面。索引包括列表中的数据块和它们在文件中的位置。每一个数据块都可以用一个AVIOLDINDEX结构做索引,包括'rec '块。如果文件包含索引,将设置AVIMAINHEADER结构的dwFlags的AVIF_HASINDEX标志。
typedef struct _avioldindex {
FOURCC fcc;
DWORD cb;
struct _avioldindex_entry {
DWORD dwChunkId;
DWORD dwFlags;
DWORD dwOffset;
DWORD dwSize;
} aIndex[];
} AVIOLDINDEX;
其他数据chunk:
可以在需要的时候插入'JUNK'块来对齐AVI文件。应用程序应该忽略JUNK块中的内容。