@
datetime
: 2021/06/14@author:
shenhao
文章目录
- `FFmpeg`硬件加速并且在代码中使用`NVIDIA`的编解码器
- 前言
- `CUDA`简单介绍
- `1.Windows`
- `2.Linux(centos7.9)和Unbuntu20.04安装`
- 3. `NVIDIA`编解码器的测试
- 4. 代码中使用`NVIDIA编解码器`
- FAQ
- FAQ
须知:一个章节如果标注了可跳过,那么它的子章节都需要跳过。
FFmpeg
硬件加速并且在代码中使用NVIDIA
的编解码器
本文中所有步骤来自NVIDIA
官方文档,以及参考了各大网友的做法总结和实践而成。另外本文只介绍一般的平台下的安装,不涉及特定的平台,如有需要,请参照NVIDIA
官方文档。
转载请标明出处。
前言
Windows
上的FFmpeg
的一般都已经集成了NVDIA
的编解码器,但是为了在代码中使用,需要重新对FFmpeg
进行重新编译。不建议在windows上编译,因为非常麻烦。而且不适合新手编译。本文介绍了三个不同平台下的**ffmpeg
硬件加速方案**,还有如何在代码中如何使用GPU
加速。刚开始本来是想先用windows的,因为便于测试,但是后来发现在windows平台下自己的内存不够,完不成编译(自己的内存是16G
,最少的要求内存暂时还不知道),另外,在使用预先编译好的ffmpeg
测试的时候,发现显卡又不支持h265
的编解码,所以一直报no devices found或者codec
not support。后来又使用虚拟机,但是又发现英伟达的显卡驱动不支持虚拟机递送(目前)。所以windows的用户确保自己的内存够用。另外,重要的是。不管是linux
和windows
的用户,都要确保CUDA
是否支持,对应的编解码是否支持。所以总结起来,先确保以下几点。
-
如果环境在虚拟机中,并想参考此文档进行。那么可以不用继续了。
-
如果环境在
windows
下,内存要大于16G
,<= 16G
的谨慎继续。 -
确定自己的显卡是否支持
CUDA
-
确定显卡是否支持
h264,265
的编解码器或者其他编解码的格式,以免在编译完成后,如果发现测试有误,首先先排除掉设备的问题。
例如,我笔记本的显卡为
860m
,则不支持h265
编码。
另外:
-
本文中的Windows编译用到了Visual Studio 2019,但不介绍Visual Studio 2019安装。
-
make
与cmake
等编译工具链也不介绍。 -
文中所用到的
pexports
工具和pkg-config
自行百度。
CUDA
简单介绍
CUDA
® 是由 NVIDIA
® 发明的并行计算平台和编程模型。 通过利用图形处理单元 (GPU
) 的强大功能,它可以显着提高计算性能。注意,它只是一种架构。
1.Windows
1.1 准备工作
1.1.1 安装Msys2
在Windows
中编译FFmpeg
需要Msys2
。(Msys2
简单来说是在windows下可以兼容posix
,说白了就是可以使用make && make install
等)
-
按照官方提示安装
Msys2
-
进入
Msys2
目录,并打开msys2_shell.cmd
-
输入以下命令
#更新
pacman -Syu
#安装相关工具
pacman -S make pkg-config diffutils yasm
#安装mingw64 mingw32的gcc
pacman -S mingw-w64-i686-nasm mingw-w64-i686-gcc mingw-w64-i686-SDL2 mingw-w64_x86_64-gcc
#安装nasm汇编器
pacman -S nasm
1.1.2 编译libx264(可跳过)
这一步的目的是避免有些机器没有NVDIA
显卡,不能使用CUDA
,所以作为候选,可以使用CPU编码.
- 下载
x264
源代码
git clone https://code.videolan.org/videolan/x264.git
- 打开
Msys2
目录中的mingw64.exe
-
cd
到libx264
源代码目录中(注意:当前目录下必须要有configure 和 makefile)#注意,以下为64位的编译 #prefix可以切换成别的路径 ./configure --host=x86_64-w64-mingw32 --enable-shared --prefix="C:\\" make && make install
成功安装所示
1.1.2.1 使用pexports
pexports
可以在windows下把dll
生成lib
映射文件
下载完成后,打开cmd
,进入到pexport.exe
所在的目录.
#注意:libx264后面的数字根据具体情况修改。
pexport.exe "x264源代码路径"/libx264-163.dll > libx264.def
这时候会在pexport
目录中会有libx264.def
生成
1.1.2.2 使用Visual Studio的Developer Cmd Prompt
打开后并cd
到pexport
目录(也就是libx264.def
所在的目录)
LIB /machine:x64 /DEF:libx264.def
此时会生成lib文件。注意这是动态库的lib
文件,需要一起拷贝libx264-163.dll
到文件夹中。
1.1.3 编译libx265(可跳过)
编译libx265
需要cmake
。自行下载。
cmake
的编译比较简单。
-
克隆代码
https://github.com/videolan/x265/releases
-
进入源代码目录的
source
子目录下
#指定x64
cmake -Bbuild -A=x64
#Release
cmake --build build --config Release
cd build
cmake --install . --prefix="前缀路径"
注意:也可以不指定–prefix,但
cmd
要管理员权限运行,因为默认安装路径在Programs Files下
如图,分别生成了静态库和动态库
1.1.4 安装CUDA Toolkit
CUDA Toolkit下载。选择windows平台。
下载完成后,会在此目录下。此目录中有include
和lib
1.2 正式开始编译
- 拉取
ffnvcodec
源代码
git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git
- 拉取
FFmpeg
源代码
git clone https://git.ffmpeg.org/ffmpeg.git
- 在
FFmpeg
源代码的目录下创建一个名为nv_sdk
的文件夹,复制C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\include
中的所有头文件和C:\Program Files\NVIDIA GPU Computing Toolkit
中的库文件\CUDA\v11.0\lib\x64
到nv_sdk
文件夹。 - 启动
Visual Studio x64 Native Tools Command Prompt
。 从Visual Studio x64 Native Tools Command Prompt
运行msys2
安装文件夹中的mingw64.exe
来启动MinGW64
环境。 在MinGW64
环境下,安装必要的包。
#以下操作在mingw64命令行中(由vs native tools 打开)
pacman -S diffutils make pkg-config yasm
#添加vc的cl.exe和link.exe所在的路径
export PATH="/c/Users/oaho/development/visual studio/2019/Community/VC/Tools/MSVC/14.29.30037/bin/Hostx64/x64":$PATH
#添加cuda sdk目录
export PATH="/c/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.0/bin/":$PATH
- 进入
ffnvcodec(之前克隆的)
的源代码目录
make install PREFIX=/usr
- 进入
FFmpeg
源代码目录
./configure --enable-nonfree --enable-shared --enable-cuda-sdk --enable-libnpp --toolchain=msvc --extra-cflags="-I../nv_sdk" --extra-ldflags="-libpath:../nv_sdk"
--prefix="安装路径"
注意:如果想加入
x264
和x265
编解码器。可以在--extra-cflags
中添加x264
和x265
的头文件路径(空格隔开), 当然也在--extra-ldflags
中添加库路径
make && make install
编译非常耗内存
到此处完成编译。
2.Linux(centos7.9)和Unbuntu20.04安装
2.1 Linux
Linux中有两种安装方式。第一种为普通安装(centos7.9
演示的则是普通安装),第二种是runfile
安装.。Ubuntu20.04
下,使用runfile
的方式安装。简单说一下runfile
安装和普通安装。runfile
安装更简单,通用性高。但是如果在特定的平台,需要使用普通平台安装。
**注意:以下安装前的内核要求,必须按照以下表内给出的限制。**具体细节说明,请参照系统内核要求说明。另外请参照NVIDIA官方文档
内核支持的版本
2.1.1 安装前准备
- 确定你当前系统的版本
uname -m && cat /etc/*release
- 确认是否安装
gcc
,如果没有,则安装gcc
#gcc的版本一定要6以上。对照上表进行。
yum install gcc
- 查看内核版本
#对于cuda11.3来说,centos 7.9 Release的内核必须要为3.10.0-1136
uname -r
- 安装内核头文件和开发工具包
yum install kernel-devel-$(uname -r) kernel-headers-$(uname -r)
2.1.2 安装CUDA
#(1)安装之前,先删除旧的,防止冲突
sudo /usr/local/cuda-X.Y/bin/cuda-uninstaller
sudo /usr/bin/nvidia-uninstall
wget https://developer.download.nvidia.com/compute/cuda/11.3.1/local_installers/cuda-repo-rhel7-11-3-local-11.3.1_465.19.01-1.x86_64.rpm
#看看输出是否为 028fd3c6c0c3e6c392f053afa52ce2f1
#如果不一致,则说明下载不完整,需要重新下载
md5sum cuda-repo-rhel7-11-3-local-11.3.1_465.19.01-1.x86_64.rpm
#(2) 下载驱动程序和库
yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
yum install subscription-manager
#这一步是为了之后的SDL2的依赖
yum install libX*
yum -y install yum-utils
#该驱动程序依赖于 /etc/X11/xorg.conf 中自动生成的 xorg.conf 文件。 如果存在自定义构建的 #xorg.conf 文件,则此功能将被禁用并且驱动程序可能无法运行。 删除现有的 xorg.conf 文件,或将 #/etc/X11/xorg.conf.d/00-nvidia.conf 的内容添加到 xorg.conf 文件中。
#安装先前安装的rpm
rpm --install cuda-repo-rhel7-11-3-local-11.3.1_465.19.01-1.x86_64.rpm
#(3) 加入额外的依赖
#此处可能需要加入yum代理,不然下载很慢
sudo yum-config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel7/x86_64/cuda-rhel7.repo
#(4) 清除yum缓存
sudo yum clean expire-cache
#(5) 安装CUDA
sudo yum install nvidia-driver-latest-dkms
sudo yum install cuda
sudo yum install cuda-drivers
进行到这一步,CentOS7
的用户请跳转到 [2.3 验证是否安装成功](#2.3 验证是否安装成功).
2.2 Ubuntu
20.04
2.2.1 安装前准备
- 安装依赖库
sudo apt-get install gcc
sudo apt-get install linux-headers-$(uname -r)
-
禁用
Nouveau
驱动- 创建
/etc/modprobe.d/blacklist-nouveau.conf
,在文件中加入以下内容
blacklist nouveau options nouveau modset=0
- 重新生成内核文件
sudo update-initramfs -u
- 创建
-
以
runlevel 3
的方式重启下面来介绍以下,
runlevel 3
如何启动。重启电脑,在Ubuntu
选择界面中按E
。找到splash单词,后面加上nomodeset
.最后在这一行的末尾加上3
。然后按F10
.重进系统后runlevel #如果显示的是N 3,则成功
注意: 重启后如果进入不了图形界面,则说明成功,如果进入了图形界面,则说明失败,重新尝试。
如果进入不了命令行进行,则按
Ctrl + Alt + F1
#验证一下,输入此行命令,如果没有输出,则说明禁用成功 lsmod | grep nouveau
2.2.2 安装CUDA
wget https://developer.download.nvidia.com/compute/cuda/11.3.1/local_installers/cuda_11.3.1_465.19.01_linux.run
sudo sh cuda_11.3.1_465.19.01_linux.run --no-opengl-libs --run-nvidia-xconfig
安装成功后,路径在/usr/local/cuda-11.3
中
2.3 验证是否安装成功
-
查看驱动版本
cat /proc/driver/nvidia/version
-
挂载
NVIDIA
设备modprobe nvidia
-
进入
/dev
目录,保证nvdia*
设备的执行权限chmod 666 nvidia*
-
执行命令检测
nvidia-smi
如果有以下显示,则说明驱动安装成功
如果出现了类似于以下的提示。则说明驱动安装失败
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.
-
运行测试
在安装成功后的用户主目录,会有
NVIDIA_CUDA-11.3_Samples/
文件夹,cd
后make(编译时间很长),进入到同目录的bin文件夹中,运行./deviceQuery和BandwidthTest
。如果成功的话,会有类似的显示。
2.4 开始编译
- 拉取
ffnvcodec
,并安装
git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git
cd nv-codec-headers && sudo make install
- 拉取
ffmpeg
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg/
- 安装所需库
sudo apt-get install build-essential yasm cmake libtool libc6 libc6-dev unzip wget libnuma1 libnuma-dev
- 配置
./configure --enable-nonfree -–enable-cuda-sdk –enable-libnpp --extra-cflags=-I/usr/local/cuda/include --extra-ldflags=-L/usr/local/cuda/lib64
这里可以加入之前编译的x264
库,根据自己选择
- 编译和安装
make && make install
2.1.1 编译SDL2(可跳过)
./configure && make && make install
2.1.2 编译x264(可跳过)
git clone https://code.videolan.org/videolan/x264.git
cd x264 && ./configure --disable-asm --prefix=/usr/local/x264 --enable-shared && make && make install && sudo ldconfig
#加入pkg-config
export PKG_CONFIG_PATH=/usr/local/x264/lib/pkgconfig:${PKG_CONFIG_PATH}
2.1.3 编译FFmpeg
- 安装
ffnvcodec
git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git
- 拉取
FFmpeg
源代码
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg/
- 安装依赖库和工具
yum install -y build-essential yasm cmake libtool libc6 libc6-dev unzip wget libnuma1 libnuma-dev
- 加入
cuda
的二进制目录到环境变量和pkg-config
export PATH=/usr/local/cuda-11.3/bin${PATH:+:${PATH}}
#注意,如果PKG_CONFIG_PATH是空的,不用加入":${PKG_CONFIG_PATH}"
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:${PKG_CONFIG_PATH}
#检验ffnvcodec版本
pkg-config --modversion ffnvcodec
- 进入
ffmpeg
源代码目录并配置
./configure --enable-nonfree -–enable-cuda-sdk –enable-libnpp --extra-cflags=-I/usr/local/cuda/include --extra-ldflags=-L/usr/local/cuda/lib64 --prefix=/root/ffmpeg-lib-cuda
注意:这里需要更改lib和include的路径
- 安装
make && make install
注意: 可以使用
make -j8
增加编译速度
- 安装后的配置(可选)
注意:如果配置了安装前缀,则需要建立软链接
注意:如果动态链接了
x264
,需要加入动态库路径
2.5 完成编译
输入以下命令查看H264
或者H265
的编解码器
ffmpeg -codecs | grep nvenc
成功后如下图所示
-
nvenc_***
:nvdia
的编码器 -
*_cuvid
:nvdia
的解码器
3. NVIDIA
编解码器的测试
3.1 FFmpeg
使用NVIDIA编解码器
这里注意一下,要确定自己的显卡是否支持这些编码。
h265
编码测试
ffmpeg -s 1920x1080 -pix_fmt yuv420p -i BQTerrace_1920x1080_60.yuv -vcodec hevc_nvenc -r 60 -y 2_60.265
ffmpeg -s 1920x1080 -pix_fmt yuv420p -i BQTerrace_1920x1080_60.yuv -vcodec hevc_nvenc -r 30 -y 2_30.265
-
h264
编码测试
ffmpeg -s 1920x1080 -pix_fmt yuv420p -i BQTerrace_1920x1080_60.yuv -vcodec h264_nvenc -r 60 -y 2_60.264
ffmpeg -s 1920x1080 -pix_fmt yuv420p -i BQTerrace_1920x1080_60.yuv -vcodec h264_nvenc -r 30 -y 2_30.264
h264
转h265
ffmpeg -i 1_60.264 -vcodec hevc_nvenc -r 60 -y 2_60_264to265.265
ffmpeg -i 1_30.264 -vcodec hevc_nvenc -r 30 -y 2_30_264to265.265
h265
转h264
ffmpeg -i 1_60.265 -vcodec h264_nvenc -r 60 -y 2_60_265to264.264
ffmpeg -i 1_30.265 -vcodec h264_nvenc -r 30 -y 2_30_265to264.264
3.2 GPU
使用情况查看
watch -n 1 nvidia-smi
4. 代码中使用NVIDIA编解码器
在使用FFmpeg API
的时候, AVCodec
编解码器可以改成:
#使用nvidia的264的编码器
av_find_encoder_by_name(“h264_nvenc”);
#使用nvidia的265的编码器
av_find_encoder_by_name(“hevc_nvenc”);
FAQ
-
在windows平台下编译时,
ffmpeg
的编译日志:无效的选项,–extra-ldflags
将忽略-L选项在windows下的适配性不太友好,使用
-libpath:
:“路径” -
[h264_nvenc @ 0x5649bab0c500] 10 bit encode not supported
此种编码,显卡不支持。参照显卡编解码支持列表
-
[h264_nvenc @ 0x5649bab0c500] No capable devices found
这种有多种情况
- 驱动没有安装好
- 显卡不支持此种编码
-
Ubuntu
在禁用nouveau
后,重启会黑屏。并之后都会黑屏恢复nouveau驱动
API的时候,
AVCodec`编解码器可以改成:
#使用nvidia的264的编码器
av_find_encoder_by_name(“h264_nvenc”);
#使用nvidia的265的编码器
av_find_encoder_by_name(“hevc_nvenc”);
FAQ
-
在windows平台下编译时,
ffmpeg
的编译日志:无效的选项,–extra-ldflags
将忽略-L选项在windows下的适配性不太友好,使用
-libpath:
:“路径” -
[h264_nvenc @ 0x5649bab0c500] 10 bit encode not supported
此种编码,显卡不支持。参照显卡编解码支持列表
-
[h264_nvenc @ 0x5649bab0c500] No capable devices found
这种有多种情况
- 驱动没有安装好
- 显卡不支持此种编码
-
Ubuntu
在禁用nouveau
后,重启会黑屏。并之后都会黑屏恢复nouveau驱动