文章

Avi

AVI文件格式

RIFF格式:

AVI文件格式的基础是RIFF

RIFF由一个RIFF文件头和一些LIST和CHUNK结构组成。

RIFF文件头=’RIFF’+4byte size+4byte ID(‘ avi’)

LIST=’LIST’+4byte size+4byte ID+(LIST CHUNK)

CHUNK=4byte ID+4byte size+(data)

AVI格式:

AVI文件包含

1avi的riff头

2.一个’hdrl’ LIST

3.一个’movi’ LIST

4可选的’idx1’

主要内容都在hdrl(头信息)和movi(数据)里

‘hdrl’ LIST包括

1一个avih chunk

2若干个 strl LIST(一般有2个,一个音频,一个视频)本段str表示stream

3 其他 chunk

strl LIST包括

strh(stream header)和strf(stream format)和可选的strd

stream format 对于音频和视频的格式不同

对于音频是如下结构

WAVEFORMA WAVEFORMATEX,后者是前者的扩展,这些结构可从MSDN中查到

那么到底用的是什么结构可从strf这个CHUNK的size处获得,如果大于16则是后者

这个部分的解码似乎有些不规整,尤其在尾巴处理上,似乎有垃圾信息的处理?

对于视频则是个BITMAPINFO结构,也可从MSDN中查到

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_1rw2.asp

其中要注意codecid的识别

AVI文件格式

发表:不详 阅读:次 关键字: 字体:[大 中 小]

AVI(Audio/Video Interleaved)文件是MS-Windows的视频文件,其文件扩展名为“.AVI”。它一般由三部分构成:信息区、数据区和索引区(可缺省),即两个LIST快和一个idx1块。这些区域,通常由一些子块组成,它们多用于为播放软件提供更为系统的数据信息;或为播放时进行快速数据定位及播放,并提供详细资料和识别手段(关于“区域”与“子块”具体包容关系请见图6)。

说明:本例由“四部分”构成,即在两个LIST块中间夹了个JUNK块。这个JUNK块纯属人为添加的自定义块,即在AVI文件中从未有对此块的定义。换句话说,我们也可以添加自己的决,只要遵循如下原则:在这三个标准块其中的某个后面,定义一个四字节的块识别码(不要与本文用到的识别码相同,最好字母用大写),紧跟一个长整数来表示你自定义的块的大小,随后便可以在定义的大小范围内写入你想表述的信息。同样,在这三个标准块的内部,也可以用上述方法添加自定义干块。

注:下文的说明内容部分取自华中理工大学出版的<>一文和<>的HELP文件。

以下就是作为例子的文件内容(数据D)及AVI文件标准结构图。

1.从(00000000-000007F3)为一个WindowsAVI文件的信息区部分。

它是文件的第一个LIST块。在它的内部记录着整个文件的系统构成,如告诉播放软件“我是一个AVI文件”;“在我的体内有几个数据流”;“每个数据流包含着什么数据类型——图像、声音或其他”;“如果是图像数据流,那么它的大小、颜色、压缩方式、播放速度等,等是怎样规定的”;“如果是声音数据流,那么它的压缩方式、播放效果等等又将有何规定”……在信息区中还有多个附属的LIST块,也就是我们前面提到的“子块”,它们用来记录每个数据流的全部信息。而这些附间LIST块与数据流之间保持着—一对应的关系,即

第一个附属LIST块对应于00号数据流;第二个附属LIST块对应于01号数据流……要想解释数据流,我们必须先了解AVI文件中数据块是什么。在AVI文件中,数据块是被放置在数据区中的一个有起始标志(由“数据流识别码”和“数据块存储方式识别码”组成,请参见对数据区部分的说明),并指明大小和数据内容的数据段.那么,数据流就是那些相互之间具有联系的同种数据类型的数据块集合.

00000000-00000003 多媒体文件识别码:RIFF

00000004-00000007 文件大小(10EDICh字节)-8字节

00000008-0000000B AVI文件识别码

0000000C-0000000F 第一个LIST块识别码

00000010-00000013 第一个LIST块的大小(168h字节)

00000014-00000017 hdrl部分识别码,以下数据记录着此文件的格式

00000018-0000001B hdrl部分所包含的avih块识别码,此模块记录着本文件的初始化信息

0000001C-0000001F avih块大小(38h字节)

00000020-00000023 每帧画面显示所维持多少个百万分之一秒,本例为1046Bh,即66667百万分之一秒,约0.07秒。所以在播放此文件时,你看到的画面约每秒15帧

AVI文件格式及其应用研究

2009-06-15 23:20

摘要:AVI文件是Windows操作系统下最常用的流媒体文件格式之一,了解AVI文件格式是正确使用AVI文件的基础,以一个具体的AVI文件的二进制码为例,详细解释和研究AVI文件的各个字段的具体含义,并指出AVI-1文件与AVI-2文件格式的区别,在此基础上,可以对AVI文件进行各种编程操作。给出使用VFW(VideoForWindows)用VisualC 编程语言从AVI-2文件中获取视频帧,转换为BMP图像,加以显示并存储为位图文件的编程方法。

  关键词:流媒体文件;VC;AVI;VFW

  中图分类号:TP311.1文献标识码:A文章编号:1004-373X(2008)02-119-04

  

  StudyonAVIFileFormatandItsApplication

  XUDianwu

  (Mechano-ElectronicCollege,ChinaUniversityofPetroleum,Beijing,102249,China)

  Abstract:UnderWindowsenvironment,AVIisapopularstreammediaformat.ToworkwithAVIfile,itisthebasictoknowaboutAVIfileformat.Inthispaper,theexampleofAVIfilebinarycodeispresentedinbinarycode,toillustrateeverychunkinthefile.TheformatofAVIfiles,andespeciallythedifferencebetweenAVI-1andAVI-2formatisdiscussed.ProgrammingmethodforpickupvideosfromanAVIfileandsaveitasBMPfilesinVisualC ispresented.

  Keywords:streammediumfile;VC;AVI;VFW

  

  1引言

  

  自微软公司推出AVI文件格式以来,AVI逐渐成为Windows操作系统上最常用的流媒体文件格式之一[1]。AVI是视频数据和音频数据交叉编码(AudioVideoInterleaved)的一种RIFF文件,其多用于音视频捕捉、编辑、播放等,其文件名后缀为.avi。应用程序的开发者在编写多媒体处理软件时,除要对AVI文件进行播放、编辑、制作外,也经常需要从一个AVI文件中提取一视频帧并存储为BMP图像文件,这些都需要对AVI文件格式有深入了解,本文在对AVI文件格式进行解析的基础上,给出了从AVI文件中获取位图的程序设计方法。这里介绍的AVI文件格式不包括OpenDMLAVIM-JPEG文件格式分委员会制定的内容以及nAVI(一种改进的ASF格式)的内容。

  

  2RIFF文件格式简介

  

  RIFF(ResourceInterchangeFileFormat)文件格式是一个信息交换框架[1],AVI文件格式是以RIFF为基础的,所以在很多文献中,AVI文件又被称为AVIRIFF文件[2]。

  RIFF文件组成的基本单元叫作“块”(chunk),使用FOURCC码(FourCharacterCode,4字符码,Windows中的数据类型为FOURCC)来标识文件中的每个块。FOURCC是由4个ASCII码组成的一个DWORD型数据,高字节在后,如4字符abcd的FOURCC码是0X64636261。RIFF就是一个FOURCC,表示这是一个RIFF块。在一个RIFF文件中,除RIFF块和LIST块可以包含子块(SubChunk)外,其他任何块均不可以包含子块。

  块的格式分为2种,可以包含子块的块(RIFF,LIST)的格式为:FOURCC、块长度(4字节,DWORD类型,长度不包括FOURCC和块长度占用的8个字节)、块数据类型、块数据。不可以包含子块的块的格式是:FOURCC、块长度、块数据,没有块数据类型部分。

  

  3AVI文件格式

  

  AVI文件是一种最复杂的RIFF文件。现在常用的AVI文件有2种:AVI-1和AVI-2。在AVI-2文件中,通常包含2个流,一个视频流和一个音频流(被称为标准AVI格式),但只有一个视频流或音频流也是合法的。在AVI-1文件中只包含一个DV(digitalVideo)数据流(视频采集设备的输出数据,其中既有视频信息也有音频信息),在文件中以单个流的形式存在,其主要优点是占用较少的存储空间,对AVI-1的支持主要来自DirectShow中的DVMuxer和DVSplitter筛选器(Filter)[2]。虽然目前AVI-2仍然是最常使用的格式,但AVI-1由于其自身的优点和受到微软最新技术的支持,将来可能会比AVI-2更流行。虽然这2种AVI文件不兼容,但他们都以RIFF格式为基础,除了实际的流数据格式不同以外,差别主要存在于文件的strh块和strf块。

  下面为AVI文件的格式,左边小括号处省略了4字节的文件大小或列表大小或块大小,凡FOURCC都用4个字母表示,除RIFF和LIST外,所有的4字符码都用单引号括起来,方括号表示可选:

1
   /*   RIFF文件头 */  

  RIFF(′AVI◇′[JY]//RIFF文件头,块的数据类型是AVI,

1
  /* hdrl列表 */

  LIST(′hdrl′[JY]//列表,列表中的数据类型是hdrl,

  [JY]下面紧跟avih子块。

  ′avih′(AVI文件的全局信息,本行构成一个AVIMAINHEADER结构,长度为64个字节)。

1
   /* strl 列表 */

  LIST(′strl′[JY]//strl列表,表示本列表是一个流的列表,

  [JY]其后紧跟strh子块。

  ′strh′([JY]//流的头信息,本行构成一个AVISTREAMHEADER

  [JY]结构,长度为64字节)

  ′strf′([JY]//流的格式信息子块,描述流中数据的格式。)

  [′strd′([JY]//附加的流头数据,一般为

  [JY]编解码器驱动程序所定义)]

  [′strn′(以0结束的字符串,流的名字)]

  …

  )

  …

  )[JY]//hdrl列表块到此结束

  /* movi列表 */

1
   LIST(′movi′[JY]//movi列表块,包含了流的实际数据, 

  [JY]数据可以是子块,也可以将子块组织成rec列表,

  [JY]一个rec列表中的数据应该一次性地从磁盘读出。

  {SubChunk LIST(′rec′

  SubChunk1

  SubChunk2

  …

  )

  …

  }

  …

  )//movi列表块到此结束

  [′idx1′(索引块)]

  [newpage]  )//RIFF块到此结束,这就是一个完整的AVIRIFF文件

  从上面的格式可以看出,一个AVIRIFF文件由3大部分组成:RIFF文件头;hdrl列表;movi列表。其中hdrl列表包含avih子块和strl子列表,文件中有多少个流,hdrl列表中就有多少个strl子列表,strl子列表在hdrl中的次序就是流的序号(隐含)。

  strl子列表由strh子块、strf子块、strd子块(可选)、strn子块(可选)构成。

1
2
3
4
5
    movi列表中存储的是流的实际数据,movi列表中数据子块的种类有:##db,##dc,##pc,##wb,其中##表示数据所属的流的序号,如00db,01dc。



    db表示未压缩的视频帧;dc表示压缩的视频帧;wb表示音频数据;pc表示调色板变化,其后的数据是一个AVIPALCHANGE结构,此时strh中的dwFlages字段必须置为AVISF_VIDEO_PALCHANGES。

  movi列表最后可以有一个可选的索引块(idxl),他指出流的数据在文件中的位置,以便于对数据进行随机访问。一个AVIRIFF文件如果有索引块,则将AVIMAINHEADER结构中的dwFlags字段置为AVIF_HASINDEX。AVI文件中的JUNK块为数据对齐而存在,应用程序应该忽略JUNK块的内容。

  AVI-1中只有一个流(DVdatastream),其AVISTREAMHEADER(strh块)中的fccType字段是4字符码′iavs′,fccHandler字段是′dvsd′,′dvhd′,′dvsl′三者之一(分别对应3种DV格式),strl子列表中的strf块是DVINFO结构(32字节)。AVI-2中一般有2个流,视频流的AVISTREAMHEADER(strh块)中的fccType字段是4字符码′vids′(也可以是′dvsd′,′dvhd′,′dvsl′三者之一)[2],音频流的4字符码是′auds′,其视频流的strl子列表中的strf块是BITMAPINFOHEADER结构(40字节),其后可以跟随DVINFO结构。AVI-2中音频流的strf块是WAVEFORMATEX结构。

  AVIRIFF文件格式只规定了文件的组成方式,即各种数据如何在文件中排列等,对于文件中的数据并没有做出编码格式的约束,如MPEG-1、DivX等都可以作为文件中数据的编码格式。数据也可以未经压缩。AVI文件可以看成是一个数据容器,AVI格式只规定了将数据装入这个容器的方法,但对数据本身的编码格式并不涉及。要操作一个AVI文件(播放、抓图、编辑),必须在系统中安装与该AVI文件中的编码器对应的解码器,才能进行正确的工作。

  

  4AVI-2文件格式的例

  

  下面以AVI文件bfh.avi(风景介绍片)为例,将该AVI文件打开,逐字节解释其中的数据(见图1):

  52494646是RIFF的ASCII码;7E443400是文件长度,高位字节在后,(0034447E) 16,(3425406) 10;41564920是AVI◇的ASCII码,◇表示空格;表示RIFF块(文件)的数据类型是AVI。4C495354是LIST的ASCII码,表示这是一个列表。10h开始的4字节表示本列表长度,(132) 16,(306) 10。接着6864726C是hdrl的ASCII码,表明这是hdrl列表,61766968是avih的ASCII码,表明这是hdrl列表中的avih块,第二行最后4字节是16进制的38,十进制的56;表示avih块的长度是56个字节(加上8正好是AVIMAINHEADER结构的长度),接下来的56个字节就是avih的内容,描述AVI文件的整体信息,AVIMAINHEADER结构中各个字段的内容不再分析,avih块到057h结束。

  从0058h开始的4C495354是LIST的ASCII码,其后4字节(74) 16,即(116) 10是本列表的大小。60h开始的7374726C是strl的ASCII码,表示这是strl(流)列表,从64h到a3h的64个字节是一个AVISTREAMHEADER结构;64h开始的73747268是strh的ASCII码,表示这是strl列表中strh块(流的头信息);下面的4字节是strh块的大小(38) 16,十进制的56,76696473是vids的ASCII码,是流的类型,表示这是一个视频流,从上面对AVI的2种格式的分析可知,这是一个AVI-2文件,如果是AVI-1文件,此处应该是iavs的ASCII码。70h开始的4字节是′MSVC′(已经注册的解码器的4字符码)的ASCII码4D535643,AVISTREAMHEADER结构其他字段不再罗列,90h这一行最后4个字节,表示显示窗口左上角 x,y, 其值为0,0。a0h开始的2字节是窗口显示的右下角 x 坐标,值为十进制的128,以象素为单位,再2字节是右下角 y 坐标,十进制的112,至此,AVISTREAMHEADER结束。

  a4h开始的4字节是strf的ASCII码73747266,后跟的4字节(28) 16,(40) 10是strf块的长度,前面说过,在AVI-2中,如果是视频流,strf就是一个BITMAPINFOHEADER结构,而该结构的长度是40字节,再后的4字节(28) 16,就是BITMAPINFOHEADER的第一个字段,指明该结构的长度,所以有2个(28) 16相连。从boh开始,就是BITMAPINFOHEADER其余的内容,(80) 16是图像的宽度,120象素。(70) 16是图像的高度,112象素,这些都与前面的信息相符合。0001两字节是位平面数,(0018) 16是每象素比特数(24位)。接下来4字节44495633是′DIV3′(压缩编码格式的四字符码)的ASCII码,是BITMAPINFOHEADER的biCompression域的值,指压缩方式,这是和普通的BMP文件不同的。后面的字段不再分析。值得指出的是,这里可以后跟一个DVINFO结构(可选),如果是AVI-1文件,这里用DVINFO结构取代BITMAPINFOHEADER结构。接下来的4C495344是LIST的ASCII码,表明下面又是一个列表,列表大小是6Ah,doh行最后4字节是strl的ASCII码,表明这是一个“流”列表。后面的数据不再分析。

  

  5从AVI文件中提取位图

  

  Windows提供的VFW和DirectShow[3]都可以处理和操作AVI文件,考虑到VFW为大多数程序员所熟悉以及AVI-2仍然是最常使用的AVI文件格式,下面给出使用VFW从AVI-2文件中提取视频帧加以显示并存储为BMP位图文件的程序。

  VFW提供的AVIFile动态链接库使用OLE技术实现,在AVIFile中的API函数将AVI文件中的数据当作“流”来处理,而不必逐一地寻找其中的块(chunk)。使用该库要首先调用函数AVIFileInit来初始化,使用完毕调用函数AVIFileExit后释放。首先使用MFCAppWizard创建一个名为avi的单文档项目,然后重载CDocument类的虚函数OnOpenDocument,在此函数中打开AVI文件,读出其中的视频帧,存储为BMP文件并在屏幕上加以显示(在VC 6.0中调试通过):

  [newpage]  

  BOOLCAviDoc::OnOpenDocument(LPCTSTRlpszPathName)

  {if(!CDocument::OnOpenDocument(lpszPathName))returnFALSE;

  AVIFileInit();[JY]//初始化

  AVIFileOpen(&pAviFile,lpszPathName,OF_SHARE_DENY_WRITE,0l);[JY]//打开AVI文件

  AVIFileGetStream(pAviFile,&pAviStream,streamtypeVIDEO,0L);[JY]//打开流

  AVIStreamInfo(pAviStream,&aviStrInfo,sizeof(AVISTREAMINFO));[JY]//获取流的信息

  longlStreamSize;[JY]//流格式长度

  pBmpInfoH=newBITMAPINFOHEADER;[JY]//pBmpInfoH是文档类的成员变量

  AVIStreamFormatSize(pAviStream,0,&lStreamSize);[JY]//获取流的格式信息的长度

  AVIStreamReadFormat(pAviStream,0L,pBmpInfoH,&lStreamSize);

  PGETpgf;

  pgf=AVIStreamGetOpen(pAviStream,NULL);[JY]//为解压帧做准备

  [JY]//解压读出第0帧,紧缩DIB的数据以返回值pData为起始地址

  pData=(LPBYTE)AVIStreamGet(pgf,0L);[JY]//文档类的成员变量,类型为LPBYTE

  pBmpInfoH->biCompression=0;

  BITMAPFILEHEADERbmpFH;[JY]//位图文件头

  bmpFH.bfType=0x4d42;

  bmpFH.bfSize=bmpInfoH.biWidthbmpInfoH.biHeight3 54;

  bmpFH.bfReserved1=0;bmpFH.bfReserved2=0;

  bmpFH.bfOffBits=54;

  CFileDialogdlg(FALSE);[JY]//获取用户要存储成的位图文件名和路径

  if(IDOK==dlg.DoModal())str.Format(“s”,dlg.GetPathName());

  CFilebmp(str,C:modeWrite C:modeCreate);

  bmp.Write(&bmpFH,sizeof(BITMAPFILEHEADER));[JY]//写入位图文件头

  bmp.WriteHuge(pData,bmpFH.bfSize-14);[JY]//写入紧缩DIB

  bmp.Close();AVIFileExit();

  UpdateAllViews(NULL);[JY]//更新视图,在视图类的OnDraw函数中显示位图

  returnTRUE;

  }//程序中省略所有安全性检查语句。位图的显示在视类的OnDraw函数(略)中。

  图2是程序执行的结果:从bfh.avi中提取的第0帧转换成的位图的显示。

  上面程序中pAviFile,pAviStream,aviStrInfo都是文档类的成员变量,类型分别为PAVIFILE,PAVISTREAM,AVISTREAMINFO。在文档类的构造函数中将所有指针初始化为NULL。还可以循环调用函数AVIStreamFindNextKey寻找所有的关键帧加以显示并存储为BMP文件。需要注意,函数AVIStreamGet返回的是一个“紧缩DIB”的地址,即以一个位图的BITMAPINFOHEADER开始的地址,且所需的缓冲区由该函数自己开辟,不需应用程序动态申请。程序要加入#i nclude,且在Project->Settings->Link中键入vfw32.lib。

  

  6结语

  

  由于Windows是很流行的操作系统,AVI是Microsoft公司大力支持的格式,因此在编写基于Windows操作系统的流媒体图像处理程序方面,AVI占有不可替代的位置。准确理解AVI文件格式以及针对AVI文件的编程方法在工程实践中具有重要的意义。AVI-1文件格式由于占用存储空间小,受到DirectShow的支持,其将来会成为AVI文件中最流行的格式。

  

  参考文献

  [1]姜楠,王健.常用多媒体文件格式压缩标准解析[M].北京:电子工业出版社,2005.

  [2]DirectXDocumentationforC [EB/OL].MicrosoftCorporation,2005.

  [3]陆其明.DirectShow开发指南[M].北京:清华大学出版社,2003.

  

  注:本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。

  (作者:徐殿武-字数:3302)

本文由作者按照 CC BY 4.0 进行授权