这是 Matthew Gregan 的个人博客 中的一篇转载文章,介绍了他为将 HTML5 开放视频引入移动设备所做的工作。Google 最近宣布 为一些工作提供资金,通过 CPU 驱动的代码路径将 Theora 引入 ARM 设备。Mozilla 在过去的一年左右时间里一直在资助 类似的工作,在移动设备中发现的 DSP 上进行视频解码,使 CPU 大部分处于空闲状态。
我们意识到这篇文章并非严格面向 Web 开发人员,但对于那些希望了解这些内容在幕后如何工作的人来说,它足够有趣。
N900 上的 Theora:或者,如何在 N900 上以 80% 的 CPU 空闲率播放全屏 Theora 视频。
C64x+ DSP 通常在基于 TI 的 OMAP3 SoC 的系统中找到,例如 Palm Pre、摩托罗拉 Droid 和诺基亚 N900。去年,Mozilla 为一个名为 Leonora 的项目提供了资金,该项目将 Xiph 的 Theora 视频编解码器移植到 TI C64x+ DSP。David Schleef 令人印象深刻地快速完成了移植工作,并 发布了他的成果。该项目的目的是为通用的移动计算平台提供一组高质量的免版税媒体编解码器。最初的重点是 N900 上的 Firefox Mobile,因此我正在努力将 David 的工作集成到 Firefox 中。为了试验 Firefox 可以用来加速视频播放的其他功能并测试集成,我一直在对 Chris Double 编写的一个名为 plogg 的独立 Ogg Theora 和 Vorbis 播放器的 分支 进行修改。
解码和播放视频可能是一个 CPU 密集型过程,尤其是在所有步骤都在争夺单个 CPU 上的时间时。播放过程中的昂贵部分可以分解成几个粗略的部分,按成本从高到低排列(近似)
- 视频帧解码
- 视频色彩空间转换(Y’CbCr 到 RGB)
- 视频帧显示
- 音频块解码
- 音频块播放
David 的 DSP 工作使项目 1 完全从 CPU 中卸载,有效地提供了“硬件加速”视频解码。大多数设备都有一些方法可以将项目 2 和 3 卸载到图形硬件,但在与现有的图形渲染管道集成时,使用起来可能很困难。
N900 具有 800×480 像素的显示屏,因此我希望能够以 30 帧/秒的速度全屏播放 800×480 视频,同时保持较低的 CPU 使用率和良好的电池续航时间。
N900 中的 ARM CPU 非常快。在进行纯视频解码测试时,原始的 Theora 库(目前没有 ARM 特定的优化)能够以 76 帧/秒的速度解码 640×360 视频,甚至可以以 32 帧/秒的速度解码 800×480 视频。使用 Robin Watts 优化的 ARM 移植版本,这些数字变为 110 FPS 和 47 FPS。David 的 DSP 移植版本产生 78 FPS 和 39 FPS,并且它使 CPU 完全空闲,因为整个解码都卸载到 DSP。根据这些数字,很明显,如果我们能够足够快地将位图显示到屏幕上,N900 完全能够流畅地播放视频。
我正在使用 plogg 作为实验的基础,使用适用于 Firefox 渲染引擎的技术。此要求立即排除了某些技术。例如,使用硬件 Y’CbCr 叠加来显示视频帧被排除在外,因为 Firefox 不可能在叠加层之上渲染任意 HTML 内容。
Chris 的 plogg 原版使用了 SDL 的 Y’CbCr 叠加 API,该 API 在大多数系统上使用快速的直接叠加路径。这为播放性能提供了基准。使用 DSP 解码我的 800×480 测试视频,可以以 33 FPS 的速度播放,CPU 空闲率约为 20%。与上面提到的仅解码基准不同,plogg 基准同时播放音频和视频,并进行正确的 A/V 同步。使用 44.1kHz 立体声音频,我观察到设备的 CPU 有 10-15% 用于 PulseAudio。这表明音频播放在某些配置下可能会占用大量的处理器时间。
由于已经开始着手在 Firefox 中提供 OpenGL 加速合成,并使用新构思的 Layers API,因此尝试使用 GLSL 片段着色器将色彩空间转换卸载到 GPU 似乎合乎逻辑。事实证明,这对于播放全屏视频来说太慢了。
查看 N900 上可用的供应商特定 OpenGL 扩展列表,我发现了 纹理流 API。这允许程序直接映射纹理内存并将 Y’CbCr 数据复制到该内存中,而无需执行代价高昂的纹理上传或色彩空间转换。色彩空间转换卸载到通过标准 OpenGL API 无法访问的专用图形硬件。使用此功能和来自 gst-bc-cat 项目的修改后的 bc-cat 内核模块,可以以 26 FPS 的速度播放,CPU 空闲率为 81%。
当前 bc-cat 内核驱动程序的一个缺点是,它支持的纹理格式非常有限(NV12、UYVY、RGB565 和 YUYV),并且没有一个与 Theora 生成的格式相同。为了解决此问题,需要进行格式转换以将平面 Y’CbCr 转换为打包的 4:2:2 UYVY。幸运的是,这种转换比完整的色彩空间转换简单得多。Timothy Terriberry 向我发送了 几个补丁 以将此转换工作卸载到 DSP。如果可以扩展 bc-cat 驱动程序以支持与 Theora 输出兼容的纹理格式,则可以进一步提高性能。
用于基准测试的测试文件为:大雄兔(视频:640×360 @ 500 kbps 24 FPS,音频:64 kbps 48kHz 立体声,9 分 56 秒,40MB)和电影 9 的预告片(视频:800×480 @ 2 Mbps 23.98 FPS,音频:44.1kHz 立体声,2 分 30 秒,30MB)。基准测试在 CPU 频率固定为 600MHz 的情况下运行。
总而言之,通过将视频解码卸载到 DSP,以及将色彩空间转换和绘制卸载到 GPU,可以在 N900 上以全帧速率和低 CPU 使用率播放全屏 Ogg Theora 视频。仍然存在优化机会,需要调查电池续航时间的调整,并且仍需要将其集成到 Firefox 中。
仅视频解码
解码器 | FPS(800×480) | 空闲 CPU |
---|---|---|
libtheora 1.1 | 32 | 0.7% |
TheorARM 0.04 | 47 | 0.4% |
leonora(DSP) | 39 | 99.0% |
播放(视频解码 + 绘制,音频解码 + 未播放)。DSP 解码视频
方法 | FPS(800×480) | 空闲 CPU |
---|---|---|
SDL/叠加 | 33 | 20.0% |
OpenGL/bc-cat | 26 | 81.4% |
4 条评论