AVI文件格式学习笔记(非完全版)
1、名词解释
— AVI:Audio Video Interleaved
— RIFF:Resource Interchange File Format
— FOURCC:Four-Character Code
2、RIFF格式
RIFF格式的文件由一个RIFF头开始,其后添加0个或多个list或chunk组成。
— RIFF头格式如下:
'RIFF' filesize filetype (data)
'RIFF':'RIFF'的FOURCC码;
filesize:4字节,包括filetype域和data域在内的所有数据的大小,不包括'RIFF'和filesize域本身;
filetype:表示文件类型的FOURCC码;
— chunk的格式如下:
ckID ckSize ckData
ckID:FOURCC码,标识chunk中的数据;
ckSize:4字节,ckData域的实际数据的大小,不包括ckID和ckSize域以及ckData中的padding数据;
ckData:chunk中的数据,其大小通常要被padding到word对齐(即2字节对齐)
本文档中,一个chunk将被表述为:ckID ( ckData )
— list的格式如下:
'LIST' listSize listType listData
'LIST':'LIST'的FOURCC码;
listSize:4字节,该list的大小,包括listType域和listData域,不包括'LIST'和listSize域;
listType:FOURCC码;标识list中的数据;
listData:list中的数据;
本文档中,一个list将被表述为:'LIST' ( listType ( listData ) )
3、AVI RIFF格式
— 概述
AVI文件在RIFF头中用FOURCC码'AVI '标识;
一个AVI文件中包两大主要的LIST chunks,一个定义流的格式,另一个包含流的数据;
AVI文件中还可能包含一个索引(index)chunk,帮助定位数据chunk在文件中的位置;
包含这些组件的AVI文件将有如下格式:
RIFF( 'AVI '
LIST ('hdrl' ... )
LIST ('movi' ... )
['idxl' (<AVI Index>)]
)
其中:
'hdrl':定义数据的格式;
'movi':包含AVI序列的数据;
二者可能各自包含subchunk;
— 一个完整的AVI文件的示例:
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 Main Header
AVI的'hdrl' list由一个AVI Main Header开头,其中包含了整个AVI文件的全局信息。具体结构如下:
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;
某些成员解析:
fcc:FOURCC码,为'avih';
cb:整个结构的大小,除了开头的8个字节;
dwMicroSecPerFrame:每帧需要的时间,用us表示;
dwMaxBytesPerSec:每秒最大的数据量,即指明了该文件的最大数据速率;
dwTotalFrames:整个文件中的总帧数;
dwInitialFrames:指明interleaved文件中首帧的位置;非interleaved文件中,
dwStreams:指明文件中流的数目。比如,一个包含有音频和视频数据的文件,包含有两个流;
dwWidth:每行的像素数;
deHeight:每列的像素数;
— AVI Stream Header
AVI Main Header之后就是一个一个的'strl' list,每条数据流都需要一个'strl' list;
每个'strl' list都可包含四个部分:'strh'、'strf'、'strd'和'strn'。其中'strd'和'strn'是可选的;
'strh'为stream header chunk,其结构如下:
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;
某些成员解析:
fcc:FOURCC码'strh';
cb:本结构大小,除掉开头的8个字节;
fcctype:FOURCC码,指明当前流中的数据类型;标准取值有'auds'、'mids'、'txts'和'vids',分别对应Audio、MIDI、Text和Video流;
fccHandler:FOURCC码,指明当前流的数据handler,比如音频流或视频流的解码器;
dwScale和dwRate:dwScale除以dwRate即得到每秒的sample数;
dwStart:当前流的起始时间;
dwLength:当前流的长度,其单位由dwScale和dwRate定义;
dwQuality:当前流的数据质量;
dwSampleSize:每一个sample的数据量,0表示可变;
recFrame:指明当前流在整个播放画面中的相对位置;
'strf'为stream format chunk,用于表示当前流中的数据格式;
video流数据格式的信息用BITMAPINFO结构来描述,而audio流数据格式的信息则用WAVEFORMATEX结构来描述;
'strd'为stream-header data chunk,其格式和内容均由编码器驱动程序定义;
'strn' chunk通常包含一些对当前流的描述信息;
— Stream Data('movi' list)
'movi' list中包含的是真正的数据,即视频帧以及音频采样;
数据chunk可以直接放置在movi list中,也可以分组成'rec' list;一个'rec'list中的数据必须一次性整体读取;
每个数据chunk均由一个FOURCC码标识,该FOURCC码的组成为:2字节的stream number+2字节的标识码;
stream number即在stream header中该stream的index;
标识码的可选取值及含义如下:
db — uncompressed video frame
dc — compressed video frame
pc — palette change
wb — audio data
text流可以使用任意2字节码;
比如:如果stream 0包含的是音频数据流,则对应的data chunk的FOURCC码则为'00wb';如果stream 1包含的是视频数据流,则对应的data chunk的FOURCC码则为'01db'或'01dc'
参考链接:
浙公网安备 33010602011771号