AVI文件格式

RIFF文件格式:(T420 rw1)


RIFF文件首先含有一个如下的文件头结构.
 R I F F    文件大小     文件类型     数据
|-4字节-|    4字节         4字节        ...


//最开始的4字节是一个四字符码'RIFF',表示这是一个RIFF文件,紧跟着后面用4个字节表示此RIFF文件的大小 
//然后又是一个四字符码说明文件的具体类型(比如 AVI WAVE);最后就是实际的数据;
//文件大小的值不包括 'RIFF'域 和 '文件大小'域本身的大小.


RIFF文件的实际数据中,通常还使用了列表(List)和块(Chunk)的形式来组织.列表可以嵌套子列表和块.


列表的结构为:'LIST' listSize listType listData 
    'LIST'是一个四字符码,表示这是一个列表;
    'listSize'占用了4字节,记录了整个列表的大小;
    'listType'也是一个四字符码,表示本列表的具体类型;
    'listData'就是实际的列表数据;
        listSize:不包括'LIST'域和listSize域本身的大小


宏块的结构为:ckID ckSize ckData
    'ckID'是一个表示块类型的四字符码;
    'ckSize'占用4个字节,记录整个块的大小;
    'ckData'为实际的块数据;
        ckSize:不包括ckID域和ckSize域本身的大小.
    
AVI文件格式:    
    AVI文件类型用一个四字符码'AVI'来表示.
    整个AVI文件的结构为:一个RIFF头 + 两个列表(一个用于描述媒体流格式,一个用于保存媒体流数据) + 一个可选的索引块.
    
    首先,RIFF('AVI' ...)表征了AVI文件类型,然后就是AVI文件必需的第一个列表 ===> 'hdrl'列表,用于描述AVI
    文件中各个流的格式信息(AVI文件中的每一路媒体数据都称为一个流). 'hdrl'列表嵌套了一系列块和子列表,
    首先是一个'avih'块,用于记录AVI文件的全局信息,比如流的数量,视频图像的宽和高等,
    可以使用一个AVIMAINHEADER数据结构来描述:
    
    typedef struct _avimainheader {
        FOURCC fcc;   // 必须为‘avih’
        DWORD  cb;    // 本数据结构的大小,不包括最初的8个字节(fcc和cb两个域)
        DWORD  dwMicroSecPerFrame;   // 视频帧间隔时间(以毫秒为单位)
        DWORD  dwMaxBytesPerSec;     // 这个AVI文件的最大数据率
        DWORD  dwPaddingGranularity; // 数据填充的粒度
        DWORD  dwFlags;         // AVI文件的全局标记,比如是否含有索引块等
        DWORD  dwTotalFrames;   // 总帧数
        DWORD  dwInitialFrames; // 为交互格式指定初始帧数(非交互格式应该指定为0)
        DWORD  dwStreams;       // 本文件包含的流的个数
        DWORD  dwSuggestedBufferSize; // 建议读取本文件的缓存大小(应能容纳最大的块)
        DWORD  dwWidth;         // 视频图像的宽(以像素为单位)
        DWORD  dwHeight;        // 视频图像的高(以像素为单位)
        DWORD  dwReserved[4];   // 保留
    } AVIMAINHEADER;
    
    然后,就是一个或多个'str1'子列表,每个'str1'子列表至少包含一个'strh'块和一个'strf'块,
    而'strd'块(保存编解码器需要的一些配置信息)和'strn'块(保存流的名字)是可选的.
    
    首先是'strh'块,用于说明这个流的头信息,可以使用一个AVISTREAMHEADER数据结构来操作:
    
    typedef struct _avistreamheader {
         FOURCC fcc;  // 必须为‘strh’
         DWORD  cb;   // 本数据结构的大小,不包括最初的8个字节(fcc和cb两个域)
    FOURCC fccType;    // 流的类型:‘auds’(音频流)、‘vids’(视频流)、
                       //‘mids’(MIDI流)、‘txts’(文字流)
         FOURCC fccHandler; // 指定流的处理者,对于音视频来说就是解码器
         DWORD  dwFlags;    // 标记:是否允许这个流输出?调色板是否变化?
         WORD   wPriority;  // 流的优先级(当有多个相同类型的流时优先级最高的为默认流)
         WORD   wLanguage;
         DWORD  dwInitialFrames; // 为交互格式指定初始帧数
         DWORD  dwScale;   // 这个流使用的时间尺度
         DWORD  dwRate;
         DWORD  dwStart;   // 流的开始时间
         DWORD  dwLength;  // 流的长度(单位与dwScale和dwRate的定义有关)
         DWORD  dwSuggestedBufferSize; // 读取这个流数据建议使用的缓存大小
         DWORD  dwQuality;    // 流数据的质量指标(0 ~ 10,000)
         DWORD  dwSampleSize; // Sample的大小
         struct {
             short int left;
             short int top;
             short int right;
             short int bottom;
    }  rcFrame;  // 指定这个流(视频流或文字流)在视频主窗口中的显示位置
                 // 视频主窗口由AVIMAINHEADER结构中的dwWidth和dwHeight决定
} AVISTREAMHEADER;
    
然后是'strf'块,用于说明流的具体格式.如果是视频流,则使用一个BITMAPINFO数据结构来描述;
如果是音频流,则使用一个WAVEFORMATEX数据结构来描述.


//BITMAPINFO =======> BITMAPINFO数据结构
typedef struct tagBITMAPINFO {
  BITMAPINFOHEADER bmiHeader;
  RGBQUAD          bmiColors[1];
} BITMAPINFO, *PBITMAPINFO;


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, *PBITMAPINFOHEADER;


typedef struct tagRGBQUAD {
  BYTE rgbBlue;
  BYTE rgbGreen;
  BYTE rgbRed;
  BYTE rgbReserved;
} RGBQUAD;


//WAVEFORMATEX结构体:
typedef struct {
  WORD wFormatTag; 
  WORD nChannels; 
  DWORD nSamplesPerSec; 
  DWORD nAvgBytesPerSec; 
  WORD nBlockAlign; 
  WORD wBitsPerSample; 
  WORD cbSize;} 
WAVEFORMATEX; 




随后跟着的是AVI文件必需的第二个列表-- 'movi'列表,用于保存直正的媒体流数据,可以将数据
直接嵌在'movi'列表,也可以将几个数据块分组成一个'rec'列表后再编排进'movi'列表.流数据块
之间区别,数据块使用了一个四字符码来表征它的类型,这个四字符码由2个字节的类型码和2个字节
的流编号组成.


标准类型码:'db'(非压缩视频帧) 'dc'(压缩视频帧) 'pc'(改用新产调色板) 'wb'(音频)
0x00wb 0x00db 0x00dc 0xxxpc:调色板 新的调色板使用一个数据结构AVIPALCHANGE来定义.


最后紧跟在'hdrl'列表和'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结构中包含一个AVIF_HASINDEX标记.




RIFF    AVIsize     'AVI '
LIST    LISTsize    'hdrl'  avih块
    .......................................................................
    .LIST    LISTsize    'strl'                                           .              
    .    strh块  strf块  strd块(可能有可能没有)  strn块(可能有可能没有)     .
    ....................................................................... 
    
    ....重复上述框中的内容(个数不确定)....
    
LIST    LISTsize    'movi'  data


idx1索引块

 

 

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>) ]
         )

 

typedef struct

{

FOURCC ckid; //记录数据块中子块的标记

DWORD dwFlags; //表示chid所指子块的属性

DWORD dwChunkOffset; //子块的相对位置

DWORD dwChunkLength; //子块长度

}INDEXHEADER;

 

typedef struct _avioldindex {
   FOURCC  fcc;
   DWORD   cb;
   struct _avioldindex_entry {
      DWORD   dwChunkId;
      DWORD   dwFlags;
      DWORD   dwOffset;
      DWORD   dwSize;
  } aIndex[];
} AVIOLDINDEX;

Members

fcc

Specifies a FOURCC code. The value must be 'idx1'.

cb

Specifies the size of the structure, not including the initial 8 bytes.

dwChunkId

Specifies a FOURCC that identifies a stream in the AVI file. The FOURCC must have the form 'xxyy' where xx is the stream number and yy is a two-character code that identifies the contents of the stream:

Two-character codeDescription
dbUncompressed video frame
dcCompressed video frame
pcPalette change
wbAudio data

dwFlags

Specifies a bitwise combination of zero or more of the following flags:

ValueDescription
AVIIF_KEYFRAMEThe data chunk is a key frame.
AVIIF_LISTThe data chunk is a 'rec ' list.
AVIIF_NO_TIMEThe data chunk does not affect the timing of the stream. For example, this flag should be set for palette changes.

dwOffset

Specifies the location of the data chunk in the file. The value should be specified as an offset, in bytes, from the start of the 'movi' list; however, in some AVI files it is given as an offset from the start of the file.

dwSize

Specifies the size of the data chunk, in bytes.

Remarks

This structure consists of the initial RIFF chunk (the fcc and cb members) followed by one index entry for each data chunk in the 'movi' list.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值