avi 格式解析

分析工具 RiffPad
http://download.csdn.net/detail/codeheng/9793505

AVI:Audio/Video Interleaved(视音频交织),用于采集、编辑、播放的RIFF文件。由Microsoft公司1922年11月推出,用于对抗苹果Quicktime技术,AVI现在还在被广泛使用。
RIFF:Resource Interchange File Format(资源交互文件格式),是由Microsoft提出的一种多媒体文件存储方式,不同编码的视频、音频文件按照RIFF保存,当提取文件时,可以根据RIFF的规则解析文件。常见的RIFF文件有:WAV、AVI等。
RIFF格式是一种树状结构,基本组成单元为LIST和CHUNK:LIST相当于目录,可以包含多个CHUNK或者多个LIST,包含关键字“LIST”。CHUNK是数据保存的基本单元,可用于保存音视频数据或者一些参数信息。RIFF文件结构最开始4个字节表示“RIFF”,接着4个字节表示该文件的大小,再下来的4个字节表示该文件的类型(AVI或者WAV等)。
LIST结构:
‘LIST’,一个四字符码,表示这是一个列表;
listSize,占用4字节,记录了整个列表的大小;
listType,一个四字符码,表示本列表的具体类型;
listData,实际的列表数据。
CHUNK结构:
ckID,一个表示块类型的四字符码;
ckSize,占用4字节,记录了整个块的大小;
ckData,实际的块数据。
AVI是一种最复杂的RIFF文件,现在常用的AVI文件有2种:AVI-1, AVI-2。AVI-1中只包含一个DV数据流,占用较少的存储空间。AVI-2中通常包含一个视频流和一个音频流,只有一个视频流或者音频流也是合法的。
AVI文件格式:一个AVI RIFF文件由以下组成:RIFF文件头、hdrl列表(AVI文件的数据格式)、movi列表(AVI的视音频序列数据),可选索引块。

  • RIFF(‘AVI’ –RIFF文件头,块的数据类型是AVI
    • LIST(‘hdrl’ –hdrl列表
    • avih() –avi子块开始,本行长度为64字节
    • LIST (‘strl’ –strl列表,是一个流的列表
    • strh() –流的信息头,长度为64字节
    • strf() –流的格式信息子块,描述流中的数据
    • .. additional header data –strd可选的额外的头信息||strn可选的流的名字
    • )
    • )
    • LIST(‘movi’ –movi列表块,包含流的实际数据,可以是子块,也可以将子块组织成rec列表
    • { LIST(‘rec’ –一个rec列表中的数据应该以此性从磁盘中读出
    • SubChunk…
    • )
    • | SubChunk } ….
    • )
    • [ ] –索引块
    • )

RIFF(‘AVI’…)
表明AVI文件的格式。

hdrl列表
嵌套了一系列块和子列表,一个avih块,一个或多个strl子列表。
avih块
记录AVI文件的全局信息,使用AVIMAINHEADER数据结构来操作:

typedef struct
{
DWORD dwMicroSecPerFrame; //视频帧显示率,ns
DWORD dwMaxBytesPerSec; // 最大数据传输率
DWORD dwPaddingGranularity;//记录块的长度须为此值的倍数,通常是2048
DWORD dwFlags; // AVI文件的特殊属性,包含文件中的任何标志字。如:有无
//索引块,是否是interlaced,是否含版权信息等
DWORD dwTotalFrames; // 数据帧的总数
DWORD dwInitialFrames; // 在开始播放前需要的帧数
DWORD dwStreams; //文件中包含的数据流种类
DWORD dwSuggestedBufferSize;//建议使用的缓冲区的大小,通常为存储一阵图像以
//及同步声音所需要的数据之和,大于最大的CHUNK的大小
DWORD dwWidth;//图像宽,像素
DWORD dwHeight; //图像高,像素
DWORD dwReserved[4];//保留值dwScale,dwRate,dwStart,dwLength
} MainAVIHeader;

strl子列表
一个strl子列表中至少包含一个strh块和一个strf块。文件中有多少个流,就对应有多少个strl子列表,strl子列表在hdrl中的次序就是流的序号。
strh块说明这个流的头信息,长度为64字节,使用AVISTREAMHEADER数据结构来操作:

typedef struct {
FOURCC fccType;//4个字符,若此流是视频数据,为“vids”,若是音频数据,为
//“auds”
FOURCC fccHandler; //4个字符,描述数据所用编解码算法
DWORD dwFlags; //数据流的属性
WORD wPriority; //此数据流播放的优先级别
WORD wLanguage; //音频的语言代号
DWORD dwInitialFrames; //用于interlaced文件,开始播放前所需帧数
DWORD dwScale; //数据量,视频每帧的大小或者音频的采样大小
DWORD dwRate; //dwRate / dwScale = =samples/second(每秒采样数)
DWORD dwStart; //数据流开始播放的位置,单位:dwScale
DWORD dwLength; //数据流的数据量,单位:dwScale
DWORD dwSuggestedBufferSize; //建议缓冲区的大小
DWORD dwQuality; //解压缩质量参数,值越大,质量越好(0~10000)
DWORD dwSampleSize; //音频的采样大小
RECT rcFrame; //视频数据图像所占的矩形。即这个流在视频主窗口显示的位置。
}AVIStreamHeader;

movi列表
hdrl列表后是movi列表,movi列表中存储流的实际数据,movi列表中数据子块的种类有:##db,##dc,##pc,##wb。

表示数据所属的流的序号;

db:未压缩的视频帧;
dc:压缩的视频帧;
wb:音频数据;
pc;改用新的调色板。(新的调色板使用一个数据结构AVIPALCHANGE来定义。如果一个流的调色办中途可能改变,则应在这个流格式的描述中,也就是AVISTREAMHEADER结构的dwFlags中包含一个AVISF_VIDEO_PALCHANGES标记。)

可选的索引块
movi列表后是AVI文件可选的索引块。这个索引块对AVI文件中每一个媒体数据块进行索引,并且记录它们在文件中的偏移(可能相对于‘movi’列表,也可能相对于AVI文件开头)。索引块使用一个四字符码‘idx1’来表征,索引信息使用一个数据结构来 AVIOLDINDEX定义:
typedef struct _avioldindex {
FOURCC fcc; // 必须为‘idx1’
DWORD cb; // 本数据结构的大小,不包括最初的8个字节(fcc和cb两个域)
struct _avioldindex_entry {
DWORD dwChunkId; // 表征本数据块的四字符码
DWORD dwFlags; // 说明本数据块是不是关键帧、是不是‘rec ’列表等信息
DWORD dwOffset; // 本数据块在文件中的偏移量
DWORD dwSize; // 本数据块的大小
} aIndex[]; // 这是一个数组!为每个媒体数据块都定义一个索引信息
} AVIOLDINDEX;
注意:如果一个AVI文件包含有索引块,则应在主AVI信息头的描述中,也就是AVIMAINHEADER结构的dwFlags中包含一个AVIF_HASINDEX标记。
index flag = 1 表示关键帧

你可能感兴趣的:(嵌入式开发)