泄漏的存储桶缓冲区模型 (Microsoft Media Foundation)

通过网络流式传输媒体时,解码器以理论上恒定的速率接收编码数据, (传输速率) 。 解码器使用此数据来生成解码的输出。 但是,在一般情况下,解码器以 可变 速率使用数据,因为这样编码器可以使用可变编码速率。

“泄漏桶”模型是一种为平滑播放的缓冲要求建模的方法。 在此模型中,解码器维护缓冲区。 编码的数据从网络进入缓冲区,从缓冲区进入解码器。 如果缓冲区下溢,则意味着解码器从缓冲区中删除数据的速度比网络提供数据的速度要快。 如果缓冲区溢出,则表示网络传递数据的速度比解码器使用数据的速度要快。

本主题介绍用于编码和解码的缓冲区的“泄漏桶”模型。

漏水桶

若要了解漏水桶模型,请考虑底部有一个小孔的桶。 三个参数定义存储桶:

  • 容量 (B)
  • 水从水桶流出的速度 (R)
  • 存储桶的初始满度 (F)

在此比喻中,存储桶是缓冲区:

插图显示缓冲区作为桶,输入速率作为水进入桶,输出速率作为水通过桶中的一个孔离开

如果水以恰好速率 R 倒入桶中,则桶将保持 F,因为输入速率等于输出速率。 如果输入速率增加,而 R 保持不变,则桶将积水。 如果输入速率在持续一段时间内大于 R ,则最终存储桶会溢出。 但是,只要平均输入速率不超过存储桶的容量,输入速率就可以在 R 左右变化,而不会溢出存储桶。 容量越大,输入速率在给定时间范围内的变化越大。

在 ASF 中,泄漏存储桶由三个参数定义:

  • 平均比特率(以字节/秒为单位),对应于输出速率 (R)
  • 缓冲区窗口(以毫秒为单位)对应于存储桶容量 (B) 。
  • 初始缓冲区满度,通常设置为零。

比特率测量编码流中每秒的平均位数。 缓冲区窗口以该比特率测量可以容纳在缓冲区中的数据的毫秒数。 缓冲区的大小(以位为单位)等于 R * (B/ 1000) 。

ASF 有效负载数据可能会在不规则的时间和不规则的数量进入泄漏的存储桶,但必须以恒定的正比特率离开存储桶。 由于缓冲区窗口,有效负载进入存储桶的时间和离开时间之间可能存在延迟。 可能发生的最大延迟为 B/R。 输入到存储桶中的有效负载数据取决于呈现时间,并且不得溢出存储桶。 除了呈现时间外,每个有效负载还有一个发送时间,即有效负载数据根据比特率离开存储桶的时间。 发送时间必须早于演示时间,以确保当泄漏的存储桶接近满时,每个有效负载都会在演示时间之前或之前离开存储桶。 为实现此目的,演示时间由预滚动) (B/R 值提前移动,并且发送时间从零开始。 发送时间必须不晚于演示时间,因为这表示有效负载进入存储桶太晚,并且不能包含在数据对象中。 预滚动值包含在 ASF 标头对象 中。

若要通过网络进行无故障流式处理,媒体内容中的压缩流在整个播放持续时间内必须保持恒定的比特率。 ASF 泄漏存储桶模型可确保媒体数据以恒定的比特率跨网络发送。 泄漏存储桶的参数在 ASF 标头对象的扩展流属性对象中指定。 在 Microsoft Media Foundation 中,它们设置为表示流的媒体类型的属性。

泄漏的存储桶值在 ASF 文件接收器和基础 ASF 多路复用器对象以及 Windows Media 编码器中定义。 这些值可能相同或不同。 例如,假设有一个流式处理方案,它要求音频样本的传送时间晚于视频样本,以便可以无延迟地流式传输文件。 为此,可以将媒体接收器中的音频流的泄漏存储桶设置为高于 Windows 媒体音频编码器中设置的值。

若要在编码器中设置 B/R 值,应用程序必须设置 MFPKEY_RAVGMFPKEY_BAVGMFPKEY_RMAXMFPKEY_BMAX 属性。 有关在编码器中设置属性的信息,请参阅 编码属性

正在使用的存储桶

编码器的目标是确保内容永远不会溢出缓冲区。 编码器使用比特率和缓冲区窗口值作为参考。 在等于缓冲区窗口的任何时间段内传递的实际位数永远不能大于缓冲区大小的两倍。

考虑以下示例:你有一个 3 加仑的桶,里面有一个孔,每分钟 1 加仑可以流过。 你把水桶放在一个尖顶下,打开阀门,以每分钟1加仑的速度放出水。 水在进入桶时流出水桶的速度一样快,水桶中没有多余的水。 然后,将流量从尖顶增加到每分钟 2 加仑。 水以这种速度流动的每分钟,2加仑进入桶中,1加仑泄漏,在桶中留下1加仑。 3分钟结束时,6加仑的水已经进入水桶,3加仑已经泄漏,水桶已经满了。

在实践中,在等于缓冲区窗口的间隔内理论上的最大数据速率永远不会实现。 上一个示例假定数据速率为恒定。 给定相同的 3 加仑桶,可以将流量从尖顶提高到每分钟 6 加仑一分钟,然后关闭尖顶 2 分钟。 即使放入水桶的总量在缓冲窗口的理论最大值内,该量在窗口的一部分的浓度会导致桶溢出。 以每分钟 6 加仑的速度,3 加仑的桶在 30 秒通过后不久溢出。 因此,在与缓冲区窗口设置相等的任何时间间隔内可以传送到缓冲区的实际最大数据量取决于单个样本的大小以及传送样本的时间。

到目前为止,这些示例只讨论了解码器使用的缓冲区,但创建压缩内容的编码器也使用泄漏的存储桶缓冲区。 编码器对压缩算法进行必要的任何调整,以将压缩样本的比特率保持在比特率和缓冲区窗口描述的边界内,假设样本将以恒定速率传递到解码器。 可以将编码器存储桶视为镜像解码器存储桶。 编码器存储桶以由单个样本大小确定的可变速率填充,并且以等于平均比特率的恒定速率泄漏。

请考虑以下示例:通过网络连接在一起的编码器和解码器。 以每秒 30 帧的速度对视频文件进行编码,比特率为每秒 6,000 位,缓冲区窗口为 3 秒, (总缓冲区大小为 18,000 位) 。 第一个示例编码为关键帧,占用 7,000 位。 编码器缓冲区现在包含 7,000 位。 接下来的 29 帧都是总 3,000 位的增量帧。 因此,第一秒的内容 (30 帧,) 如果没有任何泄漏,则会使缓冲区的满度为 10,000 位。我们知道流的比特率为每秒 6,000 位,因此,将编码内容的第一秒放入编码器缓冲区后,完整度将降至 4,000 位。 在解码应用程序中,此流以每秒 6,000 位的速度传递到解码器缓冲区。 一秒钟后,缓冲区包含 6,000 位。 第一个示例包含 7,000 位,因此在解码器开始删除样本之前,必须填充更多解码器缓冲区。

为 ASF 流设置泄漏的存储桶值

在文件编码方案中,应用程序可以在 ASF 配置文件中配置流时设置泄漏的存储桶值。

创建流并引用流的 IMFASFStreamConfig 接口后,可以使用以下属性设置值:

有关添加流和获取 IMFASFStreamConfig 指针的信息,请参阅 将流信息添加到 ASF 文件接收器

这些值包含以下信息集:

  • 平均比特率:从媒体类型协商期间选择的输出媒体类型获取平均比特率。 对音频流使用 MF_MT_AUDIO_AVG_BYTES_PER_SECOND 属性 () ,对视频流使用 MF_MT_AVG_BITRATE 属性 () 。
  • 缓冲区窗口:如果你有编码器的实例并协商输出媒体类型,则可以稍后通过查询编码器来更新此值,以获取 IWMCodecLeakyBucket 接口,然后调用 IWMCodecLeakyBucket::GetBufferSizeBits (wmcodecifaces.h、wmcodecdspuuid.lib) 。 否则,请使用默认值 3000 毫秒。
  • 初始缓冲区大小:设置为 0。

应用程序提供的值取决于编码类型和流的媒体类型。 例如, 常量比特率编码 需要预先确定的固定比特率和缓冲区窗口。 应用程序可以通过在流中设置 MFPKEY_VIDEOWINDOW 编码属性和 MF_ASFSTREAMCONFIG_LEAKYBUCKET1 属性来指定这些泄漏的存储桶值。 指定的缓冲区窗口值用于确保编码的文件在数据包上标记了正确的发送时间,并且预滚动值显示在 ASF 标头对象中。 设置 MF_ASFSTREAMCONFIG_LEAKYBUCKET1 就足够了,因为这些指定的值将复制到 MF_ASFSTREAMCONFIG_LEAKYBUCKET2 属性中。

对于 2 次编码模式,需要设置这两个属性以指定平均值和最大值。

对于 VBR 编码,应用程序只能在编码传递完成后查询编码器使用的泄漏存储桶值。 因此,在配置媒体接收器时,应用程序可以选择不设置与泄漏存储桶相关的属性或属性。 编码后,应用程序必须在编码器中查询 MFPKEY_RAVGMFPKEY_BAVGMFPKEY_RMAXMFPKEY_BMAX 属性,并在媒体接收器中设置它们,以便准确的值反映在标头对象中。 有关如何更新 VBR 编码值的代码示例,请参阅 教程:1-Pass Windows Media 编码中的“更新文件接收器中的编码属性”。

如果要在没有编码的情况下将 Windows Media 内容从源复制到媒体接收器,则必须在媒体接收器中设置泄漏的存储桶值。

ASF 多路复用器中的泄漏存储桶值

在 Media Foundation 中, ASF 多路复用器 使用泄漏桶值来设置内部泄漏桶值,该值用于生成数据包。 有效负载包含在媒体示例中,一系列媒体示例构成 ASF 数据包。 根据泄漏桶值和呈现时间,多路复用器为每个媒体样本分配发送时间,以便通过网络发送的数据包的比特率 (R) 不变。

应用程序不能直接在多路复用器中设置泄漏的存储桶值。 必须在 ASF 媒体接收器上提供这些值,该接收器在多路复用器上设置适当的值。 多路复用器使用 MF_ASFSTREAMCONFIG_LEAKYBUCKET1MF_ASFSTREAMCONFIG_LEAKYBUCKET2 中设置的值来验证发送到 ASF 媒体接收器的样本是否使用指定的值生成。

更新 ASF 媒体接收器中的泄漏存储桶值

应用程序可以通过在媒体接收器 (的属性存储区中设置 MFPKEY_ASFSTREAMSINK_CORRECTED_LEAKYBUCKET 属性,覆盖在创建流) 期间在 ASF 配置文件中设置的 级泄漏存储桶值。 若要获取对属性存储的引用,请使用媒体接收器实现的 ContentInfo 对象。 有关详细信息,请参阅 在文件接收器中设置属性

注意 只有音频流才允许此操作。

在编码器上设置输出类型后,必须设置此属性。 编码器根据媒体类型中设置的比特率计算缓冲区大小,以确保生成的媒体样本不会溢出缓冲区。 编码器在压缩期间进行必要的调整,以将压缩样本的比特率保持在比特率和缓冲区窗口描述的边界内。

与泄漏存储桶的流配置属性类似,在 DWORD 数组中设置平均比特率和缓冲区大小以及初始缓冲区填充度。 有关详细信息,请参阅本主题中的“为 ASF 流设置泄漏的存储桶值”部分。

媒体基础中的 ASF 支持

Windows Media 编解码器