使用 ffmpeg 在 6700 XT 上进行硬件加速无损录制

使用 ffmpeg 在 6700 XT 上进行硬件加速无损录制

我正在尝试使用 ffmpeg 在 6700 XT 上使用硬件加速来无损(或以接近无损的质量)录制屏幕。我正在使用5.14.14-051414-generic内核运行 Linux Mint。

我试过了:

ffmpeg -vaapi_device /dev/dri/renderD128 -f x11grab -video_size 2560x1440 -i :0 -r 60 -vf 'hwupload,scale_vaapi=format=nv12' -c:v h264_vaapi -qp 0 output.mp4

ffmpeg据称它以 60 fps 的速度录制,但录制的内容不稳定且颜色略有偏差。我假设颜色问题来自颜色格式 nv12,但是rgborrgb8给出了错误。

我也尝试过使用 kmsgrab:

ffmpeg -device /dev/dri/card0 -f kmsgrab -i - -vf 'hwmap=derive_device=vaapi,scale_vaapi=w=2560:h=1440:format=nv12' -c:v h264_vaapi -qp 0 output.mp4

但它给出了错误:

[kmsgrab @ 0x558f001c8d80] Using plane 65 to locate framebuffers.
[kmsgrab @ 0x558f001c8d80] Failed to get framebuffer 127: Invalid argument.
pipe:: Invalid argument

后面的数字Failed to get framebuffer通常是到127或从134到 的某个位置136

我得到了这些命令这里

答案1

我认为真正的无损编码只能在软件中完成,但如果比特率更高,它看起来可能就足够好了。

此外,ffmpeg wiki 表示 VAAPI 仅部分支持 AMD GPU。

但我怀疑您目前可能正在使用 CPU 的集成 GPU,这可能会导致性能问题:

如果同一台机器上有多个可用设备(例如 Intel 集成 GPU 和 AMD 独立显卡),则可以同时使用它们来解码不同的流:

ffmpeg -init_hw_device vaapi=intel:/dev/dri/renderD128 -init_hw_device vaapi=amd:/dev/dri/renderD129 -hwaccel vaapi -hwaccel_device intel -i... -hwaccel vaapi -hwaccel_device amd -i...

您是否查看过是否有多个可用的硬件设备?

尝试ls /dev/dri/查看哪些设备可用。

无论您是否使用了正确的设备,-qp 0选项可能无法按预期工作,因此请使用给出的确切命令进行尝试,看看它们是否会给出更好的结果:

ffmpeg -vaapi_device /dev/dri/renderD128 -f x11grab -video_size 1920x1080 -i :0 -vf 'hwupload,scale_vaapi=format=nv12' -c:v h264_vaapi -qp 24 output.mp4

或者

ffmpeg -vaapi_device /dev/dri/renderD128 -f x11grab -video_size 1920x1080 -i :0 -vf 'format=nv12,hwupload' -c:v h264_vaapi -qp 24 output.mp4

只需更改分辨率,如果您找到另一个硬件设备,您也可以尝试更改它。

如果您能以合理的比特率/文件大小获得良好的质量,我会很感兴趣,所以如果您成功了,请告诉我。

顺便说一句,以下不是使用硬件加速,而是无损编码,所以你也可以尝试这个:https://trac.ffmpeg.org/wiki/Capture/Desktop#lossless-recording

要加快编码过程,您可以使用无损编码并禁用高级编码器选项,例如:

ffmpeg -video_size 1920x1080 -framerate 30 -f x11grab -i :0.0 -c:v libx264rgb -crf 0 -preset ultrafast -color_range 2 output.mkv

-crf 0 告诉 x264 以无损模式编码; -preset ultrafast 建议它做得这么快。注意使用 libx264rgb 而不是 libx264;后者会进行从 RGB 到 yuv444p 的有损转换(8 位 yuv444p 不足以保留 8 位 RGB,需要 10 位 YCbCr)。 ...

在大多数现代硬件上,编码器的速度应该足够快,以便在没有任何帧丢失的情况下进行记录,甚至为其他应用程序留出足够的 CPU 空间。

如果您要存档录音或担心文件大小,请再次无损地重新编码,但使用较慢的预设。 ...

答案2

TL,DR:我认为您主要遇到了 ffmpeg 和/或堆栈的其他部分中的错误,这些错误现在似乎已修复。

你的第一个命令:

ffmpeg -vaapi_device /dev/dri/renderD128 -f x11grab -video_size 2560x1440 -i :0 -r 60 -vf 'hwupload,scale_vaapi=format=nv12' -c:v h264_vaapi -qp 0 output.mp4

对我来说,在带有 ffmpeg 5.1 的 Debian Bookworm 上工作(我只更改了大小以匹配我的显示器),没有颜色问题和 60 fps,在相同的 GPU (6700 XT) 上。所以也许(当时)你的 ffmpeg 版本或 VA-API 驱动程序或其他地方存在错误。

它不使用最高质量,-qp 0可能超出了该编码器支持的范围并随后被忽略,显然它回落到默认值:

No quality level set; using default (20).

尽可能低的值-qp 1似乎可以接受,并且可能会带来足够的质量来满足您的需求。


关于 kmsgrab,请注意,使用它需要以 root 身份运行,或者设置 CAP_SYS_ADMIN 功能。这很可能是导致错误的原因,解决方法是在 ffmpeg 上设置功能:

setcap cap_sys_admin=ep /usr/bin/ffmpeg

这对于安全性来说并不理想,并且在更新 ffmpeg 时会中断,但它可以工作,并且您的命令行对我来说也运行良好。

另请注意,在至少 ffmpeg 5.1 之前,使用 kmsgrab 同时录制音频会导致音频/视频同步问题:

https://trac.ffmpeg.org/ticket/8377

如果您想使用它,您可能需要升级到 ffmpeg 6,根据我的经验,它解决了最后一个问题。

答案3

昨天有人问过这个问题,答案仍然是一样的:硬件视频编解码器不支持更改量化因子,即crf更多,因此它们不支持无损编码。

https://trac.ffmpeg.org/wiki/Hardware/VAAPI

libx264 的映射选项

目前不支持类似 CRF 的模式。唯一的恒定质量模式是 CQP(恒定量化参数),它对场景内容没有适应性。然而,它确实允许对不同的帧类型进行不同的质量设置,通过在未引用的 B 帧上花费更少的比特来提高压缩 - 请参阅 (i|b)_q(factor|offset) 选项。 CQP 模式不能与最大比特率或缓冲区大小结合使用。

相关内容