2

我在媒体基础上创建了 ogg 解码器。

我已经读取了一些数据包作为样本(压缩数据),现在我需要知道样本的时间和样本的持续时间。

现在我知道了 AvgBytesPerSec 和 SamplesPerSec 等等,但是这个参数用于解压缩数据。

那么如何通过使用压缩数据来获取 IMFSample 的时间和持续时间呢?

4

1 回答 1

2

在回答之前,我假设您知道一些事情:

  • 如何读取 Vorbis 设置数据包(流中的第一个和第三个):
    • 采样率
    • 解码参数(特别是块大小和模式)
  • 如何读取 Vorbis 音频数据包标头:
    • 验证位
    • 模式选择
  • 如何根据样本数计算未压缩 PCM 数据的当前时间戳。
  • 如何根据样本计数计算未压缩 PCM 数据缓冲区的持续时间。

Vorbis 规范应该对前两个有所帮助。由于您没有对音频进行解码,因此您可以在阅读后安全地丢弃时间、地板、残差和映射配置(从技术上讲,您也可以丢弃码本,但只有在您阅读了地板配置之后)。

Granule Position 和 Sample Position 在 Vorbis 中是可互换的术语。

要计算数据包中的样本数,请将当前数据包的块大小与前一个数据包的块大小相加,然后除以 4。这有两个例外:第一个音频包为空(0 个样本),最后一个音频包数据包的大小是通过从最后一页的粒度位置减去倒数第二个页面的粒度位置来计算的。

要计算数据包的最后一个样本位置,请使用以下逻辑:

  1. 流中的第一个音频包为 0。
  2. 页面中最后一个完整的音频包是页面的颗粒位置(包括最后一页)
  3. 页面中间的数据包是根据页面的颗粒位置计算的。从页面中最后一个完整音频数据包的粒度位置开始,然后在您计算的数据包之后减去每个数据包中的样本数。
  4. 如果需要数据包的初始位置,请使用前一个数据包的颗粒位置。

如果您需要一个如何完成这一切的示例,您可以尝试通读这个(公共领域,C)。如果这没有帮助,我可以链接到 C# 中的从头开始实现。

于 2012-10-17T13:51:39.880 回答