正文

AVI2010-06-22 14:25:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/niao0311/51385.html

分享到:

它于1992年被Microsoft公司推出,随Windows3.1一起被人们所认识和熟知。所谓“音频视频交错”,就是可以将视频和音频交织在一起进行同步播放。这种视频格式的优点是图像质量好,可以跨多个平台使用,其缺点是体积过于庞大,而且更加糟糕的是压缩标准不统一,最普遍的现象就是高版本Windows媒体播放器播放不了采用早期编码编辑的AVI格式视频,而低版本Windows媒体播放器又播放不了采用最新编码编辑的AVI格式视频,所以我们在进行一些AVI格式的视频播放时常会出现由于视频编码问题而造成的视频不能播放或即使能够播放,但存在不能调节播放进度和播放时只有声音没有图像等一些莫名其妙的问题,如果用户在进行AVI格式的视频播放时遇到了这些问题,可以通过下载相应的解码器来解决。是目前视频文件的主流。 这种格式的文件随处可见,比如一些游戏、教育软件的片头,多媒体光盘中,都会有不少的AVI 。

  现在,在WINDOWS 95或98里都能直接播放AVI,而且它自己的格式也有好几种,最常见的有 Intel Indeo(R)Video R3.2、Microsoft video 等。
  avi含三部分:文件头、数据块和索引块。
  其中数据块包含实际数据流,即图像和声音序列数据。这是文件的主体,也是决定文件容量的主要部分。视频文件的大小等于该文件的数据率乘以该视频播放的时间长度,索引块包括数据块列表和它们在文件中的位置,以提供文件内数据随机存取能力。文件头包括文件的通用信息,定义数据格式,所用的压缩算法等参数。
  nAVI格式
  nAVI是newAVI的缩写,是一个名为ShadowRealm的地下组织发展起来的一种新视频格式(与我们上面所说的AVI 格式没有太大联系)。它是由Microsoft ASF压缩算法的修改而来的,但是又与下面介绍的网络影像视频中的ASF视频格式有所区别,它以牺牲原有ASF视频文件视频“流”特性为代价而通过增加帧率来大幅提高ASF视频文件的清晰度。
  DV-AVI格式
  DV的英文全称是Digital Video Format,是由索尼、松下、JVC等多家厂商联合提出的一种家用数字视频格式。目前非常流行的数码摄像机就是使用这种格式记录视频数据的。它可以通过电脑的IEEE 1394端口传输视频数据到电脑,也可以将电脑中编辑好的的视频数据回录到数码摄像机中。这种视频格式的文件扩展名一般是.avi,所以也叫DV-AVI 格式。
  目前(07年10月)AVI图象反转的原因很可能是暴风影音和windows media player冲突,下载一个完整的DIVX解码器可以解决。
  1992年初Microsoft公司推出了AVI技术及其应用软件VFW(Video for Windows)。在AVI文件中,运动图像和伴音数据是以交织的方式存储,并独立于硬件设备。这种按交替方式组织音频和视像数据的方式可使得读取视频数据流时能更有效地从存储媒介得到连续的信息。构成一个AVI文件的主要参数包括视像参数、伴音参数和压缩参数等:
  AVI没有MPEG这么复杂,从WIN3.1时代,它就已经面世了。它最直接的优点就是兼容好、调用方便而且图象质量好,因此也常常与DVD相并称。但它的缺点也是十分明显的:体积大。也是因为这一点,我们才看到了MPEG-1MPEG-4的诞生。2小时影像的AVI文件的体积与MPEG-2相差无计,不过这只是针对标准分辨率而言的:根据不同的应用要求,AVI的分辨率可以随意调。窗口越大,文件的数据量也就越大。降低分辨率可以大幅减低它的体积,但图象质量就必然受损。与MPEG-2格式文件体积差不多的情况下,AVI格式的视频质量相对而言要差不少,但制作起来对电脑的配置要求不高,经常有人先录制好了AVI格式的视频,再转换为其他格式。

参数

  视像参数
  1、视窗尺寸(Video size):根据不同的应用要求,AVI的视窗大小或分辨率可按4:3的比例或随意调整:大到全屏720×576,小到160×120甚至更低。窗口越大,视频文件的数据量越大。
  2、帧率(Frames per second):帧率也可以调整,而且与数据量成正比。不同的帧率会产生不同的画面连续效果。
  伴音参数
  在AVI文件中,视像和伴音是分别存储的,因此可以把一段视频中的视像与另一段视频中的伴音组合在一起。AVI 文件与WAV文件密切相关,因为WAV文件是AVI文件中伴音信号的来源。伴音的基本参数也即WAV文件格式的参数,除此以外,AVI文件还包括与音频有关的其他参数:
  1、视像与伴音的交织参数(Interlace Audio Every X Frames)AVI格式中每X帧交织存储的音频信号,也即伴音和视像交替的频率X是可调参数,X的最小值是一帧,即每个视频帧与音频数据交织组织,这是CD-ROM上使用的默认值。交织参数越小,回放AVI文件时读到内存中的数据流越少,回放越容易连续。因此,如果AVI文件的存储平台的数据传输率较大,则交错参数可设置得高一些。当AVI文件存储在硬盘上时,也即从硬盘上读AVI文件进行播放时,可以使用大一些的交织频率,如几帧,甚至1秒。
  2、同步控制(Synchronization)
  在AVI文件中,视像和伴音是同步得很好的。但在MPC中回放AVI文件时则有可能出现视像和伴音不同步的现象。
  压缩参数
  
在采集原始模拟视频时可以用不压缩的方式,这样可以获得最优秀的图像质量。编辑后应根据应用环境选择合适的压缩参数。

数字视频

  AVI及其播放器VFW已成为了PC机上最常用的视频数据格式,是由于其具有如下的一些显著特点:
  一、提供无硬件视频回放功能
  AVI格式和VFW软件虽然是为当前的MPC设计的,但它也可以不断提高以适应MPC的发展。根据AVI格式的参数,其视窗的大小和帧率可以根据播放环境的硬件能力和处理速度进行调整。在低档MPC机上或在网络上播放时,VFW的视窗可以很小,色彩数和帧率可以很低;而在Pentium级系统上,对于64K色、320×240的压缩视频数据可实现每秒25帧的回放速率。这样,VFW就可以适用于不同的硬件平台,使用户可以在普通的MPC上进行数字视频信息的编辑和重放,而不需要昂贵的专门硬件设备。
  二、实现同步控制和实时播放
  
通过同步控制参数,AVI可以通过自调整来适应重放环境,如果MPC的处理能力不够高,而AVI文件的数据率又较大,在WINDOWS环境下播放该AVI文件时,播放器可以通过丢掉某些帧,调整AVI的实际播放数据率来达到视频、音频同步的效果。
  三、可以高效地播放存储在硬盘和光盘上的AVI文件
  由于AVI数据的交叉存储,VFW播放AVI数据时只需占用有限的内存空间,因为播放程序可以一边读取硬盘或光盘上的视频数据一边播放,而无需预先把容量很大的视频数据加载到内存中。在播放AVI视频数据时,只需在指定的时间内访问少量的视频图像和部分音频数据。这种方式不仅可以提高系统的工作效率,同时也可以实现迅速地加载和快速地启动播放程序,减少播放AVI视频数据时用户的等待时间。
  四、提供了开放的AVI数字视频文件结构
  AVI文件结构不仅解决了音频和视频的同步问题,而且具有通用和开放的特点。它可以在任何Windows环境下工作,而且还具有扩展环境的功能。用户可以开发自己的AVI视频文件,在Windows环境下可随时调用。
  五、AVI文件可以再编辑
  AVI一般采用帧内有损压缩,可以用一般的视频编辑软件如Adobe Premiere或MediaStudio进行再编辑和处理。

AVI文件的展开结构

  AVI(Audio Video Interleaved的缩写)是一种RIFF(Resource Interchange File Format的缩写)文件格式,多用于音视频捕捉、编辑、回放等应用程序中。通常情况下,一个AVI文件可以包含多个不同类型的媒体流(典型的情况下有一个音频流和一个视频流),不过含有单一音频流或单一视频流的AVI文件也是合法的。AVI可以算是Windows操作系统上最基本的、也是最常用的一种媒体文件格式。
  先来介绍RIFF文件格式。RIFF文件使用四字符码FOURCC(four-character code)来表征数据类型,比如‘RIFF’、‘AVI ’、‘LIST’等。注意,Windows操作系统使用的字节顺序是little-endian,因此一个四字符码‘abcd’实际的DWORD值应为0x64636261。另外,四字符码中像‘AVI ’一样含有空格也是合法的。
  最开始的4个字节是一个四字符码‘RIFF’,表示这是一个RIFF文件;紧跟着后面用4个字节表示此RIFF文件的大小;然后又是一个四字符码说明文件的具体类型(比如AVI、WAVE等);最后就是实际的数据。注意文件大小值的计算方法为:实际数据长度 + 4(文件类型域的大小);也就是说,文件大小的值不包括‘RIFF’域和“文件大小”域本身的大小。
  RIFF文件的实际数据中,通常还使用了列表(List)和块(Chunk)的形式来组织。列表可以嵌套子列表和块。其中,列表的结构为:‘LIST’ listSize listType listData ——‘LIST’是一个四字符码,表示这是一个列表;listSize占用4字节,记录了整个列表的大小;listType也是一个四字符码,表示本列表的具体类型;listData就是实际的列表数据。注意listSize值的计算方法为:实际的列表数据长度 + 4(listType域的大小);也就是说listSize值不包括‘LIST’域和listSize域本身的大小。再来看块的结构:ckID ckSize ckData ——ckID是一个表示块类型的四字符码;ckSize占用4字节,记录了整个块的大小;ckData为实际的块数据。注意ckSize值指的是实际的块数据长度,而不包括ckID域和ckSize域本身的大小。(注意:在下面的内容中,将以LIST ( listType ( listData ) )的形式来表示一个列表,以ckID ( ckData )的形式来表示一个块,如[ optional element ]中括号中的元素表示为可选项。)
  接下来介绍AVI文件格式。AVI文件类型用一个四字符码‘AVI ’来表示。整个AVI文件的结构为:一个RIFF头 + 两个列表(一个用于描述媒体流格式、一个用于保存媒体流数据) + 一个可选的索引块。AVI文件的展开结构大致如下:
  /*
  * heres the general layout of an AVI riff file (new format)
  *
  * RIFF (3F??????) AVI <- not more than 1 GB in size
  * LIST (size) hdrl
  * avih (0038)
  * LIST (size) strl
  * strh (0038)
  * strf (????)
  * indx (3ff8) <- size may vary, should be sector sized
  * LIST (size) strl
  * strh (0038)
  * strf (????)
  * indx (3ff8) <- size may vary, should be sector sized
  * LIST (size) odml
  * dmlh (????)
  * JUNK (size) <- fill to align to sector - 12
  * LIST (7f??????) movi <- aligned on sector - 12
  * 00dc (size) <- sector aligned
  * 01wb (size) <- sector aligned
  * ix00 (size) <- sector aligned
  * idx1 (00??????) <- sector aligned
  * RIFF (7F??????) AVIX
  * JUNK (size) <- fill to align to sector -12
  * LIST (size) movi
  * 00dc (size) <- sector aligned
  * RIFF (7F??????) AVIX <- not more than 2GB in size
  * JUNK (size) <- fill to align to sector - 12
  * LIST (size) movi
  * 00dc (size) <- sector aligned
  *
  *-===================================================================*/
  首先,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;
  然后,就是一个或多个‘strl’子列表。(文件中有多少个流,这里就对应有多少个‘strl’子列表。)每个‘strl’子列表至少包含一个‘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数据结构来描述。
  当AVI文件中的所有流都使用一个‘strl’子列表说明了以后(注意:‘strl’子列表出现的顺序与媒体流的编号是对应的,比如第一个‘strl’子列表说明的是第一个流(Stream 0),第二个‘strl’子列表说明的是第二个流(Stream 1),以此类推),‘hdrl’列表的任务也就完成了,随后跟着的就是AVI文件必需的第二个列表——‘movi’列表,用于保存真正的媒体流数据(视频图像帧数据或音频采样数据等)。那么,怎么来组织这些数据呢?可以将数据块直接嵌在‘movi’列表里面,也可以将几个数据块分组成一个‘rec ’列表后再编排进‘movi’列表。(注意:在读取AVI文件内容时,建议将一个‘rec ’列表中的所有数据块一次性读出。)但是,当AVI文件中包含有多个流的时候,数据块与数据块之间如何来区别呢?于是数据块使用了一个四字符码来表征它的类型,这个四字符码由2个字节的类型码和2个字节的流编号组成。标准的类型码定义如下:‘db’(非压缩视频帧)、‘dc’(压缩视频帧)、‘pc’(改用新的调色板)、‘wb’(音缩视频)。比如第一个流(Stream 0)是音频,则表征音频数据块的四字符码为‘00wb’;第二个流(Stream 1)是视频,则表征视频数据块的四字符码为‘01db’或‘01dc’。对于视频数据来说,在AVI数据序列中间还可以定义一个新的调色板,每个改变的调色板数据块用‘xxpc’来表征,新的调色板使用一个数据结构AVIPALCHANGE来定义。(注意:如果一个流的调色办中途可能改变,则应在这个流格式的描述中,也就是AVISTREAMHEADER结构的dwFlags中包含一个AVISF_VIDEO_PALCHANGES标记。)另外,文字流数据块可以使用随意的类型码表征。
  最后,紧跟在‘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结构的dwFlags中包含一个AVIF_HASINDEX标记。
  还有一种特殊的数据块,用一个四字符码‘JUNK’来表征,它用于内部数据的队齐(填充),应用程序应该忽略这些数据块的实际意义。

阅读(1367) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册