avi 文件格式解析

http://blog.sina.com.cn/s/blog_6ca8ed170100qlhw.html

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结构:

  1. ‘LIST’,一个四字符码,表示这是一个列表;
  2. listSize,占用4字节,记录了整个列表的大小;
  3. listType,一个四字符码,表示本列表的具体类型;
  4. listData,实际的列表数据。

CHUNK结构:

  1. ckID,一个表示块类型的四字符码;
  2. ckSize,占用4字节,记录了整个块的大小;
  3. 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(<MainAVIHeader>)  --avi子块开始,本行长度为64字节

         LIST ('strl'  --strl列表,是一个流的列表

             strh(<Stream header>)  --流的信息头,长度为64字节

             strf(<Stream format>)  --流的格式信息子块,描述流中的数据

             .. additional header data  --strd可选的额外的头信息||strn可选的流的名字

                                          )

                                 ...

                        )

      LIST('movi'   --movi列表块,包含流的实际数据,可以是子块,也可以将子块组织成rec列表

             { LIST('rec'  --一个rec列表中的数据应该以此性从磁盘中读出

                      SubChunk...

                       )

            | SubChunk } ....    

          )

      [ <AVIIndex> ]  --索引块

    )

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  表示关键帧

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页