[博客翻译]结束OpenH264的篇章


原文地址:https://bbhtt.space/posts/closing-the-chapter-on-openh264/


关于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”堆栈)构成了GnomeKDE 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文件,则它将是一个由arbsdtar命令组成的序列,用于提取文件,然后将其安装在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扩展的继任者,于2019-2020年左右创建)。所以,我再次添加了libx265, libde265及其相应的libheif插件到ffmpeg-full扩展中。几个月后,我还添加了libx264,因为当时我们已经在运送libx265,而Cisco的OpenH264编码性能次优。

我对结果感到满意,这一切都在Freedesktop SDK 24.08中发布。但有些人出于正当理由感到不满意。

ffmpeg-full扩展创建时,出于各种顾虑,从未将其添加到运行时或SDK清单中;它作为一个可选的“应用程序”扩展存在——这意味着应用程序开发者需要在他们的Flatpak清单中添加一小段代码以使用它。

这在某些方面是存在问题的——有时应用程序开发者不知道这个扩展或不知道他们需要它,结果清单中缺少允许使用扩展的部分。这使用户体验和开发者体验有些糟糕。一旦我们在ffmpeg-full中引入了libheif,问题变得更加严重,因为实际的libheif库在运行时中,但没有扩展就无法解码任何HEIF/HEIC图像。于是,实际上这个扩展成了必需品。KDE Flatpaks团队的一员Albert Astals Cid对此表示不满,Erick555也提出了一项问题,讨论将ffmpeg-full作为运行时扩展的可能性。

最初出于各种原因,我有点抗拒这样做,并且情况再次超出了我们的控制范围(这次是因为H.265专利)。但我们询问了Endless等各方,令人惊讶的是,大家似乎都没有反对将其作为运行时扩展,甚至自动下载与运行时一同下载的提议。

随着这一变化,我们决定将ffmpeg-full扩展重新命名为codecs-extra,以便更好地反映这样一个事实:它不仅包含带专利部分的FFMPEG,还包括处理专利编码器的其他库。这相当于发行版为专利或受限编码器提供的各种“元包”。

种子已经埋下,我在一个月前将ffmpeg-full切换到codecs-extra 这里

这将在Freedesktop SDK 25.08中发布。应用程序开发人员的重大变化在于不再需要在清单中写入类似于:

add-extensions: org.freedesktop.Platform.ffmpeg-full:version:'24.08'directory:lib/ffmpegadd-ld-path:.

的内容。org.freedesktop.Platform.codecs-extra将由运行时自动安装并可供用户使用。

取消OpenH264扩展

上述codecs-extra变更意味着我们现在不再真正需要org.freedesktop.Platform.openh264,因为codecs-extra已经有了FFMPEG的内部H.264解码器和libx264编码器。

因此,我最初禁用了自动下载,并鉴于上述OpenH264的各种“缺陷”,提出了一个在26.08版本中计划退役的问题。

然而,这一决定被彻底推翻,因为libopenh264中发现了一个高严重性的漏洞,影响了2.5.0及更早版本。

Freedesktop运行时的23.08分支锁定在2.2.0版本,由于多个ABI断裂和SONAME升级,无法升级到已修复的版本。打补丁也不可行,正如我前面所说。

我们急忙应对这一情况。对于23.08,我们决定做出“ABI断裂”,删除扩展,因为升级是不可能的。于是,我做了一个略显吓人的公告

但24.08仍然保留着2.4.1版本,升级到固定版本2.6.0再次因ABI升级而受阻。

然而,通过查看2.4.1和2.6.0之间的提交并通过libabigail分析库,我们未能找到任何实际的ABI断裂,并考虑到Cisco过去做出过不必要的SONAME升级,我们试图修补2.6.0发布以提供旧的ABI。

我折腾了那个宝贵的apply_extra,并写了一个小实用程序来修补SONAME。但上游后来指出了ABI断裂,这个想法不得不完全废弃。(之后我跟libabigail维护者Dodji Seketeli交谈后,才知道为什么libabigail无法显示ABI断裂。)

随后,我们要求上游提供具有旧ABI的2.5.1修补版本,让我们惊讶的是,他们几周内便做到了!该版本已在24.08.15中发布,解决了24.08分支的运行时问题。

经历了这么多波折和额外的“头痛”,没有人觉得再分发openH264扩展是合适的。因此,它从主分支中被删除,这意味着在25.08及以后不会有任何org.freedesktop.Platform.openh264扩展或noopenh264

尾声

综合考虑一切,我认为并希望我们做出了正确的决定,希望新的org.freedesktop.Platform.codecs-extra能够顺利运行。libx264, libx265和其他库均从源代码构建,没有涉及二进制或额外数据。理论上,我们应该能够修补并解决未来可能出现的任何问题。

除此之外,我对这种设置可能会引发的法律问题稍感担忧,而且新扩展内容可能过多,但我们还需观察事情的发展。

有趣的一点是,我没想到Fedora也在使用我们的org.freedesktop.Platform.openh264扩展。由于noopenh264又一次迁移这里,现在迁移到了Fedora,他们正在寻找创建自己的OpenH264扩展的方法,类似于我们的做法。

我希望这段经验能对将来想要维护类似扩展的人有所帮助,同时这也提醒了我们这类专利会导致多少额外的工作量。

阅读全文(20积分)