来源:IBC2021 作者:W. Law、E. Toullec、Mickael Raulet 翻译整理:胡经川 本文介绍了一种利用通用媒体应用程序格式(CMAF)作为标准化容器格式的方法,结合低延迟HLS(LL-HLS)和低延迟DASH(LL-DASH)中的特定内容编码约束和寻址模式约束,提供跨格式解决方案,最大限度地提高边缘缓存效率,最大限度地降低源存储成本和客户端请求率。
目录
2020 年发布了端到端延迟在 2 秒范围内的两个 HTTP 自适应流 (HAS) 标准的更新:低延迟 DASH (LL-DASH) 和低延迟 HLS (LL-HLS)。这些标准和操作模式都是独立开发的,虽然它们可以在内容交付系统中部署为单独的流,但如果这两种流格式都可以统一由一组媒体对象提供服务,那么打包、源、CDN 和播放器等模块都会获得性能和成本的增益。
通用媒体应用程序格式 (CMAF) 是由 MPEG 为媒体交付应用程序开发的标准化容器格式,并标准化提案 ISO/IEC 23000-19。具体来说,CMAF 使用 ISO 基本媒体文件格 (ISOBMFF) 容器—具有通用加密 (CENC);支持 H.264、HEVC 和其他编解码器;支持 WebVTT 和 IMSC-1 字幕。本文研究了使用 CMAF 作为文件容器,结合 LL-HLS 中的字节范围寻址语法和额外的编码约束,以解决在一般互联网上交付具有高性能和可扩展性的低延迟视频的问题。
让我们先来研究一下边缘缓存的效率,当我们同时面对低延迟和标准延迟的 HLS 和 DASH 客户端时,它们都在播放相同的内容。缓存是 CDN 扩展 HTTP 自适应流 (HAS)的主要方式。缓存的内容越多,性能越好,成本也越低。我们以 4s segment 和 1s part 的 LL-HLS 流举例,图 1 显示了需要在 4 秒窗口内缓存在边缘的所有对象。图形的面积与文件尺寸成比例,如其显示,视频片段占用的空间最大。
如图 1 所示,紫色区域表示在 live edge 播放的低延迟客户端使用的部分,绿色区域则是标准延迟客户端使用的连续媒体段部分,它们之间存在内容重复。如果我们加入 DASH footprint,我们会在图 2 中看到我们有三个文件库,所有文件都包含相同的媒体内容,但在缓存空间方面相互竞争。我们的目标是将这些减少到一个文件库。这将使原始存储降低三倍,并使 CDN 的缓存效率提高三倍。这可以通过字节范围寻址来实现。
在 LL-HLS 媒体播放列表中,使用唯一的 URL 来描述每个 part。例如 #EXT-X-PART:DURATION=0.500,URI="segment1000-6.m4s",它也可以使用 BYTE-RANGE 语法来描述:#EXT-X-part:DURATION=0.500,URI=“segment1000.m4s”,BYTERANGE=251022@2079557。通过字节范围指定该 Part 在 Segment 中的长度和偏移量。对于最后一个字节位置未知的 PRELOAD HINT Part,只会发出字节范围开始的信号:#EXT-X-PRELOAD-HINT:TYPE=PART,URI="segment1000.m4s",BYTERANGE-START=2005479。图 3 左侧显示了离散的播放列表,右侧是其等价字节范围表示方式
当面对 PRELOAD HINT 条目所指定的开放范围请求时,预期的起点行为是我们需要特别关注的。根据 HLS 规范,"当处理对一个URL或一个URL的字节范围的请求时,其中包括一个或多个尚未完全可以发送的 Partial Segment-例如响应 EXT-X-PRELOAD-HINT 标签的请求-服务器必须避免发送属于该 Partial Segment 的任何字节,直到该 Partial Segment 的所有字节可以以链接全速传送到客户端。" 这意味着起点必须推迟开始响应,直到该预载部分的所有字节都可用。该规范继续说,"如果请求的范围包括一个以上的 Partial Segment,那么服务器必须依次对每个 Partial Segment 执行这一交付的保障。这使客户能够进行准确的自适应比特率(ABR)测量。" 由于我们的开放范围请求确实包括一个以上的 part(事实上,它包括该 segment 的所有剩余 part),起点应该继续将连续的 part 返回到同一个响应中,在每个 part 完全可用时才触发。这里的关键点是,这个单一的请求实际上将返回该 segment 中剩余的所有 part。图 4 说明了如何利用这一事实来推导出 LL-HLS 和 LL-DASH 之间的共同工作流程。
图 4 的下半部分表示一个使用字节范围寻址的客户端的工作流程。在时间 0,它对 SEGMENT1 提出了一个开放式的范围请求。原点会阻断响应,直到第 1 个 part 的全部内容可用,然后它开始向客户发出一个聚合响应。如果是http/1.1,这将是一个分块传输的响应,但是由于 LL-HLS 强制要求使用 http/2,而http/2 有框架,这只是一个聚合的 http/2 响应。请注意,字节被注入字节地址响应的时间与它们被释放到离散地址部分的时间完全一致。这两种方法的延迟是等效的。另外,重要的是字节寻址情况下的聚合响应正是 LL-DASH 客户端所期望的。DASH 客户端没有 part(或"chunk")必须是突发的约束,但这种突发并不影响他们,事实上,它对他们的带宽估计有很大帮助。
早期版本的 LL-HLS 产生的 part 都是独立的(即每一个 part 都包含一个关键帧),然后连续的片段有一个关键帧,如图 5 所示。其原因是编码效率问题,GOP 变长后,编码效率会有小幅提高。然而,这种安排打破了一个单一对象存储在缓存中的可移植性,我们可以从这个对象中获得 part 和 segment 的服务。为了实现统一的缓存,我们的 segment 必须是 part 的直接串联。将缓存空间减半所带来的好处远远超过了拥有两个不同比特的对象所带来的少量编码效率的提高。
所有的HTTP自适应流媒体客户端必须使用媒体段(segment)的下载,以估计可用的吞吐量,从而使他们的ABR算法能够切换。对于离散部分的交付,这是通过测量接收到的比特并除以接收时间来完成的,如图 6 上半部分所示。由于这些对象在服务器上是完全可用的,它们的交付速度受到线路速度的限制,因此可以用来估计有多少吞吐量开销。如果对聚合范围寻址响应遵循同样的逻辑,它将提供一个不正确的响应。分子将是正确的,但分母将包括原点阻断传送的时间,如图 6 下半部分。
播放器将一直用媒体段的总比特数除以传输时间,这基本上是该段的媒体播放时间。这个结果将总是返回估计的吞吐量等于对象的编码比特率--这是一个无用的结果,既不准确,又妨碍播放器切换到一个更高的比特率层。相反,播放器必须做的是只在跨线比特增加时估计整个过程,如图 7 所示。
播放器怎么能做到这一点呢?简单来说,媒体播放列表将部分边界描述为范围,原点和边缘服务器被要求总是突发 part。因此,如果播放器监控它的接收缓冲区,它可以标记接收部分边界的时间,从而计算出聚合窗口正确部分的吞吐量。
为了在真实的互联网上验证本文中描述的概念,Ateme在美国弗吉尼亚州的 AWS 实例中安装了一个编码器和LL-HLS 源。然后,把 Akamai CDN 放在上面,用它来向位于加利福尼亚州旧金山的客户传输数据,如图 8 所示。
播放器是用 Javascript 写的一个测试版本,它可以在网络浏览器中运行。基于浏览器的播放器是一个非常方便的终端,可以验证请求、时间和 CDN 性能。
测试流包含 4s 的片段,其中 part 长度为 0.5s。在 1.5s 的目标端到端延迟下运行。在图 9 中所示,绿点显示了每个媒体段请求的完成情况。这些都需要不到4秒的时间,这也是我们所期望的。橙色的点代表媒体播放列表的更新,每 500ms 发生一次。
通过测试发现,这些请求只针对片段,每个请求都从边缘服务器收到了 200 的响应,并且只用了不到 4 秒就完成了。一个奇怪的事实是,尽管我们在 LL-HLS 中使用了基于范围的寻址,但在稳定播放的情况下,客户端不需要发出任何基于范围的请求!如果在非零偏移处发出初始请求,它就会用到基于范围的请求。如果最初的请求是在非零偏移处发出的,它将使用 RFC8673 惯例,这将显示为一个 206 响应,前面有一个 CORS 预检 OPTIONS 请求,以验证范围头是否被允许。这个预检请求是在网络浏览器上测试的一个伪命题,如果在原生应用程序上测试就不会出现。相比之下,媒体播放列表的更新比媒体片段的返回要快得多,大约间隔500ms。
基于范围寻址的 LL-HLS 的出现,为直播节目的分销商带来了许多好处。
最后附上演讲视频:
http://mpvideo.qpic.cn/0bc3hmaboaaatuaoh4p4tfqvao6dc45qafya.f10002.mp4?dis_k=93960cb4d9e3ca51baf4a96b98460de2&dis_t=1645153123&vid=wxv_2254444826412924932&format_id=10002&support_redirect=0&mmversion=false