一. OGG音频格式概述
Ogg是一个自由且开放标准的容器格式,由Xiph.Org基金会所维护。Ogg格式并不受到软件专利的限制,并设计用于有效率地流媒体和处理高品质的数字多媒体。
“Ogg”意指一种文件格式,可以纳入各式各样自由和开放源代码的编解码器,包含音效、视频、文字(像字幕)与元数据的处理。
在Ogg的多媒体框架下,Theora提供有损的图像层面,而通常用音乐导向的Vorbis编解码器作为音效层面。针对语音设计的压缩编解码器Speex和无损的音效压缩编解码器FLAC与OggPCM也可能作为音效层面使用。
“Ogg”这个词汇通常意指Ogg Vorbis此一音频文件格式,也就是将Vorbis编码的音效包含在Ogg的容器中所成的格式。在以往,.ogg此一扩展名曾经被用在任何Ogg支持格式下的内容;但在2007年,Xiph.Org基金会为了向后兼容的考量,提出请求,将.ogg只留给Vorbis格式来使用。Xiph.Org基金会决定创造一些新的扩展名和媒体格式来描述不同类型的内容,像是只包含音效所用的.oga、包含或不含声音的影片(涵盖Theora)所用的.ogv和程序所用的.ogx。
OGGVobis(oggVorbis)是一种新的音频压缩格式,类似于MP3等的音乐格式。OggVobis是完全免费、开放和没有专利限制的。OggVorbis文件的扩展名是.OGG。Ogg文件格式可以不断地进行大小和音质的改良,而不影响旧有的编码器或播放器。OGG Vorbis有一个特点是支持多声道。
1. OGG文件的组织形式
OGG是以页(page)为单位将逻辑流组织链接起来,每个页都有pageheader和pagedata。
2. OGG page页结构
每个页之间相互独立,都包含了各自应有的信息,页的大小是可变的,通常为4K-8KB,最大值不能超过65307bytes(27+255+255*255=65307)。
1) 页标识:ASCII字符,0x4f 'O' 0x67 'g' 0x67 'g' 0x53 'S',4个字节大小,它标识着一个页的开始。其作用是分离Ogg封装格式还原媒体编码时识别新页的作用。
2) 版本id:一般当前版本默认为0,1个字节。
3) Header_type:标识当前的页的类型,1个字节,
0x01:本页媒体编码数据与前一页属于同一个逻辑流的同一个packet,若此位没有设,表示本页是以一个新的packet开始的;
0x02:表示该页为逻辑流的第一页,bos标识,如果此位未设置,那表示不是第一页;
0x04:表示该页位逻辑流的最后一页,eos标识,如果此位未设置,那表示本页不是最后一页。
4) Granule_position:媒体编码相关的参数信息,8个字节,对于音频流来说,它存储着到本页为止逻辑流在PCM输出中采样码的数目,可以由它来算得时间戳。对于视频流来说,它存储着到本页为止视频帧编码的数目。若此值为-1,那表示截止到本页,逻辑流的packet未结束。(小端)
5) Serial_number: 当前页中的流的id,4个字节,它是区分本页所属逻辑流与其他逻辑流的序号,我们可以通过这个值来划分流。(小端)
6) Page_seguence:本页在逻辑流的序号,4个字节。OGG解码器能据此识别有无页丢失。
7) CRC_cbecksum:循环冗余校验码校验和,4个字节,包含页的32bit CRC校验和(包括头部零CRC校验和页数据校验),它的产生多项式为:0x04c11db7。
8) Num _segments:给定本页在segment_table域中出现的segement个数,1个字节。其最大值为255.页最大物理尺寸为65307bytes,小于64KB。
9) Segment_table: 从字面看它就是一个表,表示着每个segment的长度,取值范围是0~255。
由segment可以得到packet的值,每个packet的大小是以最后一个不等于255的segment结束的,从页头中的segment_table可以得到每个packet长度,举例:如果一组segment依次顺序为FF 45 FF FF FF 40 FF 5 FF FF FF66,那么第一个packet的长度为255+69 = 324,第二个packet大小829,同理
页头基本上就是由上述的参数组成,由此我们可以得到页头的长度和整个页的长度:
header_size = 27+Num_segments;(byte)
page_size = header_size +segment_table中每个segment的大小;
例如:
0000: 4F 67 67 53 00 02 00 00 00 00 00 00 00 00 82 78 OggS..........倄
0010: 00 00 00 00 00 00 12 85 4E 81 01 1E 01 76 6F 72 .......匩....vor
0020: 62 69 73 00 00 00 00 01 44 AC 00 00 FF FF FF FF bis.....D.......
0030: 00 F4 01 00 FF FF FF FF B8 01 4F 67 67 53 00 00 ..........OggS..
0040: 00 00 00 00 00 00 00 00 82 78 00 00 01 00 00 00 ........倄......
0050: CC 63 C9 DB 0F 4D FF FF FF FF FF FF FF FF FF FF 蘡邵.M..........
0060: FF FF FF E8 03 76 6F 72 62 69 73 1D 00 00 00 58 .....vorbis....X
0070: 69 70 68 2E 4F 72 67 20 6C 69 62 56 6F 72 62 69 iph.Org libVorbi
0080: 73 20 49 20 32 30 30 34 30 36 32 39 01 00 00 00 s I 20040629....
0090: 1C 00 00 00 45 4E 43 4F 44 45 52 3D 41 64 6F 62 ....ENCODER=Adob
00A0: 65 28 52 29 20 41 75 64 69 74 69 6F 6E 28 52 29 e(R) Audition(R)
00B0: 01 05 76 6F 72 62 69 73 29 42 43 56 01 00 08 00 ..vorbis)BCV....
0000-0039:第一页
0000-001B:页头部
0000-0003=4F 67 67 53:页标识,OggS的Ascii字符
0004=00:版本号为0
0005=02:页头部类型:本页为逻辑流的第一页bos
0006-000D=0:区段位置为0
000E-0011=82 78 00 00:逻辑流ID
0012-0015=0:本页在逻辑流中的序号为0
0016-0019=12 85 4E 81:循环冗余校验码校验和
001A=01:区段表中有1个区段
001B=1E:区段表中的区段长度为 1E
001C-0039:页数据(0039=1C+1E-1)
001C=01:包头类型为标识包,包长度为1E(001C-0039),是区段表中区段的长度
001D-0022=76 6F 72 62 69 73:包头标识,vorbis的Ascii码
0023-0026=0:版本号为0
0027=01:单声道
0028-002B=44 AC 00 00:音频采样率为44.1KHZ(&HAC44=44100)
002C-002F=FF FF FF FF:最大比特率未设置
0030-0033=00 F4 01 00:标称比特率
0034-0037=FF FF FF FF:最小比特率未设置
0038=B8:块大小0为二进制的1011,块大小1为二进制的1000
0039=01:标识包结束
003A-0E8B:第二页
003A-0063:页头部
003A-003D=4F 67 67 53:页标识,OggS的Ascii字符
003E=00:版本号为0
003F=00:页头部类型:本页为新包,不是逻辑流的第一页,也不是最后一页
0040-0047=0:区段位置为0
0048-004B=82 78 00 00:逻辑流ID
004C-004F=01 00 00 00:本页在逻辑流中的序号为1
0050-0053=CC 63 C9 DB:循环冗余校验码校验和
0054=0F:区段表中有15个区段
0055-0063=4D FF FF FF FF FF FF FF FF FF FF FF FF FF E8:区段表中15个区段的长度
0064-0E8B:页数据(0E8B=64+4D+FF*D+E8-1)
0064=03:包头类型为注释包,包长度为4D(0064-00B0),是区段表中第1个区段的长度
0065-006A=76 6F 72 62 69 73:包头标识,vorbis的Ascii码
006B-006E=1D 00 00 00:制作软件信息]的长度为29字节
006F-008B=制作软件信息字符串:Xiph.Org libVorbis I 20040629
008C-008F=01 00 00 00:保留字节
0094-00AF=注释[1]字符串:ENCODER=Adobe(R) Audition(R)
00B0=01:注释包结束
00B1=05:包头类型为装备包
00B2-00B7=76 6F 72 62 69 73:包头标识,vorbis的Ascii码