一、WAV文件和AVI文件格式简介

WAV的英文全称是Waveform Audio File Format ,它采用 RIFF (Resource Interchange File Format)文件格式结构。通常用来保存 PCM 格式的原始音频数据,所以通常被称为无损音频。但是严格意义上来讲, WAV 也可以存储其它压缩格式的音频数据。

AVI的英文全称是Audio/Video Interleaved,被我们称为音频视频交错格式。它是一种音频视频交错在一起同步播放的文件格式,其中它对视频文件采用了一种有损压缩方式,尽管该文件在画面质量上不太好,但是应用范围也是比较广泛的。如主要应用在多媒体光盘上,用来保存电视、电影等各种影响信息。AVI是由Microsoft公司1992年11月推出的一种符合RIFF文件规范的数字音频与视频文件格式,经过发展后,也成为了常用的视频格式之一。

AVI与WAV文件都属于RIFF文件,因此都遵循RIFF文件的格式要求。

二、RIFF文件格式介绍

1、RIFF文件简介

RIFF的英文全称是Resource Interchange File Format(资源交互文件格式),是由Microsoft提出的一种多媒体文件存储方式,不同编码的视频、音频文件按照RIFF保存,当提取文件时,可以根据RIFF的规则解析文件。常见的RIFF文件有:
• 音频视频交错格式数据 .AVI
• 波形格式数据 .WAV
• 位图数据格式 .RDI
• MIDI格式数据 .RMI
• 调色板格式 .PAL
• 多媒体电影 .RMN
• 动画光标 .ANI
• 其他的RIFF文件 .BND

2、RIFF文件格式

RIFF格式是一种树状结构,主要由 FOURCC, CHUNK,LIST 组成。基本组成单元为LIST和CHUNK:LIST相当于目录,可以包含多个CHUNK或者多个LIST,包含关键字“LIST”。CHUNK是数据保存的基本单元,可用于保存音视频数据或者一些参数信息。RIFF文件结构最开始4个字节表示“RIFF”,接着4个字节表示该文件的大小,再下来的4个字节表示该文件的类型(AVI或者WAV等)。

2.1 CHUNK

CHUNK 是组成 RIFF 文件的基本单元,它的基本结构如下:

struct chunk {uint32_t id;         // 块标识符uint32_t size;          // 块大小uint8_t  data[size]; // 块内容
};
id 由 4 个 ASCII 字符组成,用于识别块中包含的数据,如:"RIFF", "LIST", "fmt", "data", "WAV", "AVI" ......,由于这种文件结构最初是由 Microsoft 和 IBM 为 PC 机所定义, RIFF 文件是按照小端字节顺序写入的。
size 表示 data 域的数据长度。
data 所包含的数据是以 word 为单位排列的,如果长度是奇数,则在最后添加一个空 (NULL) 字符。Note: 如果 id 为 "RIFF" 或 "LIST", 则 data 域则包含 SUB_CHUNK。   

2.2 LIST

LIST 数据块结构如下:

struct list {uint32_t list_size;             // List 大小uint32_t list_type;             // List 类型uint8_t  list_data[list_size];  // List 数据
};Note: list_data 是该 LIST 的数据内容,由 CHUNK 和 SUB_LIST 组成,它们的个数和组成次序可以是不确定的。

2.3 FOURCC

一个 FOURCC (four character code) 是占用 4 个字节的数据,一般表示 4 个 ASCII 字符。在 “RIFF” 文件格式中,块的起始标识等信息都是使用 FOURCC 表示的,如 “fmt”, “data”, “wav“等。

三、WAV文件格式介绍

1、WAV文件简介

wav是微软开发的一种音频文件格式,注意,wav文件格式是无损音频文件格式,相对于其他音频格式文件数据是没有经过压缩的,通常文件也相对比较大些。
通常使用三个参数来表示声音,量化位数,取样频率和采样点振幅。量化位数分为8位,16位,24位三种,声道有单声道和立体声之分,单声道振幅数据为n1矩阵点,立体声为n2矩阵点,取样频率一般有11025Hz(11kHz) ,22050Hz(22kHz)和44100Hz(44kHz) 三种,不过尽管音质出色,但在压缩后的文件体积过大,相对其他音频格式而言是一个缺点,其文件大小的计算方式为:

WAV格式文件所占容量(B) = (取样频率 X量化位数X 声道) X 时间 / 8 (字节= 8bit)

而采样率一般是44.1K,16bit采样精度,存储成
WAV格式大小 = 44.1KHz(采样率) X 16bit(采样位数) X 2(双声道) X 播放时间
每一分钟WAV格式的音频文件的大小为10MB,其大小不随音量大小及清晰度的变化而变化。

2、WAV文件格式

WAVE文件是非常简单的一种RIFF文件,它的格式类型为"WAVE"。
WAV文件遵循RIFF规则,其内容以区块(chunk)为最小单位进行存储。
WAV文件一般由3个区块组成:RIFF chunk、Format chunk和Data chunk。
另外,文件中还可能包含一些可选的区块,如:Fact chunk、Cue points chunk、Playlist chunk、Associated data list chunk等。

2.1 RIFF区块

  • 以’RIFF’为标识
  • Size是整个文件的长度减去ID和Size的长度
  • Type是WAVE表示后面需要两个子块:Format区块和Data区块

2.2 FORMAT区块

  • 以’fmt '为标识
  • Size表示该区块数据的长度(不包含ID和Size的长度)
  • AudioFormat表示Data区块存储的音频数据的格式,PCM音频数据的值为1
  • NumChannels表示音频数据的声道数,1:单声道,2:双声道
  • SampleRate表示音频数据的采样率
  • ByteRate每秒数据字节数 = SampleRate * NumChannels * BitsPerSample / 8
  • BlockAlign每个采样所需的字节数 = NumChannels * BitsPerSample / 8
  • BitsPerSample每个采样存储的bit数,8:8bit,16:16bit,32:32bit

2.3 DATA区块

  • 以’data’为标识
  • Size表示音频数据的长度,N = ByteRate * seconds
  • Data音频数据

2.4 小端存储

WAV文件以小端形式来进行数据存储。

大端模式:数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;
小端模式:数据的低位保存在内存的低地址中,而数据的高位,保存在内存的高地址中。

2.5 PCM数据在WAV文件中的bit位排列方式

四、WAV文件格式实例分析

要分析的WAV文件的基本信息如下,用Visual Studio2022以二进制编辑器形式打开该WAV文件。

WAV文件是在PCM纯音频样本数据的基础上添加了44字节的文件头。

各字节依次表示:
①资源交换文件标志(RIFF),4字节,52 49 46 46,固定写法;
②从下个地址(08)到WAV文件结尾的总字节数,4字节,7E 26 3A 00,整个WAV文件的大小就是该数值+8;
7E 26 3A 00(16)=3810942(10),与文件大小3810950正好差了8字节。
PCM音频样本总字节数+44−8=WAV文件字节数
③WAVE 文件标志 , 4字节,57 41 56 45 , 是 WAVE 四个字母的 ASCII 码 , 固定写法 ;
④波形格式标志 , 4字节,66 6D 74 20 , 一般都是 fmt , 其中 0x20 对应的字符是空格 ;
⑤过渡字节 , 4字节,12 00 00 00 , 不确定 , 有的时候是 10 00 00 00 ;
⑥格式种类 , 2字节,01 00 , 1 时表示线性 PCM 编码 ;
⑦通道数 , 2字节,02 00 , 1 表示单声道 , 2 表示立体声 ;
⑧采样频率 , 4字节,44 AC 00 00 , 44100Hz ;
⑨波形数据传输速率 , 即每秒中的字节数 , 4字节,10 B1 02 00 , 每秒传输 176400 字节 ;
计算公式 :
采样率×通道数×采样位数/8=44100×2×16/8=176400。
采样位数是16位 , 1字节8位 , 16位是2字节 , 即每个采样2字节 ;
⑩数据块调整长度 , 2字节,04 00 , 表示4 字节 ;
计算公式:
通道数×样本数据位数/8=2×16/8=4
⑪每个样本的数据位数 , 2字节,10 00 , 表示16位即2字节;

注:接下来是ffmpeg转码的数据表示ffmpeg转码的信息

⑫数据标记 , 4字节,64 61 74 61 , data 的 ASCII 码值 ;
⑬ PCM 数据总长度, 单位 字节 , 00 26 3A 00 , PCM 数据总长度为 3,810,816 字节 ;

五、AVI文件格式介绍

1、AVI文件简介

AVI是一种最复杂的RIFF文件,它能同时存储同步表现的音频视频数据。现在常用的AVI文件有2种:AVI-1, AVI-2。AVI-1中只包含一个DV数据流,占用较少的存储空间。AVI-2中通常包含一个视频流和一个音频流,只有一个视频流或者音频流也是合法的。
AVI层次划分如下图所示。

2、AVI文件格式

AVI的RIFF块的形式类型是AVI,它包含3个子块,如下所述。

  1. 信息块——包括文件的通用信息,定义数据格式,所用的压缩算法等参数。
  2. 数据块——包含实际数据流,即图像和声音序列数据。这是文件的主体,也是决定文件容量的主要部分。视频文件的大小等于该文件的数据率乘以该视频播放的时间长度。
  3. 索引块——索引块包含数据块列表好它们在文件中的位置,以提供文件内数据随机存取能力。

2.1 信息块

信息块是ID为“hdrl”的LIST块,定义AVI文件的数据格式。
“hdrl”LIST块包含两个子块,一个是ID为“avih”的子块和一个是ID为”strl”的LIST块。
“avih”块结构:用于记录AVI文件的全局信息,比如流的数量,视频图像的宽和高等。

typedef struct
{DWORD ChunID;                // 必须为'avih'DWORD ChunkSize;             //本数据结构的大小,不包括最初的8個位元組(ID和Size兩個域)DWORD dwMicroSecPerFrame ;   //显示每帧所需的时间ns,定义avi的显示速率DWORD dwMaxBytesPerSec;      //最大的数据传输率DWORD dwPaddingGranularity;  //记录块的长度需为此值的倍数,通常是2048DWORD dwFlages;              //AVI文件的特殊属性,如是否包含索引块,音视频数据是否交叉存储DWORD dwTotalFrame;          //文件中的总帧数DWORD dwInitialFrames;       //说明在开始播放前需要多少桢DWORD dwStreams;             //文件中包含的数据流个数DWORD dwSuggestedBufferSize; //建议使用的缓冲区的大小,//通常为存储一桢图像以及同步声音所需要的数据之和DWORD dwWidth;               //图像宽DWORD dwHeight;              //图像高DWORD dwReserved[4];         //保留值
}MainAVIHeader;

”avih”块的数据部分:一个或多个“strl”子列表

  1. 文件中有多少个流,这里就对应有多少个“strl”子列表。
  2. 每个“strl”字列表至少包含一个“strh”块和一个“strf”块,
  3. “strd”块(保存编解码器需要的一些配置信息)和“strn”块(保存流的名字)可选。
  4. 注意:“strl”子列表出现的顺序与媒体流的编号是对应的,比如第一个“strl”字列表说明的是第一个流(Stream 0),第二个“strl”字列表说明的是第二个流(Stream 1),以此类推。

“strh”块结构:用于说明这个“strl”LIST块对应的数据流的头信息:

typedef struct
{FOURCC fccType;       //4字节,表示数据流的种类,vids 表示视频数据流,auds 音频数据流FOURCC fccHandler;    //4字节 ,表示数据流解压缩的驱动程序代号DWORD dwFlags;        //数据流属性WORD wPriority;       //此数据流的播放优先级WORD wLanguage;       //音频的语言代号DWORD dwInitalFrames; //说明在开始播放前需要多少桢DWORD dwScale;        //数据量,视频每桢的大小或者音频的采样大小DWORD dwRate;         //dwScale /dwRate = 每秒的采样数DWORD dwStart;        //数据流开始播放的位置,以dwScale为单位DWORD dwLength;       //数据流的数据量,以dwScale为单位DWORD dwSuggestedBufferSize; //建议缓冲区的大小DWORD dwQuality;     //解压缩质量参数,值越大,质量越好DWORD dwSampleSize;  //音频的采样大小RECT rcFrame;        //视频图像所占的矩形
}AVIStreamHeader;

“strf” 块结构:“strf”子块紧跟在“strh”子块之后,其结构是“strh”子块的类型而定,如下所述:

  • 如果strh子块是视频数据流,则strf子块的内容是一个BITMAPINFO结构,如下。
typedef struct tagBITMAPINFO
{BITMAPINFOHEADER bmiHeader;RGBQUAD bmiColors[1]; //颜色表
}BITMAPINFO;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;
  • 如果strh子块是音频数据流,则strf子块的内容是一个WAVEFORMAT结构,如下:
typedef struct
{WORD wFormatTag; WORD nChannels;        //声道数DWORD nSamplesPerSec;  //采样率DWORD nAvgBytesPerSec; //WAVE声音中每秒的数据量WORD nBlockAlign;      //数据块的对齐标志WORD biSize;           //此结构的大小
}WAVEFORMAT

“strd”块结构:“strd”子块紧跟在strf子块后,存储供压缩驱动程序使用的参数,不一定存在,也没有固定的结构
“strl”List块定义的AVI数据流依次将“hdrl”LIST块中的数据流头结构与“movi”LIST块中的数据联系在一起,第一个数据流头结构用于数据流0,第二个用于数据流1,依次类推。

2.2 数据块

数据块是ID为“movi”的LIST块,包含AVI的音视频序列数据。
用于保存真正的媒体流数据(视频图像帧数据或音频采样数据等)。保存方式为:

  1. 将数据块直接嵌套在“movi”列表里面
  2. 将几个数据块分组成一个“rec”列表后再编排进“movi”列表

(注意:在读取AVI文件内容时,建议将一个“rec”列表中的所有数据块一次性读出)
但是,当文件中包含有多个流的时候,数据块与数据块之间如何来区别呢?于是数据块使用了一个四字符码来表征它的类型,这个四字符码由2个字节的类型码和2个字节的流编号组成。
“db”——非压缩视频
“dc”——压缩视频
“pc”——改用新的调色板
“wb”——音缩视频
比如:第一个流(Stream 0)是音频,则表征音频数据块的四字符码为“00wb”;
第二个流(Steam 1)是视频,则表征视频数据块的四字符码为“01db”或“01dc”。
对于视频数据来说,在AVI数据序列中间还可以定义一个新的调色板,每个改变的调色板数据块永“xxpc”来表征,新的调色板使用一个数据结构AVIPALCHANGE来定义。(注意:如果一个流的调色板中途改变,则应在这个流格式的描述中,也及时AVISTREMAHEADER结构的dwFlags中包含一个AVISF_VIDEO_PALCHANGES标记)另外,文字数据块可以使用随意的类型码表征。

2.3 索引块

索引块是ID为“idxl”的子块,定义“movi”LIST块的索引数据,是可选块。
最后紧跟在“hdr”列表块和“movi”列表块之后的,就是AVI文件可选的索引块。这个索引块为AVI文件中每一个媒体数据块进行索引,并且记录它们在文件中的偏移(可能相对于“movi”列表,也可能相对于AVI文件开头)。索引块使用一个四字符码“idxl”来表征,索引信息使用一个数据结构AVIOLDINDEXl来定义。

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中包含一个AVI_HASINDEX标记。
还有一种特殊的数据块,用一个四字符码“JUNK”来表征,它用于内部数据的对齐(填充),应用程序应该忽略这些数据块的实际意义。

六、AVI文件思考题

用MediaConch打开一个AVI文件,可以发现:
①AVI文件音频和视频的数据是交织放置的,这种按交替方式组织音频和视频数据的方式可使得读取视频数据流时能更有效地从存储媒介得到连续的信息。
②AVI文件的一个视频帧占据1个字节(?),一个音频帧占据32个字节,如下图所示。

七、总结

WAV文件是非常简单的一种RIFF文件,而AVI文件是一种较为复杂的RIFF文件,它们都按RIFF格式存储。
WAV文件是在PCM纯音频样本数据的基础上添加了44字节的文件头。文件头中包含量化位数,取样频率和通道数等信息。
AVI文件包含信息块、数据块和索引块三个子块,音视频数据是交织放置的。


参考

什么是AVI文件
WAV文件格式详解
RIFF 格式解析
AVI文件格式详解
wav音频文件格式解析【个人笔记】(自用)
WAV文件格式解析
【音频处理】WAV 文件格式分析 ( 逐个字节解析文件头 | 相关字段的计算公式 )

【数据压缩】WAV文件和AVI文件格式分析相关推荐

  1. WAV文件格式分析(附AVI文件格式分析)

    目录 一.WAV格式简介 二.WAV格式结构 1.RIFF chunk 2.Format chunk 3.Data chunk 三.AVI文件格式分析 Q1:音频和视频的数据是如何放置的?交织放置or ...

  2. PE文件和COFF文件格式分析——导出表的应用——一种摘掉Inline钩子(Unhook)的方法

    在日常应用中,某些程序往往会被第三方程序下钩子(hook).如果被下钩子的进程是我们的进程,并且第三方钩子严重影响了我们的逻辑和流程,我们就需要把这些钩子摘掉(Unhook).本件讲述一种在32位系统 ...

  3. PE文件和COFF文件格式分析——导出表的应用——通过导出表隐性加载DLL

    通过导出表隐性加载DLL?导出表?加载DLL?还隐性?是的.如果觉得不可思议,可以先看<PE文件和COFF文件格式分析--导出表>中关于"导出地址表"的详细介绍.(转载 ...

  4. PE文件和COFF文件格式分析——导出表的应用——一种插件模型

    可能在很多人想想中,只有DLL才有导出表,而Exe不应该有导出表.而在<PE文件和COFF文件格式分析--导出表>中,我却避开了这个话题.我就是想在本文中讨论下载Exe中存在导出表的场景. ...

  5. PE文件和COFF文件格式分析——导出表

    在之前的<PE可选文件头>相关博文中我们介绍了可选文件头中很多重要的属性,而其中一个非常重要的属性是(转载请指明来源于breaksoftware的CSDN博客) IMAGE_DATA_DI ...

  6. PE文件和COFF文件格式分析——RVA和RA相互计算

    之前几节一直是理论性质的东西非常多.本文将会讲到利用之前的知识得出一个一个非常有用的一个应用.(转载请指明来源于breaksoftware的csdn博客) 首先我们说下磁盘上A.exe文件和正在内存中 ...

  7. PE文件和COFF文件格式分析——节信息

    在<PE文件和COFF文件格式分析--签名.COFF文件头和可选文件头3>中,我们看到一些区块的信息都有偏移指向.而我们本文讨论的节信息是没有任何偏移指向的,所以它是紧跟在可选文件头后面的 ...

  8. PE文件和COFF文件格式分析--概述

    刚工作的时候,我听说某某大牛在做病毒分析时,只是用notepad打开病毒文件,就能大致猜到病毒的工作原理.当时我是佩服的很啊,同时我也在心中埋下了一个种子:我也得有这天.随着后来的工作进行,一些任务的 ...

  9. 【数据压缩3】AVI文件格式分析及问题回答+WAV文件格式分析

    目录 AVI文件问题回答 1.AVI文件音频和视频的数据是如何放置的,交织放置还是连续放置? 2.AVI文件一个视频帧大约占据多少字节?一个音频数据块大约占用多少字节? WAV文件格式分析 文件概述 ...

最新文章

  1. 经典文章之java 操纵Excel[转]
  2. 《PhoneGap精粹:构建跨平台的移动App》——1.10节PhoneGap资源
  3. AOP开发——在不修改源代码的前提下,对类里面的方法进行增强 : 前置 后置 环绕 异常||如何得到目标方法的参数和返回值
  4. ctab法提取dna流程图_【分子】DNA的提取与检测(下)——质粒DNA
  5. css background 一半_CSS小技巧
  6. 2014年二级c语言,2014年计算机二级考试C语言选择题
  7. sed很强大的文本操作命令
  8. python中第三方模块_如何在python脚本中包含第三方模块?
  9. Jquery EasyUi日期输入框(点击今天不自动填充)
  10. 天天淘宝,你却不知道个性化推荐技术...
  11. python header是啥_Python爬虫之Header
  12. u盘/U盘启动盘插入电脑后,不显示文件,但有保留占用内存
  13. 区块链学习2——区块链浏览器的搭建
  14. 解决Anaconda安装包时报错CondaVerificationError: The package for pytorch located at...
  15. CentOS.7卸载与安装Nvidia Driver
  16. VUE echarts绘制省级/市级地图自动轮循tooltip
  17. 评测酷睿i5 1240p和锐龙r5 6600u选哪个 i51240p和锐龙r56600u对比
  18. table固定列html5,css+js简单实现table固定首行首列
  19. respberry pi 树莓派系统设置返回英文English
  20. excel百万数据如何导入导出

热门文章

  1. Shadowing, Overriding, Hiding and Obscuring
  2. 36-基于51单片机士壤湿度检测及自动浇花系统
  3. oracle怎么新开账期,oracle成本核算
  4. seq to seq
  5. DIY申请达姆施塔特工业大学计算机专业(Informatik)硕士(Master)【附个人简历和动机信】...
  6. 万字长文,图文并茂的给你讲清SpringBoot注解,自动装配原理!
  7. 科技爱好者周刊(第 202 期):三个有启发的学习方法
  8. G2:双折线图动态获取数据
  9. springboot properties
  10. 生产者和消费者问题-----管程法