首页 > 解决方案 > make ffmpeg 选择了 Nvidia CUDA 而不是 Intel QSV(带有两个视频适配器的 Windows 10)

问题描述

我刚刚设置了一台带有内置英特尔视频和 Nvida 卡的“新”PC:主要是为了加快 ffmpeg 和其他程序的视频处理速度。起初内置的 Intel 被禁用,只运行 Nvidia 卡。ffmpeg 按预期工作,CPU 可用于解码和编码。

但是:我经常使用的程序 VirtualDub 与 Nvidia 卡有问题(至少在 Windows 10 上)。显示搞砸了,预览不起作用,以及各种其他问题发生。我尝试了所有各种讨论板,但没有人有好的解决方案。(问题显然在 VirtualDub 和 Nvidia 之间存在,因为所有其他程序,如 VideoLan、Avidemux、HandBrake、OBS 工作室等,似乎都可以正常工作。)

所以我重新启用了板载英特尔适配器,并将其作为我的主要和唯一的带有显示器的视频。Nvidia 卡仍然存在,但没有连接显示器。我真的只需要它来进行硬件加速。

HandBrake 和 OBS Studio 找到了该卡并毫无问题地使用它。

但是,我的为解码和编码指定 cuda 的批处理文件无法运行。包含 -hwaccel cuda 的 ffmpeg 命令导致:

[h264 @ 000002783beaa700] Hardware is lacking required capabilities 
[h264 @ 000002783beaa700] Failed setup for format cuda: hwaccel initialisation returned error.

我也试过-hwaccel nvenc,被拒绝了。在这个版本的 ffmpeg 中,它显然不是同义词:

ffmpeg version 4.3.1-2021-01-01-full_build-www.gyan.dev Copyright (c) 2000-2021 the FFmpeg developers built with gcc 10.2.0 (Rev5, Built by MSYS2 project) configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-lzma --enable-libsnappy --enable-zlib --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libdav1d --enable-libzvbi --enable-librav1e --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libilbc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint libavutil 56. 51.100 / 56. 51.100 libavcodec 58. 91.100 / 58. 91.100 libavformat 58. 45.100 / 58. 45.100 libavdevice 58. 10.100 / 58. 10.100 libavfilter 7. 85.100 / 7. 85.100 libswscale 5. 7.100 / 5. 7.100 libswresample 3. 7.100 / 3. 7.100 libpostproc 55. 7.100 / 55. 7.100

当我在另一台 PC 上使用 QSV 加速时,我必须这样做:

-init_hw_device qsv=qsv -hwaccel qsv

所以我尝试了

-init_hw_device cuda=cuda -hwaccel cuda

但这也没有用。

如果安装了多个板,我已经看到有关使用 -gpu 选项选择 GPU 的能力的评论。但是,当我尝试使用 -gpu 0 或 -gpu 1 时,我得到:

为输入文件#0 (xxx.avi) 指定的编解码器 AVOption gpu(选择要使用的支持 NVENC 的 GPU。第一个 GPU 为 0,第二个为 1,依此类推。)不是解码选项。

我看着:

https://github.com/FFmpeg/FFmpeg/commit/527a1e213167123d24d014bc0b956ef43d9d6542

获取有关 -init_hw_device 的更多信息,但我很遗憾地说该页面上的内容对我来说毫无意义。没有示例,也没有说明如何实际选择设备。

我看着:

https://docs.nvidia.com/video-technologies/video-codec-sdk/ffmpeg-with-nvidia-gpu/

其中有一个 -init_hw_device 的“示例”,我将他们在那里的内容剪切并粘贴到我的批处理文件中,但它被拒绝了。

我还看了:

如何使用“overlay_cuda”、ffmpeg 视频过滤器在视频上刻录基于字幕的图像

其中有两个关于如何初始化 cuda 设备的示例,它们也不适用于我。-init_hw_device cuda=cuda 被正确接受,但是 -hwaccel cuda 仍然失败。尝试使用硬件加速过滤器 scale_cuda 也失败了。

那么,当它不是唯一的图形适配器时,如何让 Nvidia 卡解码视频?当只有 Nvidia 卡处于活动状态时,我能够解码视频,现在“必须”有一种方法可以得到它。我只需要知道如何告诉 ffmpeg 使用那里的卡。既然找到编码的卡没有问题,那它不应该也能找到解码和过滤的卡吗?还是我真的是第一个在我的系统上同时使用 Intel 和 Nvidia 图形适配器并尝试将 ffmpeg 与硬件加速一起使用的人?

======================

最近更新。

我已经尝试了 Nvidia FFmpeg 转码指南网页上的示例,如前所述,我仍然遇到错误。我从那个网页剪切并粘贴到我的命令窗口,但 ffmpeg 仍然没有找到正确的图形适配器。

但是,我确实有一个解决方法。我不是特别喜欢它,但它确实有效。

首先:Windows (10) 不理解没有连接显示器的图形适配器的概念。即使图形处理器(特别是 Nvidia)在没有实际视频输出的情况下可用,并且用于超级计算机和其他地方进行高速流处理,但如果没有连接显示器,Windows 将不允许您访问卡设置。Nvidia 控制中心也不允许您访问任何卡的设置,并且您不能设置处理器关联。

所以我连接了第二台显示器,并将 Nvidia 卡设置为主。

现在 ffmpeg -hwaccel cuda 第一次工作。我之前使用的命令:

ffmpeg -hide_banner -hwaccel cuda -i "input.avi" -c:a copy -ac 1 -c:v h264_nvenc -preset hq -movflags faststart -qp 30 "output.mp4"

失败是因为它找不到 Nvidia 适配器。此命令现在第一次正常工作,并使用硬件加速进行解码和编码。(音频部分无关紧要,如果我也重新编码音频,结果是一样的。)

使用缩放,命令是这样的:

ffmpeg -hide_banner -hwaccel cuda -i "input.avi" -c:a copy -ac 1 -c:v h264_nvenc -preset hq -vf "scale=640:480" -movflags faststart -qp 30 "output.mp4"

这行得通。然而:

ffmpeg -hide_banner -hwaccel cuda -i "input.avi" -c:a copy -ac 1 -c:v h264_nvenc -preset hq -vf "scale_cuda=640:480" -movflags faststart -qp 30 "output.mp4

失败

Impossible to convert between the formats supported by the filter 'graph 0 input from stream 0:0' and the filter 'auto_scaler_0'
Error reinitializing filters!
Failed to inject frame into filter network: Function not implemented
Error while processing the decoded data for stream #0:0

通过以似乎不必要的复杂语法重新排列事物,我能够解决这个问题。

ffmpeg -hide_banner -hwaccel cuvid -hwaccel_output_format cuda -i "input.avi" -c:a aac -b:a 192k -ar 48000 -vf "scale_cuda=856:480" -c:v h264_nvenc -preset hq -movflags faststart -qp 26 "output.mp4"

必须两次指定输出格式似乎很奇怪,但任务管理器显示接近 100% 的视频解码活动,并且执行此操作所需的时间向我表明正在使用 scale_cuda 过滤器。

我不是特别喜欢使用第二台显示器(如果 VirtualDub 工作正常,我可能就不必),但我愿意忍受它。看来,如果您有两个不同的视频卡,并且您想在其中一个上使用硬件加速,则它必须是主要的。

我还没有测试英特尔 QSV 是否仍然可以访问,我也没有尝试将图形适配器的顺序切换回来以完全验证问题的根源,我并没有真正打算这样做(除非你们中的一些人认为会很有用)。我有一个明确的印象,很少有人(如果有的话)试图让 Nvidia 和 Intel 适配器在同一系统上提供硬件视频加速。我将尝试访问 QSV 以查看使用这两个加速器是否是一种改进。

我可以使用奇怪的命令行来让 cuda 过滤器工作,但如果有人知道更好的方法,我认为如果其他人遇到类似问题,将它发布在这里以供将来参考会很有帮助。我在阅读过的许多网站上找到的使用 cuda 加速过滤器的示例都没有完全按照给定的方式工作。

===================

好消息:

至少在某些情况下,可以同时使用 Nvidia 和 QSV 硬件。

此命令有效:

ffmpeg -hide_banner -hwaccel dxva2 -i "input.avi" -c:a copy ^
  -c:v h264_qsv -vf "crop=1920:1044:0:0" -preset veryfast -profile:v high -level 4.1 -qp 22 "output.mp4"

任务管理器说 Nvidia 正在对输入进行解码,而 GPU-Z 说 Intel 也处于活动状态,所以它一定是在进行编码。

坏消息:我想不出在同一进程中同时使用 CUDA 过滤器和标准过滤器的方法。

这不起作用:

ffmpeg -hide_banner -hwaccel cuvid -hwaccel_output_format cuda -i "input.avi" -c:a aac -b:a 192k -ar 48000 -vf "scale_cuda=856:480,crop=1280:696:0:24" -c:v h264_nvenc -preset hq -movflags faststart -qp 30 "output.mp4"

颠倒 scale_cuda 和crop 的顺序(对数字进行适当调整)也不起作用。存在无法传输处理流的错误。

我会尝试最新评论中的更改,但我想我之前可能已经尝试过,但有些东西不起作用。但我会再次检查。

在我的网络搜索中,我没有找到“混合”过滤器的示例。

我确实在 Nvidia ffmpeg trancode 网页上看到了“-crop”和“-resize”,类似于:

–crop 0x36x0x0 –resize 1280x696

再一次,我从 Nvidia 网页剪切并粘贴到我的命令窗口,但它不起作用。如果有一种方法可以为这些经过测试并发现实际工作的选项调用 Nvidia 命令,我真的很想看到它。

标签: ffmpeggpu

解决方案


我终于得到了一个作物的例子,但有一个错误。

ffmpeg -hwaccel cuvid -c:v h264_cuvid -crop 10x100x10x100 -i input.mp4 -c:v h264_nvenc output.mp4

导致裁剪输出,但出现错误:

警告:默认 hwaccel_output_format 为 cuda 以与旧命令行兼容。此行为已弃用,将来将被删除。请明确设置“-hwaccel_output_format cuda”。

现在的问题是,绝对没有办法在不出错或导致命令拒绝裁剪过滤器的情况下添加它。我已经尝试将该选项放在命令行中我能找到的任何地方,让操作正常工作的唯一方法是省略该选项,并希望 Nvidia 不会贬低默认值。

同样的命令不适用于另一个 AVI 文件,即使它是相同的 AVC 视频编码。我在任何地方都找不到这个文档,当我在没有裁剪过滤器的情况下进行视频转码时,ffmpeg 可以很好地读取 AVI 文件,并且如前所述,任务管理器说 Nvideo 卡正在对输入文件进行硬件解码。我还可以对由同一软件 (VirtualDub) 创建的其他 AVI 文件进行转码。这两个文件都在同一个批处理文件中,我对命令行进行了剪切和粘贴,它只更改了输入文件名。错误消息只是说:

选项 hwaccel(使用硬件加速解码)不能应用于输出 url –crop - 您正在尝试将输入选项应用于输出文件,反之亦然。将此选项移到它所属的文件之前。输出文件的错误解析选项 –crop。打开输出文件时出错:参数无效

我不明白为什么更改输入文件名会导致命令失败。

我确实发现 -crop 的参数是 Crop (top)x(bottom)x(left)x(right)


推荐阅读