Ogg 容器基础

从 Ogg page、逻辑流到 Vorbis、Opus 和 Theora 的关系

Posted by Yvain Zhang on November 30, 2021 主题:技术

Ogg 经常被直接叫成“音频格式”,但严格来说,它首先是一个容器。
这一点和很多人熟悉的 MP4、WAV 有点像:真正装在里面的可以是不同类型的数据流,而容器负责把这些流组织起来。

1. Ogg 到底是什么

Ogg 是 Xiph.Org 维护的一套开放容器格式。它最初就不是为了绑定某一个音频编码,而是为了给多媒体流提供一个自由、开放、适合流式传输的封装方式。

因此谈 Ogg 时,最好先把两层拆开:

  • Ogg:容器 / 比特流组织方式
  • Vorbis、Opus、Theora、FLAC:装在里面的编解码内容

这也是为什么很多人说“ogg 文件”,实际想表达的往往是:

  • Ogg 容器里装了 Vorbis 音频

2. 为什么 Ogg 这个容器有存在感

它长期被使用,原因主要有三点:

  • 开放,不受一部分传统专利体系约束
  • 对流式传输比较友好
  • 能容纳多个独立逻辑流

如果只看工程使用场景,它特别适合:

  • 开源音视频生态
  • 网络分发
  • 需要多路流复用的内容

3. Ogg 和 .ogg 扩展名不是一回事

这件事很容易混淆。历史上 .ogg 扩展名常被宽泛使用,但更严格一点时:

  • .ogg 常被用于 Ogg Vorbis 音频
  • .oga 更偏纯音频
  • .ogv 更偏视频
  • .ogx 可用于更一般的复用内容

也就是说,扩展名只是外层习惯,真正决定文件内容的还是容器里到底放了什么流。

4. Ogg 文件里最基本的单位是什么

Ogg 的基本单位是 page。解析时,经常先从 page 层理解它。

每个 page 通常以固定捕获串开始:

OggS

这件事非常重要,因为它让解析器在流损坏、偏移不准或者需要重新同步时,有机会重新找到正确边界。

5. 一个 Ogg page 里通常有哪些关键信息

从工程角度看,page 头部里最值得盯的是这些字段:

  • 捕获模式 OggS
  • 版本
  • 标头类型
  • granule position
  • bitstream serial number
  • page sequence number
  • checksum
  • segment table

这里面最关键的几个点分别对应不同问题:

granule position

它和时间定位相关,但它不是统一语义的“毫秒时间戳”,而是一个抽象位置值。具体代表什么,要看里面装的编解码器怎么定义。

bitstream serial number

用来区分逻辑流。一个文件里如果有多路流,就靠它把 page 分给正确的流。

page sequence number

用来检查页序是否连续,便于检测丢失或乱序。

checksum

帮助校验当前页是否损坏。

6. segment table 为什么存在

Ogg 并不是简单“一个 page 对应一个完整包”。
它允许数据包跨 page,也允许一个 page 里装多个 segment。

所以 segment table 的作用,就是告诉解析器:

  • 当前 page 里切成了多少段
  • 每段长度是多少
  • 某个 packet 是否会继续延伸到下一页

理解这一点非常关键。否则一旦写解析器时默认“页边界就是包边界”,后面会立刻出错。

7. 逻辑流是什么意思

Ogg 的一个很重要能力,是一个物理文件里可以复用多个逻辑流。

比如:

  • 一路音频
  • 一路视频
  • 甚至还可以挂别的辅助流

这些页会按时间顺序交织在同一个文件里,但通过 serial number 仍然能区分彼此属于哪条逻辑流。

所以:

  • 物理文件只有一个
  • 逻辑流可以有多条

8. Ogg 常见搭配的编解码器有哪些

Ogg 自己不决定音频 / 视频怎么压缩,它更像外层壳。

常见搭配包括:

  • Vorbis:常见的有损音频
  • Opus:更现代的音频编解码器,语音和通用音频都很强
  • Theora:视频
  • FLAC:无损音频

这也意味着做播放器或解复用器时,不能只认 Ogg 容器,还得认清里面具体是哪种 codec。

9. 工程上常见的几个问题

能识别 Ogg,但播不出来

通常说明:

  • 容器层识别对了
  • 里面的 codec 没支持,或者参数解释不对

文件可以顺序播放,但拖动定位很差

这时优先看:

  • granule position 的处理是否正确
  • 页级同步和 packet 重组逻辑是否完整

解析时经常断流或错位

重点查:

  • OggS 同步
  • segment table 解释
  • continuation page 处理
  • checksum 校验

10. 总结

理解 Ogg,最重要的是别把它直接等同于某一种音频编码。

更实用的抓法通常是:

  • 先把 Ogg 当成容器
  • 再看 page 结构
  • 再看逻辑流怎么复用
  • 最后再看里面到底装的是 Vorbis、Opus 还是别的内容

把这几层分开之后,后面无论是读格式文档、看播放器实现,还是自己做解析,都会顺很多。