编程 FFmpeg 9.0「Lei」深度拆解:从二十年架构重写到 Vulkan 全矩阵,一个多媒体框架的自我革命

2026-08-09 11:17:02 +0800 CST views 8

FFmpeg 9.0「Lei」深度拆解:从二十年架构重写到 Vulkan 全矩阵,一个多媒体框架的自我革命

2026年8月4日,FFmpeg 社区正式发布了 FFmpeg 9.0,代号「Lei」。这不仅是 FFmpeg 历史上技术动作最大的一次版本更新,更因为它选择了一个非科学家、非数学家的名字作为代号而引发全球开发者的情感共鸣。

但今天,我们不只谈情怀。这篇文章从工程视角出发,深度剖析 FFmpeg 9.0 的架构级变化、GPU 加速体系重塑、HDR 专业管线升级,以及作为下游开发者必须掌握的 ABI 破坏性变更和迁移路径。


一、背景:为什么 9.0 不是一个普通的大版本

从版本号看,9.0 不过是 8.x 的自然延续。但数字背后的工程量,远超常规:

  • 2200+ 次提交,1781 个文件被修改
  • 净增约 52000 行代码
  • 7 个核心库的 ABI 全部破坏性升级:libavutil 60→61、libavcodec 62→63、libavformat 62→63、libavdevice 62→63、libavfilter 11→12、libswscale 9→10、libswresample 6→7

这意味着什么?意味着所有依赖 FFmpeg 动态库的下游应用,都必须重新编译。没有任何豁免。

而且 9.0 与上一个版本 8.1 "Hoare" 之间只隔了四个半月。能在如此短周期内完成如此大规模的重构,靠的是社区的高度共识:是时候解决那些年积累下来的历史债务了


二、swscale 二十年架构重写:最重磅的工程变更

2.1 旧架构的问题

libswscale 负责像素格式转换和缩放,是 FFmpeg 中调用最频繁的库之一。二十年来,它积累了大量格式特定的转换代码——每新增一种像素格式,就需要手写一条特殊处理路径。

Niklas Haas 在重构提案中描述了一个令人窒息的现实:到了 9.0 周期初,swscale 维护者每加一个格式,就要写 8-12 个特殊分支,其中大部分是手写的汇编。维护成本已经高到不可持续。

2.2 新架构设计:算子图 + 可插拔后端

新架构的核心思想是:将每一种像素格式转换分解为一系列基础操作,由优化器分析后,编译为最优的内核链

旧架构:input → if_rgb32 → if_yuv420p → special_path → if_nv12 → output(8-12个硬编码分支)

新架构:
  input (read) → swizzle → linear_transform → scale → pack (output)
                   ↓              ↓              ↓
            C 后端参考实现   x86 SIMD后端   NEON后端   Vulkan后端

这个分解过程由一个**优化器(Optimizer)**完成,它会:

  1. 分析操作列表
  2. 按平面(plane)拆分,减少单个内核循环的复杂度
  3. 选择最优后端组合
  4. 生成对应的内核链

2.3 五个后端,各司其职

后端说明适用场景
C 参考实现基于模板的通用实现正确性基准,所有后端的参照标准
快速 memcpy无需格式转换的直通场景直接拷贝
x86 SIMDNASM 宏生成的链式内核,含 AVX2 调色板读取Intel/AMD 桌面/服务器
AArch64 NEONrasm 汇编框架生成的链式内核ARM 移动/嵌入式
Vulkan SPIR-V将操作图编译为 GPU 计算着色器8K+ 高分辨率处理

2.4 Vulkan 后端:同一代码,CPU/GPU 双运行

这是最有战略意义的部分。开发者写一套转换操作图,既可以在 CPU 上用 SIMD/NEON 执行,也可以在 GPU 上用 Vulkan 着色器执行。硬件不再绑定代码路径。请求 SWS_BITEXACT 时,Vulkan 后端通过 SPIR-V 的 NoContraction 装饰禁止 GPU 的融合乘加(FMA)优化,确保 CPU 和 GPU 输出的结果逐 bit 一致,这对专业视频制作管线至关重要。

2.5 正确性工程:常量数学与 bit-exact

新架构解决了 swscale 多年的一个隐患:常量数学计算从浮点近似改为 64 位有理数精确计算,消除了一系列溢出检查错误。

2.6 稳定版本注意事项

新架构当前仍受 SWS_UNSTABLE 宏门控。在 9.0 稳定版中,默认行为仍使用旧代码。要启用新架构,需要在包含 swscale.h 之前定义 #define SWS_UNSTABLE 1,不建议在生产环境中启用。


三、libavcodec:700+ 次提交,全面开花

3.1 动画 WebP 解码器:关闭了 11 年的 ticket

FFmpeg 对 WebP 的支持始于 2015 年,但只支持静态 WebP。动态/动画 WebP 的解码和解封装(demuxer)一直缺失,对应的 ticket #4907 悬而未决 11 年。9.0 终于补全了这块短板:

# 解码动画 WebP 为帧序列
ffmpeg -i animated.webp frame_%04d.png

# 将帧序列重新打包为动画 WebP
ffmpeg -i frame_%04d.png -loop 0 output.webp

# 从视频提取动画 WebP(封面图)
ffmpeg -i video.mp4 -vf "select=eq(n\,0)" -frames:v 1 cover.webp

新增的 WebP 解码器处理 RGB 和 YUV 两种色彩空间,由 Josef Zlomek 发起、Ramiro Polla 完成。

3.2 HE-AAC 960:数字广播的盲区被填补

常规 AAC 使用 1024 采样帧,但欧洲 DAB+ 数字广播使用的是 960 采样帧的 HE-AAC。在 9.0 之前,FFmpeg 无法正确解码这类内容——音频会听起来音调偏高或出现解码错误:

# 解码 DAB+ 广播流(9.0 新支持)
ffmpeg -i dabplus_stream.ts -c:a aac audio.aac

# 解码并重采样为标准 PCM
ffmpeg -i dabplus_stream.ts -c:a pcm_s16le audio.wav

3.3 Playdate 编码器:复古掌机的视频支持

Playdate 是 Panic! Inc. 推出的复古风格手持游戏机,使用 1-bit 400×240 分辨率显示屏。9.0 新增了对该设备的原生视频编码支持,输出使用 delta 编码和 zlib 压缩:

ffmpeg -i input.mp4 \
  -vf "scale=400:240:flags=neighbor" \
  -c:v libplaydate \
  -compression_level 5 \
  output.pdv

3.4 新 API:avcodec_receive_frame_flags

9.0 新增的 avcodec_receive_frame_flags() 支持 AV_CODEC_RECEIVE_FRAME_FLAG_SYNCHRONOUS 标志,让低延迟消费者(如实时通信场景)绕过帧线程队列延迟:

#include <libavcodec/avcodec.h>

// 9.0 新增 API:支持同步帧接收,绕过帧线程延迟
int avcodec_receive_frame_flags(AVCodecContext *avctx, AVFrame *frame, int flags);

// 使用场景:WebRTC、游戏直播等需要立即得到解码结果的场景
if (low_latency_mode) {
    ret = avcodec_receive_frame_flags(avctx, frame, 
        AV_CODEC_RECEIVE_FRAME_FLAG_SYNCHRONOUS);
} else {
    ret = avcodec_receive_frame(avctx, frame);
}

3.5 NVENC 改进:AV1 分层 B 帧 + 12位输入

9.0 的 NVENC 改进包括 AV1 编码支持分层 B 帧参考模式(改善压缩效率)、兼容 Video Codec SDK 13.1,以及接受 12 位输入格式(内部截断为 10 位):

# 9.0 NVENC AV1 编码:启用分层 B 帧参考模式
ffmpeg -i input.mp4 \
  -c:v hevc_nvenc \
  -preset p4 \
  -tune hq \
  -rc vbr \
  -rc-lookahead 32 \
  -bf 7 \
  output.hevc

# 12位输入自动截断为10位
ffmpeg -i input_12bit.yuv \
  -c:v hevc_nvenc \
  -pix_fmt p010le \
  output.hevc

3.6 FFV1 Bayer:传感器直出无损压缩

专业相机传感器的 Bayer 色彩滤镜阵列(CFA)数据,以前必须先去马赛克(Demosaic)才能用 FFV1 压缩——这个过程不可逆,会损失信息。9.0 新增 FFV1 Bayer 支持:

# 编码 Bayer CFA 数据(保留全部原始传感器信息)
ffmpeg -f rawvideo -pix_fmt bggr16le -s 4096x3072 -i raw_bayer.raw \
  -c:v ffv1_bayer \
  -level 3 \
  -slicecrc 1 \
  output.mkv

# 解码回 Bayer 格式用于后期处理
ffmpeg -i output.mkv -pix_fmt bggr16le decoded_bayer.raw

Lynne 还实现了 Vulkan GPU FFV1 编解码器——完整编解码管线在 GPU 上运行,部分工作由 Sovereign Tech Fund 赞助。


四、Vulkan GPU 加速:全面铺开

9.0 最突出的技术主题,是 Vulkan 加速体系的系统化扩展。FFmpeg 正在摆脱对单一厂商 SDK 的依赖,构建跨平台的 GPU 加速基础设施。

4.1 v360_vulkan:8K 全景视频不再噩梦

360° 全景视频的投影格式转换(ERP、CubeMap、Equiangular Cubemap 等)计算量巨大,CPU 处理 8K 球面内容极其缓慢:

# CPU 方式(慢,适合小分辨率)
ffmpeg -i input_equi.mp4 -vf v360=equirect:equiangular output.mp4

# Vulkan 方式(快,8K 毫无压力)
ffmpeg -i input_equi.mp4 -vf v360_vulkan=equirect:equiangular output.mp4

4.2 APV Vulkan:Samsung 专业制作 Codec 的 GPU 加速

APV(Advanced Professional Video)是 Samsung 开发的专业制作编解码器,8.0 首次引入 FFmpeg,9.0 新增 Vulkan GPU 加速解码器。

4.3 运行时 GLSL 编译被移除

所有 Vulkan 着色器在构建时预编译为 SPIR-V,不再需要运行时 GLSL 编译器。构建产物更小,启动更快:

# scale / nlmeans / blackdetect 滤镜已移植到新 Vulkan 架构
ffmpeg -i input.mp4 -vf "scale_vulkan=1280:720" output.mp4
ffmpeg -i input.mp4 -vf "nlmeans_vulkan=s=10" denoised.mp4

4.4 NVIDIA CUDA 新滤镜

# transpose_cuda:画面旋转全程在 GPU 完成,无需 CPU 拷贝
ffmpeg -i input.mp4 -vf "transpose_cuda=dir=2" output.mp4

# 完整的 10/12 位 4:2:2 管线(NVDEC → CUDA 滤镜 → NVENC)
ffmpeg -c:v h264_cuvid -i input.mp4 \
  -c:v hevc_nvenc -preset p4 -profile:v main10 \
  -rc:v vbr -tune:v hq \
  output_hevc.mp4

4.5 AMD AMF 增强

  • frc_amf:硬件辅助帧率转换(插帧)
  • vqe_amf:视频质量增强(去噪、超分)
  • vpp_amf 新增完整 HDR 能力,含 HDR 元数据与 AMF 表示互译的公开 helpers

4.6 Apple VideoToolbox:ProRes RAW 硬件解码

在支持 VideoToolbox 的 Apple 芯片上直接硬件解码 ProRes RAW:

ffmpeg -c:v prores_videotoolbox -i prores_raw.mov \
  -c:v prores_aw -profile:v 4444 \
  output.mov

五、ONNX Runtime:将 AI 推理引入滤镜图

这是 9.0 中最具前瞻性、但最容易被忽视的变化。

FFmpeg 的 DNN 滤镜现在支持 ONNX Runtime GPU 执行提供者,涵盖:

  • NVIDIA CUDA
  • Windows DirectML(跨厂商 GPU)
  • AMD Ryzen AI NPU(通过 VitisAI 执行提供者)

结合 8.0 引入的 Whisper 语音识别滤镜,现在可以构建这样的管线:

GPU解码 → Vulkan着色器处理 → ONNX超分辨率模型(GPU) → 编码输出

帧数据全程不碰 CPU。滤镜图正在从「像素处理工具」演变为一个 AI-native 的媒体处理层

# 运行 ONNX 超分辨率模型(GPU 加速)
ffmpeg -i input_480p.mp4 \
  -vf "hwupload_cuda,scale_onnx=model=espcn.onnx:device=gpu:ep=cuda" \
  -c:v h264_nvenc output_1080p.mp4

# 结合 Whisper 进行语音识别 + 字幕生成(全程 GPU)
ffmpeg -i video.mp4 \
  -vf "hwupload_cuda,scale_onnx=model=real_esrgan.onnx:ep=cuda" \
  -c:v h264_nvenc \
  -c:a pcm_s16le -f s16le - | \
  ffmpeg -f s16le -ar 16000 -ac 1 -i - \
  -c:a libwhisper -model medium -language zh \
  subtitles.srt

六、HDR 与 Dolby Vision:专业化管线

6.1 Dolby Vision Profile 7 比特流过滤

Dolby Vision Profile 7(UHD 蓝光格式)将完整增强层 HEVC 比特流和 RPU 元数据交织在基础层流内部。9.0 新增 dovi_split 比特流过滤器:

# 从 Dolby Vision 流中分离基础层(向后兼容,标准播放器可播放)
ffmpeg -i dolby_vision.mkv \
  -c:v copy -bsf:v 'dovi_split=mode=base' \
  base_layer.mkv

# 专业后期处理:分离所有层
ffmpeg -i dolby_vision.mkv \
  -c:v copy -bsf:v 'dovi_split=mode=full' \
  -map 0:v:0 base.mkv \
  -map 0:v:1 enhanced.mkv \
  -map 0:v:2 rpu.mkv

6.2 SMPTE 2094-50 动态 HDR 元数据

新增对 HDR10+ 之外另一个 SMPTE 2094 格式的完整支持:解析、写入、透传,支持 libaom 和 libvpx 编码、Matroska block additions、ffprobe 输出。

6.3 统一 T.35 元数据处理

整个 ITU-T T.35 动态元数据体系(HDR10+、中国 HDR Vivid、AOM film grain、Active Format Description)现在通过一套统一的 helpers 处理,不再逐个编解码器重新实现:

# CLI 修正携带错误静态 HDR 元数据的文件
ffmpeg -i input.mp4 \
  -mastering_display "red=x=0.680y=0.320:blue=x=0.148:y=0.060:green=x=0.265:y=0.690:white=x=0.3127:y=0.3290:max_lum=1000:min_lum=0.0010" \
  -content_light "max=1000:avg=200" \
  output.mp4

七、大清理:告别历史包袱

9.0 完成了一次彻底的历史债务清理:

移除项说明
OpenMAX 编码器完全移除
NPP 滤镜全家scale_npp、scale2ref_npp、sharpen_npp、transpose_npp 全部移除;transpose_cuda 接替,不再需要 libnpp
v308/v408/v410这些奇特 packed-YUV 格式的专用编解码器移除
NVENC 旧支持旧 preset 别名、旧速率控制模式、SDK 11.1 以下全部移除
独立 CELT 解码器自 2014 年损坏,十一年无人察觉。不影响 Opus(Opus 内含自己的 CELT)
Sonic 编解码器Michael Niedermayer 2000 年代初的实验性编解码器家族

TLS 证书验证:最容易被忽视的行为变更

FFmpeg 9.0 默认验证 TLS 证书。这是 8.0 预告过、9.0 正式落地的安全修复。如果服务器证书有问题,9.0 将无法连接:

# 开发环境下临时绕过(仅用于测试)
ffmpeg -tls_verify 0 -i https://bad-cert.example.com/stream.m3u8 ...

八、汇编与 SIMD 优化

x86(约 200 次提交)

Andreas Rheinhardt 主持了最底层 DSP 代码的现代化运动:

  • 半像素运动补偿代码(hpeldsp 和 fpel,源自 MMX 时代)移植到 SSE2
  • H.264 帧内预测增加 AVX2 水平预测器
  • pp7 后处理 DCT 和 mpegvideoenc 中的最后 MMX 残余被清理
  • 运动估计比较函数获得 SSSE3 版本的 median SAD

ARM(约 100 次提交)

  • NEON yuv2rgb 路径重构为一次处理两行(覆盖 packed RGB、planar GBR、16-bit RGB、yuva420p、大端 16-bit)
  • HEVC 帧内角度模式 10 和 26 获得 NEON 实现
  • AAC SBR 和 float DSP 循环重新展开以更好填充现代流水线
  • Ramiro Polla 构建了 rasm 汇编框架 —— 指令级 IR + builder API,在构建时生成链式 NEON 内核

RISC-V

持续跟进:RVV 优化 hevc_add_res 和 pixelutils SAD。大部分 RISC-V 向量能量投入了 dav1d,FFmpeg 通过 dav1d 的 AV1 解码免费获得性能提升。


九、libavformat:近 400 次提交,协议与封装进化

9.0 在格式层引入了多项重量级改进:

Demuxer 命令 API:新增 avformat_send_command() / avformat_receive_command_reply(),让应用与运行中的 demuxer 实时对话。首个用户为 RTSP(暴露 SET_PARAMETER),交互式摄像头控制不再需要带外连接。

shared: 协议并发块缓存:线程安全且跨进程,多个 FFmpeg 实例读取同一远程流可共享单个缓存文件。内存映射,流完全读取后缓存文件即为可用的本地副本。由 Niklas Haas 开发。

IAMF 动态参数:mix gain、demixing 信息、recon gain 作为正规帧侧数据暴露,ffprobe 和 showinfo 滤镜可打印。

Dolby Vision 流组模型(AVStreamGroupLayeredVideo,系 LCEVC 流组的泛化):支持在 MP4、MPEG-TS 和 Matroska 中 demux 时检测,mux 到 MP4 或 Matroska 时写出(含 hvcE 增强层配置)。


十、版本速查表

旧版 8.x soname新版 9.0 soname
libavutil6061
libavcodec6263
libavformat6263
libavdevice6263
libavfilter1112
libswscale910
libswresample67

ABI 完全破坏,所有动态链接的下游必须重新编译。


十一、开发平台迁移:一个重要信号

FFmpeg 开发已正式迁移到自建的 Forgejo 实例 code.ffmpeg.org,与邮件列表并存。GitHub 上的 Pull Request 从 9.0 起 "will be ignored"。

这不是一次普通的技术迁移,而是 FFmpeg 社区对开源基础设施独立性的一次明确表态:代码托管平台的选择权,应该在社区自己手中

本周期还有一个特殊贡献者——一个自动化 bug 发现机器人,提交了 9 个被接受的 demuxer 和协议安全加固补丁。AI 正在成为开源软件质量保障的重要力量。


十二、总结:自我革命的下限与上限

FFmpeg 9.0「Lei」做了两件重要的事:

向过去告别:清理了 NPP、OpenMAX、CELT、Sonic、MMX 汇编这些十多年未维护的历史包袱,TLS 证书默认验证,CLI 大量废弃选项移除。一个多媒体框架变大的同时,也在变干净。

向未来投资:swscale 二十年架构重写、Vulkan GPU 加速体系全矩阵铺开、Dolby Vision 完整管线、ONNX Runtime 将 AI 推理引入滤镜图——这些基础设施的搭建,为 FFmpeg 的下一个十年铺平了道路。一个「解码→滤镜→AI推理→编码」全程 GPU 化的管线正在从愿景走向现实。

而那个代号,让这次发布多了一层意义。

FFmpeg 的版本代号史上写满了牛顿、傅里叶、香农、霍夫曼——改变人类知识边界的名字。而这一次,它选择记住一个让知识跨越语言障碍的人。

十年了,雷神的博客还在教人写代码。他的名字,现在刻进了一个每天被数亿设备运行的、世界上最重要的多媒体框架里。

这是开源世界对知识传播者最深的敬意。

推荐文章

PHP 唯一卡号生成
2024-11-18 21:24:12 +0800 CST
Python 基于 SSE 实现流式模式
2025-02-16 17:21:01 +0800 CST
如何在 Linux 系统上安装字体
2025-02-27 09:23:03 +0800 CST
程序员茄子在线接单