OGG是一个自由且开放标准的多媒体容器文件格式,由Xiph Org基金会所维护。OGG格式并不受到软体专利的限制,并设计用於有效率地串流媒体和处理高品质的数位多媒体。一般说到OGG,都是指的Ogg Vorbis,只包含音频压缩格式Vorbis的压缩文件格式。其实,OGG不仅仅只能包含Vorbis格式,它可以包含视频格式。因此,为了区分只包含音频格式的文件格式,产生了一种新的文件格式OGV,这种格式既包含音频格式,也包含视频格式。但是OGV文件格式的压缩方法和OGG是一样的,可以采用同一种方式进行解析。

为了说明简单,下面统称OGG。

1、OGG/OGV文件结构

首先介绍一下几个相关的概念:
(1)Packet:Packet一个解码单元,或者是一帧数据。
(2)Segment:Segment是由Packet分割而成,一个Segment最多只包含255格式bytes。Segment没有Header。
(3)Page:Page是OGG/OGV文件格式的基本组成单元,是对Segment的封装。给一个或者几个连续的Segments添加一个Page Header就构成了一个Page。

下面看一下OGG/OGV的文件格式,如下图所示:

android ogg 文件 ogg文件打开_OGV

OGG/OGV文件就是由一个个的Page组成的。在解析的时候,通过Page的Header标记(“OggS”)将Page解析出来。下面看一些Page的Header结构,如下图所示。

android ogg 文件 ogg文件打开_Vorbis_02

(1)需要详细说明一下Header Type这个field。这个变量用来标识一个Page的类型。可以设置3种数值。

        0x01:设置,说明该page和前面的一个page属于同一个packet;如果不设置,说明该page属于一个新的packet。

        0x02:设置,说明该page是该stream的第一个page,如果不设置,说明不是。

        0x04:设置,说明该page是该stream的最后一个page,如果不设置,说明不是。

(2)一个Page Header占用的字节数是不固定的,主要是因为Segment Table的长度不固定。因此,Page Header占用的字节数为:27 + Seg Numbers。

(3)Granule Position的值如果为-1,说明,该page不是当前packet的最后一个page。

OGG/OGV的封装格式比较简单。不过到这里,会有一个疑问,解码的时候是以packet为单位的,那么解析出pages之后,该如何获得packets呢?了解了OGG/OGV文件格式的封装过程之后,这个问题就比较简单了。

2、OGG/OGV文件封装过程

OGG/OGV文件格式的封装主要分为四个过程:

第一、从编码器获得Packets;

第二:将Packets分割成Segments;

第三:将Segments打包成Pages;

第四:将不同stream的pages组合在一起从而获得OGG/OGV文件。对于只含有一个stream的文件,这个过程可以没有。

封装过程如下图所示。

android ogg 文件 ogg文件打开_android ogg 文件_03

Packets分割成Segments之后,由于Segment的最大长度只能为255,而且一个Segment不能包含两个Packet中的数据,因此,如果某个Segment的长度小于255,这个Segment就是Packet的最后一个Segment。有一种特殊的情况,那就是Segment的长度为0。如果一个Packet的长度正好是255的整数倍,那么就会用一个长度为0的Segment作为与下一个Packet的分界。以图中的seg_5为例,它是packet_1和packet_2的分界,它的长度必须小于255,包括0。

图中只是给出了一个比较简单的情况。在真正深入到OGG/OGV文件中去之后才发现,Packets和Pages的关系还是比较复杂的。图中的情况是一个Packet包含在一个或者多个Pages中,而一个Page只涉及到一个Packet的数据。实际的情况是,一个Page可能涉及到多个Packets的数据,而且还有可能不是整个Packet的数据。举个例子,还是上图中的Packets和Segments,只是Pages重新打包。例如:

page_1:packet_1的seg_1、seg_2、seg_3、seg_4

page_2:packet_1的seg_5和packet_2的seg_1

page_3:packet_2的seg_2、seg_3和packet_3的seg_1、seg_2

因此,在解析OGG/OGV文件的时候,就需要做相应的处理。

3、OGG/OGV文件Header信息

OGG/OGV文件是由Pages组成的,因此,与文件、stream有关的信息,也是保存在Pages中的,这些Pages一般放在文件的开始位置。那么,如何判断Pages中放的Header信息呢?这个其实比较简单,可以通过Page的Header之后的几个字节来判断。这几个字节不仅可以判断Page中的数据是否为Header信息,还可以判断Header信息的类型。这几个字节是以ASCII的形式存在的,比如:“\001virbis、“\200theora”、“fishead”等等。OGG/OGV文件包含的Header的信息类型比较多,关于各个Header的类型、结构、解析方法等,可以去参考一下ffmpeg。

对于只包含vorbis音频格式的OGG文件,包含的Header一般比较少。而在OGV文件中,就比较多了。