ALVR 硬件视频编码加速测试指南:用 FFmpeg 验证 NVENC 与 VA-API 编码管线

原创2026-10-03 17:13:46547 阅读
文章标签:音视频图形学

ALVR 硬件视频编码加速测试指南:用 FFmpeg 验证 NVENC 与 VA-API 编码管线

ALVR 通过 Wi-Fi 将 PC 上的 VR 画面流式传输到头显,其流畅度高度依赖 GPU 硬件视频编码。本文以 ALVR 仓库中的 FFmpeg-Hardware-Encoding-Testing.md 为主线,讲解如何在 Nvidia、Intel、AMD 三种 GPU 平台上用 FFmpeg 的测试命令验证硬件编码(Offloading)是否真正生效,并对照 ALVR 在 Linux 下实际的 FFmpeg VA-API 编码实现与补丁,帮助你在配置 ALVR 之前先确认自己的编码硬件可用。

读完本文,你将掌握:三大编码器(AVC/H.264、HEVC/H.265、AV1)与四大图形编码 API 的核心区别、testsrc2 测试源的正确用法、三大 GPU 平台各自的硬件编码验证命令与监控手段,以及 ALVR 源码中 VA-API 编码管线的真实工作方式。

为什么需要先验证硬件编码

ALVR 服务端在每一帧都要把渲染出的 VR 画面压缩成视频流再经 Wi-Fi 发送。编码是最耗 CPU 的环节之一,只有把它卸载(offload)到 GPU 的专用编码单元,才能在高分辨率、高刷新率(如 90 FPS 甚至 120 FPS)下保持低延迟。从 ALVR 的 Linux 编码管线源码可以看到,VA-API 编码器对应三个 FFmpeg 编码器名称(见 EncodePipelineVAAPI.cpp):

const char* encoder(ALVR_CODEC codec) {
    switch (codec) {
    case ALVR_CODEC_H264:
        return "h264_vaapi";
    case ALVR_CODEC_HEVC:
        return "hevc_vaapi";
    case ALVR_CODEC_AV1:
        return "av1_vaapi";
    }
    ...
}

也就是说,ALVR 的 Linux 端在运行时就依赖 FFmpeg 的 *_vaapi 编码器。如果硬件不支持对应编码,编码会失败或退回软件编码(软编),延迟和画质都会明显劣化。因此,在正式部署 ALVR 之前用本文的测试命令确认“硬件编码确实生效”,是排查卡顿、高延迟问题的第一步。

三大视频编码器:ALVR 支持的编码格式

测试之前先明确要验证的目标格式。ALVR 编码器选择对应三种主流视频编码标准:

  • AVC(H.264 / MPEG-4 Part 10):基于块的运动补偿视频压缩标准,是目前应用最广的视频格式,最高支持 8K UHD 分辨率,硬件编码支持最普及。ALVR 中的 ALVR_CODEC_H264 即映射为 h264_vaapi / h264_nvenc。
  • HEVC(H.265 / MPEG-H Part 2):作为 AVC 的继任者,在同画质下数据压缩率可提升 25%~50%,最高支持 8192×4320(含 8K UHD);其 10 位 Main 10 profile 已被几乎所有新硬件编码器支持。ALVR 中的 ALVR_CODEC_HEVC 映射为 hevc_vaapi / hevc_nvenc。
  • AV1(AOMedia Video 1):开放、免版税的视频编码格式,由开放媒体联盟(AOMedia)作为 VP9 的继任者推出,起初面向互联网视频传输,其码流规范包含参考编解码器。硬件编码支持仅限最新一代硬件(如 Nvidia Ada Lovelace、Intel Arc、AMD RDNA3/VCN 4.0+)。

从 ALVR 的 Linux 编码实现还可以看到 10 位编码的具体做法:EncodePipelineVAAPI.cpp 中,当编码器为 HEVC 或 AV1 且开启 10 位编码时,硬件帧的软件格式(sw_format)使用 AV_PIX_FMT_P010,否则使用 AV_PIX_FMT_NV12。这对应 ALVR 会话设置中的 use_10bit_encoder 选项(见 lib.rs)。

四大图形编码 API

  • VA-API(Video Acceleration API):开源 API,让 VLC、GStreamer 等应用使用 GPU 硬件视频加速能力,由自由开源库 libva 加硬件专用驱动实现。Intel 用 intel-media-driver,AMD 用 mesa-va-drivers。可用 vainfo 命令查看当前 VA-API 状态(列出支持的编码/解码入口点与格式)。
  • Vulkan Video:Vulkan 面向 3D 图形与计算的低开销跨平台 API 的扩展,用于视频编解码。AV1 解码扩展已发布,H.264/H.265 编码扩展亦已纳入 Vulkan SDK,ALVR 仓库中即有 Vulkan 视频层(见 vulkan_layer)作为支撑;就编码而言其支持仍属“即将到来(upcoming)”状态,本文测试命令不涉及。
  • NVENC:Nvidia 显卡中的专用视频编码单元,把计算密集的编码从 CPU 卸载到 GPU 上的专用硬件模块。
  • AMF(Advanced Media Framework):AMD 提供的 SDK,用于在多媒体处理中充分使用 AMD GPU,是 AMD 侧的专有编码 API(在 Linux 上 ALVR 主要走 VA-API)。

生成测试视频源:testsrc2

用真实的游戏画面测试会受场景复杂度干扰,难以判断编码是否走硬件。testsrc2 测试源则能提供稳定、可重复的输入。原文给出的生成命令为:

ffmpeg -hide_banner -f lavfi -i testsrc2=duration=30:size=1280x720:rate=90

各要素说明:

  • -f lavfi:Libavfilter 输入虚拟设备。它从一个 libavfilter 滤镜图的开放输出 pad 读取数据,并为每个开放输出建立对应流;滤镜图通过 graph 选项指定,这里的 -i testsrc2=... 即为该滤镜图。
  • testsrc2:生成测试视频图案的源滤镜,显示彩色图案、滚动渐变和时戳,主要用于测试。与 testsrc 相似,但支持更多像素格式(不只是 rgb24),可直接作为其他测试输入而无需格式转换。
  • 三个参数的含义:duration 为视频时长(秒)、size 为画面尺寸(宽×高)、rate 为帧率(FPS)。

原文采用的完整测试套路是 duration=300:size=1280x720:rate=90,即 5 分钟、720p、90 FPS——90 FPS 正好对齐常见 VR 头显刷新率。请注意:使用测试源做输入仍会产生 CPU 负载(FFmpeg 本身要生成画面),监控 GPU 是否卸载编码时,预期到 FFmpeg 进程仍有 CPU 占用是正常的。

渲染回放验证

编码产出的文件是否正确,用你最顺手的播放器验证即可:

  • MPV:基于 MPlayer、mplayer2 和 FFmpeg 的自由开源播放器,支持 Linux、BSD、macOS、Windows,并有 Android 移植版(mpv-android),跨 ARM、PowerPC、x86/IA-32、x86-64、MIPS 等架构。
  • VLC:VideoLAN 项目开发的自由开源、跨平台媒体播放器与流媒体服务器,支持桌面系统与 Android、iOS、iPadOS 等移动平台。

Nvidia GPU 验证(NVENC 管线)

Nvidia 平台只支持 NVENC:目前 Nvidia 的 VA-API 驱动(nvidia-vaapi-driver)只实现了 NVDEC(解码),编码必须走 NVENC。开始前请对照 Nvidia 官方的 GPU 编码/解码支持矩阵确认你的显卡支持 NVENC 及对应编码格式。

监控工具:

  • nvtop:Neat Videocard TOP,类似 htop 的任务监视器,支持 AMD、Intel 和 Nvidia GPU,可多 GPU 显示。
  • nvidia-smi pmon:基于 NVIDIA 管理库(NVML)的命令行工具,pmon 子命令列出每个设备上运行的计算与图形进程统计。

三种编码的测试命令(NVENC):

# H.264
ffmpeg -hide_banner \
-f lavfi -i testsrc2=duration=300:size=1280x720:rate=90 \
-c:v h264_nvenc -qp 18 \
nvidia-h264_nvec-90fps-300s.mp4

# H.265
ffmpeg -hide_banner \
-f lavfi -i testsrc2=duration=300:size=1280x720:rate=90 \
-c:v hevc_nvenc -qp 18 \
nvidia-hevc_nvec-90fps-300s.mp4

# AV1(仅 Ada Lovelace 及更新架构)
ffmpeg -hide_banner \
-f lavfi -i testsrc2=duration=300:size=1280x720:rate=90 \
-c:v av1_nvenc -qp 18 \
nvidia-av1_nvec-90fps-300s.mp4

参数说明:-c:v 选择视频编码器(h264_nvenc / hevc_nvenc / av1_nvenc);-qp 18 以固定量化参数(Constant QP)方式控制质量,值越小质量越高、码率越大。运行期间用 nvtop 或 nvidia-smi pmon 观察编码器引擎利用率,确认编码发生在 GPU 而非 CPU。

Intel GPU 验证(VA-API 管线)

Intel 平台只支持 VA-API,GEN 架构图形硬件配合 intel-media-driver。编码前请对照 Intel oneVPL 的硬件支持文档确认你的 CPU/GPU 支持的编码格式。

监控工具:同样推荐 nvtop(它同时支持 AMD、Intel、Nvidia GPU)。

三种编码的测试命令(VA-API,设备节点 /dev/dri/renderD128):

# H.264
ffmpeg -hide_banner \
-f lavfi -i testsrc2=duration=300:size=1280x720:rate=90 \
-vaapi_device /dev/dri/renderD128 -vf 'format=nv12,hwupload' \
-c:v h264_vaapi -qp 18 \
intel-h264_vaapi-90fps-300s.mp4

# H.265
ffmpeg -hide_banner \
-f lavfi -i testsrc2=duration=300:size=1280x720:rate=90 \
-vaapi_device /dev/dri/renderD128 -vf 'format=nv12,hwupload' \
-c:v hevc_vaapi -qp 18 \
intel-hevc_vaapi-90fps-300s.mp4

# AV1(仅 Arc A 系列)
ffmpeg -hide_banner \
-f lavfi -i testsrc2=duration=300:size=1280x720:rate=90 \
-vaapi_device /dev/dri/renderD128 -vf 'format=nv12,hwupload' \
-c:v av1_vaapi -qp 18 \
intel-av1_vaapi-90fps-300s.mp4

VA-API 命令与 NVENC 的关键差异:-vaapi_device /dev/dri/renderD128 指定 VA-API 渲染节点(通常即集成显卡的 render 节点),-vf 'format=nv12,hwupload' 先把帧转成 NV12 再上传(upload)到 GPU 显存,随后交给 h264_vaapi / hevc_vaapi / av1_vaapi 编码器。ALVR 的 Linux 编码实现与这里的 hwupload 思路一致——见 EncodePipelineVAAPI.cpp,它通过 map_frame 把 Vulkan 帧映射为 DRM-PRIME 帧再转为 VA-API 帧,避免显存拷贝。

AMD GPU 验证(VA-API 管线)

AMD 平台只支持 VA-API,配合 mesa-va-drivers。编码需要 Video Core Next(VCN)硬件;AV1 编码需要 VCN 4.0+(RDNA3/Navi 3x 系列)硬件。请对照硬件特性确认编码支持。

监控工具:nvtop 同样适用于 AMD GPU。

三种编码的测试命令(VA-API):

# H.264
ffmpeg -hide_banner \
-f lavfi -i testsrc2=duration=300:size=1280x720:rate=90 \
-vaapi_device /dev/dri/renderD128 -vf 'format=nv12,hwupload' \
-c:v h264_vaapi -qp 18 \
amd-h264_vaapi-90fps-300s.mp4

# H.265
ffmpeg -hide_banner \
-f lavfi -i testsrc2=duration=300:size=1280x720:rate=90 \
-vaapi_device /dev/dri/renderD128 -vf 'format=nv12,hwupload' \
-c:v hevc_vaapi -qp 18 \
amd-hevc_vaapi-90fps-300s.mp4

# AV1(仅 VCN 4.0+,Navi 3x)
ffmpeg -hide_banner \
-f lavfi -i testsrc2=duration=300:size=1280x720:rate=90 \
-vaapi_device /dev/dri/renderD128 -vf 'format=nv12,hwupload' \
-c:v av1_vaapi -qp 18 \
amd-av1_vaapi-90fps-300s.mp4

AMD 在 HEVC 编码上有特殊性:仓库补丁 0006-Add-AV_VAAPI_DRIVER_QUIRK_HEVC_ENCODER_ALIGN_64_16-f.patch 为 AMD Radeon 驱动增加了 64×16 的表面对齐要求——AMD 的 VA-API HEVC 编码器要求 surface 宽度按 64、高度按 16 对齐,而不像其他硬件那样依赖 min_cb_size。这意味着在 AMD 上测试 HEVC 时,若画面尺寸不符合对齐要求,编码参数会被 FFmpeg 内部调整对齐,属正常现象。

仓库佐证:ALVR 在 Linux 上如何依赖 FFmpeg VA-API

上述测试命令并非孤立存在,ALVR 的 Linux 编码管线与它们共享同一套 FFmpeg VA-API 机制,仓库中有直接证据:

这些补丁说明,ALVR 对 VA-API 编码不只是“能用就行”,而是做了面向实时流媒体的深度适配。如果你的自编译 FFmpeg 缺少这些补丁,ALVR 的 Linux VA-API 编码可能遇到参数集、动态码率或 AMD 对齐方面的问题。

测试结果的判定要点

  • 编码器是否正确启用:命令输出中应能看到所选编码器的初始化信息(如 h264_vaapi、hevc_vaapi、av1_vaapi、h264_nvenc 等);若 FFmpeg 报告编码器不可用、初始化失败或参数不支持,说明硬件或驱动不满足条件。
  • GPU 是否真正参与:运行期间用 nvtop(三平台通用)或 nvidia-smi pmon(Nvidia)观察编码引擎(Encoder Engine / Video Engine)占用率。若编码引擎占用明显上升而 CPU 占用没有成倍增长,即说明编码已卸载到 GPU。
  • 输出是否可正常播放:用 MPV 或 VLC 回放生成的 mp4,确认画面(彩色图案 + 滚动渐变 + 时戳)与时间轴正确。
  • 与 ALVR 设置的对应:确认硬件支持后,在 ALVR 会话设置中选择对应的编码器(H.264/HEVC/AV1)与 10 位编码开关,即可让 ALVR 复用你刚验证过的硬件编码管线。
登录后查看全文
ALVR