关于OpenH264的告别
日期:2025年3月22日
大家可能已经注意到,我曾提到计划从Freedesktop SDK中移除OpenH264。在这篇文章中,我会尝试追溯它的历史、时间线以及最终决策的原因。
简单介绍
如果你不熟悉Freedesktop SDK项目,它起源于由Alexander Larsson创建的第一个1.6版本Flatpak运行时图像。该项目最初的目的是为Flatpak提供一个独立于主机的操作环境(即“运行时”)。随着时间推移,该项目在CodeThink及其他贡献者的帮助下逐步发展为一个由社区维护的独立项目,目标是提供“最小化的Linux运行时”。
目前,该运行时包括org.freedesktop.{Sdk, Platform}
Flatpak运行时,一些其他的Flatpak扩展(如GL(Mesa)扩展),一个包含Linux内核、固件和驱动程序的可引导镜像堆栈,以及一系列Docker镜像。
这些运行时(更广泛地说,“Flatpak”堆栈)构成了Gnome和KDE Flatpak运行时的基础,这两者总共支持2000多个Flatpak应用。同时,可引导堆栈及其其他组件也是GNOME OS的基础。
一些背景
H.264是当今使用最广泛的视频编码格式之一,但它受专利保护,并且许多相关专利仍未过期。这些专利限制了我们将其纳入基础运行时的能力(因为我们希望确保其适用于各种供应商且不存在任何法律灰色地带),这给所有相关方带来了困难。
为了绕过这一限制并将功能软件提供给用户,早在2019年,Tom Coldrick向Freedesktop运行时中添加了一个名为html5-codecs扩展的前驱。这个想法很简单——它将包含FFmpeg内部H.264解码器的支持,并作为可选的Flatpak扩展存在,因为我们无法将其直接集成到运行时中。
几个月后的2019年6月,Robert McQueen 提出了一个问题,建议将Cisco的OpenH264(通常也称为libopenh264
)作为运行时的一个扩展。
libopenh264
的代码虽然是开源的,但由于H.264专利问题,没有任何厂商被允许分发自己的二进制文件。解决方案是直接向用户提供未经修改的Cisco二进制文件,这样可以免去版税,但有一个限制,即这些二进制文件带有某些许可证限制。
为了解决这个问题,当时的Endless团队为Flatpak增加了额外数据支持。这意味着Flatpak扩展元数据只会包含指向Cisco二进制文件的URL、校验和及一个“配方”以制作工作扩展。二进制文件会在用户的机器上下载,在沙盒环境中执行“配方”后生成工作扩展。这种方法完全避开了再分发限制,因为我们并没有直接传输二进制文件本身。
不过,这种方法仍存在一个问题:如果终端用户系统没有下载该扩展,则基础运行时的一部分ABI会缺失。此外,扩展还会挂载到Flatpak沙盒中的非标准位置。因此,我们需要一个“公共”库来解决这个问题,该库必须包含在运行时中。
为了解决这个问题,Endless开发了一个名为noopenhh264的虚拟OpenH264库。它与实际的Cisco OpenH264库保持ABI/API兼容性,并存储在运行时的$libdir
目录中,以便软件可以链接到libopenh264并提供回退选项。在运行时,如果用户下载了实际的OpenH264扩展,那么通过Flatpak的ld.so配置,虚拟库会被扩展中的库覆盖,从而实现正常工作的OpenH264设置!
OpenH264扩展的开端
根据上述复杂的历史,2019年8月,Tom Coldrick再次将此“noopenh264”库添加到运行时,并设置了扩展点,称为org.freedesktop.Platform.openh264
。
大约在同一时间,"stub" noopenh264库的开发也转到了Freedesktop SDK伞形结构之下,而该附加数据扩展的开发则在一个专门的仓库中进行专用仓库。
我之前提到过一种被称为“recipe”的额外数据Flatpak扩展。其实这无非是一些命令的集合,存在于一个特殊的名为apply_extra
的文件中,用于部署和安装源代码。例如,如果是.deb
文件,则它将是一个由ar
或bsdtar
命令组成的序列,用于提取文件,然后将其安装在Flatpak的额外数据前缀内。
这里的关键是,使用任何这样的工具会使扩展直接依赖特定版本的Flatpak运行时,进而依赖其API/ABI。由于每一年的主要发行版都是全新的ABI,所以我们需要不断拆分出新的OpenH264扩展分支。例如,对于libopenh264版本2.1.0,我们需要针对每个不同运行时版本的分支,例如org.freedesktop.Platform.openh264//2.1.0-{18.08, 19.08, 20.08}
。这将使在Freedesktop运行时本身更新扩展变得非常麻烦,同时也让下游运行时的工作更加复杂。
为了解决这个问题,编写了一个自定义的apply_extra
脚本,仅利用几个标准头文件,并针对固定的工具链进行了静态编译。
这意味着一些复杂性增加,因为不能使用大多数让过程更容易的东西。但这同样意味着最终的扩展独立于运行时API/ABI,并基于“NoRuntime”构建。
缺陷逐渐显现
尽管有来自Cisco的一些维护问题,整个系统运作得相当好一段时间。然而,还是出现了一些缺陷。
早些时候,我提过每个供应商都必须分发Cisco在其网站https://ciscobinary.openh264.org
托管的二进制文件。不幸的是,ciscobinary.openh264.org
自从至少2014年以来就没有有效的SSL证书,并且Cisco既不提供GPG签名也不提供强大的校验和,例如SHA-256。
这意味着我们无法验证Cisco二进制文件的真实性,从而使我们容易受到各类中间人攻击和供应链漏洞的影响。我们与Mozilla以及Fedora/RedHat联系以促使Cisco修复这一问题,但最终无果。
最近(约2024年至2025年间),这种SSL问题导致域名开始被DNS阻止,从而使额外数据下载失败,破坏安装。
另一个关键问题是,如果我们上游进行了安全修复并发布了导致ABI中断的新版本,我们就无法为Flatpak运行时修复这个问题。直接通过额外数据分发二进制文件意味着无法挑选补丁,而ABI中断意味着新版本只能进入运行时的新分支。
我们在这里确实没有太多选择。如果我们考虑到潜在的缺陷而取消该扩展,那么整个Flatpak用户群体将失去H.264解码和编码支持,所以我们不得不忍受这种安排。
codecs-extra扩展的起步
大约在2024年6月,由于一系列安全问题,gdk-pixbuf
停止支持了很多“边缘”加载器。我们在稳定分支中持续分析ABI时立刻注意到了这一变化。
为弥补这些丢失的加载器,我们决定在运行时中加入对webp, avif, jxl, heif
的支持(配有pixbuf加载器)。几乎同时,Will Thompson 开启了一个问题,提出将libheif
添加到运行时,将有问题的HEIC解码器作为运行时扩展。
结果是我们认为专门为两个libheif插件创建另一个扩展并不值得付出维护成本,它们应该包含在ffmpeg-full
扩展中(这是html5-codecs
扩展的