使用GPU为FFmpeg加速

昨天因为调用GPU给FFmpeg压片子加速跟姐姐一起折腾到二半夜,现在终于不管是Win还是Linux都可以省时省力跑完一套流程(Linux在截流上还稍微有点问题,正在寻找趁手的工具——没找到,自己造了一个,详见最后)了!姑且写个记录,可能会有很多无关标题的参数记录,纯粹是记下来下次压片子备查的。我尽量写详细点,可以参考,使用场景不一样的情况下最好不要照抄。

注:显卡是N卡。

Linux下调用GPU为FFmpeg加速

本节主要参考文档:

注意:你之前可能已经安装过FFmpeg,但为了调用GPU所以咱还是得重新编译安装一遍。

安装CUDA

人英伟达的文档自己写的:

To compile FFmpeg, the CUDA toolkit must be installed on the system, though the CUDA toolkit is not needed to run the FFmpeg compiled binary.

那总之先装CUDA。

下载:CUDA Toolkit Downloads(截止本文发布时间为止,最新版本为CUDA Toolkit 11.4)

是什么系统选什么,例我自己:Linux - x86_64 - Ubuntu - 20.04 - deb[local],下载页给出的安装引导是:

$ wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
$ sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600
$ wget https://developer.download.nvidia.com/compute/cuda/11.4.0/local_installers/cuda-repo-ubuntu2004-11-4-local_11.4.0-470.42.01-1_amd64.deb
$ sudo dpkg -i cuda-repo-ubuntu2004-11-4-local_11.4.0-470.42.01-1_amd64.deb
$ sudo apt-key add /var/cuda-repo-ubuntu2004-11-4-local/7fa2af80.pub
$ sudo apt-get update
$ sudo apt-get -y install cuda

照做应该没啥问题。

验证是否安装:

/usr/local/cuda-11.4/bin/nvcc -V

当然cuda后面的版本号应该是你安装时最新的版本,不要照抄;甚至你之前可能会安装过旧版CUDA,注意分辨local下的文件夹版本号。

如果成功,一般会返回:

nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2021 NVIDIA Corporation
Built on Wed_Jun__2_19:15:15_PDT_2021
Cuda compilation tools, release 11.4, V11.4.48
Build cuda_11.4.r11.4/compiler.30033411_0

重新编译安装FFmpeg

将ffnvcodec拖到本地:

git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git

安装ffnvcodec:

cd nv-codec-headers && sudo make install && cd

将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 [...] --extra-cflags=-I/usr/local/cuda-11.4/include --extra-ldflags=-L/usr/local/cuda-11.4/lib64

编译选项里,有几项是跟GPU有关的:

--enable-nonfree
--enable-cuda
--enable-cuvid
--enable-nvenc
--enable-libnpp

CUDA的版本不一样,对应的命令不一样(比如11.4的CUDA并没有文件里写的--enable-cuda-sdk),需要手动查一下这几个命令哪个是默认开启的哪个默认没有开启。

例我自己:

./configure --enable-nonfree --enable-libnpp --extra-cflags=-I/usr/local/cuda-11.4/include --extra-ldflags=-L/usr/local/cuda-11.4/lib64

重新安装完成后查看硬件加速选项:

ffmpeg -hwaccels

这个版本支持的硬件加速:

Hardware acceleration methods:
vdpau
cuda
vaapi
drm
opencl
cuvid

cuvid就是N卡的GPU硬件加速选项。查看cuvid提供的编解码器:

ffmpeg -codecs | grep cuvid

可以看到:

 DEV.LS h264                 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (decoders: h264 h264_v4l2m2m h264_cuvid ) (encoders: libx264 libx264rgb h264_nvenc h264_omx h264_v4l2m2m h264_vaapi nvenc nvenc_h264 )
 DEV.L. hevc                 H.265 / HEVC (High Efficiency Video Coding) (decoders: hevc hevc_v4l2m2m hevc_cuvid ) (encoders: libx265 nvenc_hevc hevc_nvenc hevc_v4l2m2m hevc_vaapi )
 DEVIL. mjpeg                Motion JPEG (decoders: mjpeg mjpeg_cuvid ) (encoders: mjpeg mjpeg_vaapi )
 DEV.L. mpeg1video           MPEG-1 video (decoders: mpeg1video mpeg1_v4l2m2m mpeg1_cuvid )
 DEV.L. mpeg2video           MPEG-2 video (decoders: mpeg2video mpegvideo mpeg2_v4l2m2m mpeg2_cuvid ) (encoders: mpeg2video mpeg2_vaapi )
 DEV.L. mpeg4                MPEG-4 part 2 (decoders: mpeg4 mpeg4_v4l2m2m mpeg4_cuvid ) (encoders: mpeg4 libxvid mpeg4_v4l2m2m )
 D.V.L. vc1                  SMPTE VC-1 (decoders: vc1 vc1_v4l2m2m vc1_cuvid )
 DEV.L. vp8                  On2 VP8 (decoders: vp8 vp8_v4l2m2m libvpx vp8_cuvid ) (encoders: libvpx vp8_v4l2m2m vp8_vaapi )
 DEV.L. vp9                  Google VP9 (decoders: vp9 vp9_v4l2m2m libvpx-vp9 vp9_cuvid ) (encoders: libvpx-vp9 vp9_vaapi )

大家伙一眼看过去就很亲切的应该是h264hevc吧,下各大压制组/字幕组的片子下得多了经常见到,其中decoders是解码器的名字,encoders是编码器的名字。一般我们就用h264压片的最多。

Win10下调用GPU为FFmpeg加速

这个可简单多了,主要是Windows下已经有人帮忙把FFmpeg编译好了。

主要参考文章:Windows 下使用GPU加速ffmpeg处理任务

安装CUDA

下载:CUDA Toolkit Downloads(截止本文发布时间为止,最新版本为CUDA Toolkit 11.4)

是什么系统选什么,例我自己:Windows - x86_64 - 10 - exe[local]

然后运行下载好的文件一步步跟着向导来就行了。

最好是自定义全装,不要精简安装。

直接下载FFmpeg Windows Builds

下载:FFmpeg 各版本下载

是什么系统选什么,FFmpeg给出了两个已经编译好的版本:Windows builds from gyan.devWindows builds by BtbN,都行吧其实。我采用的是gyan.dev的版本。

下载好后解压到文件夹,进入文件夹后在进入bin文件夹,按住Shift选择在此处打开Powershell窗口,使用./ffmpeg.exe就可以跟Linux上一样使用命令行运行FFmpeg。

压片命令

我和姐姐调了半天觉得比较合适的参考命令:

ffmpeg -hwaccel cuvid -c:v h264_cuvid -i "input.mkv" -c:v h264_nvenc -b:v 2048k "output.mkv"

Windows下把ffmpeg换成./ffmpeg.exe,记得填上前面的文件夹路径(当然应该可以设置命令替代但我不太在Win下工作所以没弄)。

一些参数说明:

  • -hwaccel cuvid:使用cuvid进行硬件加速
  • -c:v h264_cuvid:使用h264_cuvid进行解码
  • -c:v h264_nvenc:使用h264_nvenc进行编码
  • -b:v 2000k:Video Bitrate,我的源(1080P)的原始vb大概是4100k左右,高清片的这个参数数值估计应该就在4000k上下;压到2000k大概属于“画质确实能感觉到变差但勉强能看”的程度吧(但反正我主要是存移动设备上方便查看就无所谓了)。

参考时间: 长度两个半小时,大小接近5个G的片子压完大概用了十分钟不到。

由于h264_nvenc编码不能直接用CRF参数了,另补一条用起来(cq)差不多的:

ffmpeg -hwaccel cuvid -c:v h264_cuvid -i "input.mkv" -preset:v p7 -tune:v hq -rc:v vbr -cq:v 23 -b:v 0 -profile:v high -c:a copy "output.mkv"

关于字幕压制

压制字幕时需要用到-vf添加字幕,但在cuvid硬件加速下无法使用对应的滤镜,需要更改为cuda加速。

ffmpeg -hwaccel cuda -c:v h264_cuvid -i input.mp4 -c:v h264_nvenc -vf "subtitles=sub.ass" -b:v 0 -c:a copy output.mp4

无关正文的部分

Win下用IDM拖各种LIVE源那真是效果拔群……到Linux下就稍微有点麻烦,需要借助一些插件辅助,我还没找到特别好用的拖.m3u8的工具(我比较希望能推到aria2里下载,但还没找到好的办法做这个事情),如果有推荐的工具欢迎在本文下留言。

7月5日的更新:没找到趁手的,干脆自己写了一个……

脚本:m3u8-dl-with-aria2

使用方法:创建一个文本文件,例如info.txt,文件第一行贴上.m3u8文件的地址,第二行贴上对应的cookie——解决只有登录才能观看的内容的下载。

执行:

chmod +x m3u8-dl-with-aria2.sh
./m3u8-dl-with-aria2.sh info.txt

一般LIVE的流存下来都是.ts,无损转换到mkv:

ffmpeg -hwaccel cuvid -c:v h264_cuvid -i "input.ts" -map 0 -vcodec copy -acodec copy -f matroska "output.mkv"

一些参数说明:

  • -map:规定输入文件的哪条流进行输出,-map 0:0 -map 0:1代表输入文件#0的第一、二条流都进行输出,-map 0代表#0的流全部进行输出,更细致的用法参考Selecting streams with the -map option
  • -vcodec copy:规定视频流编解码器,copy表示不做编解码。
  • -acodec copy:规定音频流编解码器,copy表示不做编解码。
  • -f matroska:输出格式,.mkv是Matroska封装下的文件格式。
- End -
Comments
Write a Comment
  • wellsleep reply

    膜拜脚本大神!

    win下和linux下的压制效率有差异吗?

    • @wellsleep 两边都试了一下,没有体感差异……Linux下全套会快一点,应该是因为aria2开了多线程而IDM下只能单线程下载,下载时间不同导致的,压制本身的时间感觉差不多(

  • ZERO reply

    正好我最近也在研究ffmpeg,找到了一个挺小白的工具,拖进视频直接就能显卡加速地压制视频。也能用nvenc,应该跟你的方法效果差不多,只是不用配置了,下载直接用。https://github.com/hoshinohikari/StarTools/blob/master/README_CN.md

    • @ZERO 啊,是Windows工具啊……FFmpeg本身用起来倒是很简单反正命令行回车而已,费事的是m3u8的截流合并其实(