FFmpeg 在 Meta 的应用:大规模媒体处理

作者:Wes Castro,Meta 软件工程师
原文:https://engineering.fb.com/2026/03/02/video-engineering/ffmpeg-at-meta-media-processing-at-scale/

FFmpeg 是一款名副其实的媒体处理多功能工具。作为行业标准工具,它支持多种音频和视频编解码器以及容器格式。它还能协调复杂的滤镜链,用于媒体编辑和处理。对于使用我们应用程序的用户而言,FFmpeg 在实现全新视频体验和提升现有体验的可靠性方面发挥着重要作用。

Meta 每天执行ffmpeg (主命令行应用程序)和ffprobe (用于获取媒体文件属性的实用程序)二进制文件数百亿次,这给处理媒体文件带来了独特的挑战。FFmpeg 可以轻松地对单个文件进行转码和编辑,但我们的工作流程需要满足额外的需求。多年来,我们不得不依赖内部开发的 FFmpeg 分支来提供一些 FFmpeg 最近才添加的功能,例如线程多通道编码和实时质量指标计算。

随着时间的推移,我们的内部分支与 FFmpeg 的上游版本出现了显著差异。与此同时,新版本的 FFmpeg 引入了对新编解码器和文件格式的支持,并提高了可靠性,所有这些都使我们能够不间断地接收来自用户的更多样化的视频内容。这就要求我们同时支持最新的开源 FFmpeg 版本和我们自己的内部分支。这不仅导致了功能集逐渐分化,也给安全地重新基于我们的内部更改以避免回归带来了挑战。

随着 Meta 内部分支版本日益过时,我们与 FFmpeg 开发人员、FFlabs 和 VideoLAN 合作,在 FFmpeg 中开发了相关功能,使我们能够完全弃用内部分支版本,并完全依赖上游版本来满足我们的使用需求。通过上游补丁和重构,我们成功弥补了之前依赖内部分支版本实现的两个重要功能缺口:线程化多通道转码和实时质量指标。  

构建更高效的视频点播和直播多通道转码

FFmpeg 在 Meta 的应用:大规模媒体处理
一个视频转码流程,可生成多种不同分辨率的输出。

当用户通过我们的应用上传视频时,我们会生成一组编码以支持基于 HTTP 的动态自适应流媒体 (DASH) 播放。DASH 播放允许应用内的视频播放器根据网络状况等信号动态选择编码。这些编码在分辨率、编解码器、帧速率和视觉质量级别上可能有所不同,但它们都源自同一源编码,播放器可以实时无缝切换。

在一个非常简单的系统中,可以使用独立的 FFmpeg 命令行逐一串行地为每个通道生成编码。虽然可以通过并行运行每个命令来优化效率,但由于每个进程都会执行重复工作,这种方法很快就会变得效率低下。

为了解决这个问题,可以在单个 FFmpeg 命令行中生成多个输出,只需解码一次视频帧,然后将其发送到每个输出的编码器实例。这样可​​以消除重复的视频解码和进程启动时间开销,从而大幅降低系统开销。鉴于我们每天处理超过 10 亿个视频上传,每个视频都需要多次执行 FFmpeg,因此降低每个进程的计算使用量可以显著提高效率。

我们内部的 FFmpeg 分支在此基础上进行了额外的优化:并行视频编码。虽然单个视频编码器通常在内部是多线程的,但之前的 FFmpeg 版本在多个编码器同时运行时,会串行执行每个编码器对给定帧的处理。通过并行运行所有编码器实例,可以实现更好的整体并行性。

感谢包括 FFlabs 和 VideoLAN 在内的 FFmpeg 开发者的贡献,FFmpeg 6.0 开始实现了更高效的线程处理,并在 8.0 版本中最终完善。这直接受到我们内部分支设计的影响,也是我们一直以来依赖它提供的主要功能之一。这项开发促成了FFmpeg 数十年来最复杂的重构,并为所有 FFmpeg 用户带来了更高效的编码体验。

为了完全从我们的内部分支迁移出来,我们还需要上游实现另一个功能:实时质量指标。

在直播流转码过程中启用实时质量指标

FFmpeg 在 Meta 的应用:大规模媒体处理

视觉质量指标以数值形式表示媒体的感知视觉质量,可用于量化压缩造成的质量损失。这些指标分为参考指标和非参考指标,前者将参考编码与某种失真编码进行比较。

FFmpeg 可以在编码完成后,通过单独的命令行,使用两种现有的编码方式计算各种视觉质量指标,例如 PSNR、SSIM 和 VMAF。这对于离线或视频点播 (VOD) 场景来说没问题,但对于直播来说就不合适了,因为我们可能需要在直播中实时计算这些质量指标。

为此,我们需要在每个输出通道使用的每个视频编码器之后插入一个视频解码器。这些解码器会提供压缩视频中每一帧的位图,以便我们将其与压缩前的帧进行比较。最终,我们可以使用一条 FFmpeg 命令行实时生成每个编码通道的质量指标。

得益于 FFmpeg 开发人员(包括 FFlabs 和 VideoLAN 的开发人员)从 FFmpeg 7.0 开始实现的“循环内”解码功能,我们不再需要依赖我们内部的 FFmpeg 分支来实现此功能。

Meta 选择在上游进行贡献,以实现最大的社区影响力

诸如转码过程中的实时质量指标和更高效的线程管理等功能,能为 Meta 内外基于 FFmpeg 的各类管道提升效率。我们致力于将这些成果贡献至上游,以惠及 FFmpeg 社区及整个行业。但某些内部开发的补丁并不适合贡献至上游,它们高度依赖于我们的基础设施,难以实现广泛适配。

FFmpeg 支持使用硬件加速的解码、编码和过滤功能,支持的设备包括 NVIDIA 的 NVDEC 和 NVENC、AMD 的统一视频解码器 (UVD) 以及 Intel 的快速同步视频 (QSV)。FFmpeg 通过标准 API 的实现支持每种设备,从而简化了集成过程,并最大限度地减少了对特定于设备的命令行参数的需求。我们还通过这些 API 添加了对Meta Scalable Video Processor (MSVP)的支持,MSVP 是我们用于视频转码的定制 ASIC,从而能够在不同的硬件平台上使用通用工具,并最大限度地减少平台特定的差异。

由于 MSVP 仅在 Meta 内部基础设施中使用,FFmpeg 开发人员若无法访问硬件进行测试和验证,将难以提供支持。在这种情况下,将此类补丁保留在内部是合理的,因为它们对外部没有益处。我们已承担起责任,随着时间的推移,将内部补丁重新基于更新的 FFmpeg 版本,并进行广泛的验证,以确保升级过程中的稳定性和正确性。

对 FFmpeg 的持续投入

凭借更高效的多通道编码和实时质量指标,我们已完全弃用内部开发的 FFmpeg 分支版本,用于所有视频点播和直播流处理流程。此外,得益于 FFmpeg 的标准化硬件 API,我们能够以最小的阻力,将 MSVP ASIC 与基于软件的流水线无缝集成。

FFmpeg 历经 25 年的持续开发,经受住了时间的考验。通过改进资源利用率、增加对新编解码器和功能的支持以及提高可靠性,FFmpeg 能够为更广泛的媒体格式提供强大的支持。对于我们平台的用户而言,这意味着能够带来全新的体验并提升现有体验的可靠性。我们计划继续与开源开发者合作,对 FFmpeg 进行持续投入,从而惠及 Meta、整个行业以及我们产品的用户。

致谢

感谢开源社区、我们的合作伙伴 FFlabs 和 VideoLAN 以及众多 Meta 工程师的贡献,包括 Max Bykov、Jordi Cenzano Ferret、Tim Harris、Colleen Henry、Mark Shwartzman、Haixia Shi、Cosmin Stejerean、Hassene Tmar 和 Victor Loh。

本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/65306.html

(0)

相关推荐