ffmpeg小记

Official Website:https://ffmpeg.org/

FFmpeg是啥

FFmpeg:a complete, cross-platform solution to record, convert and stream audio and video.

wiki:https://zh.wikipedia.org/wiki/FFmpeg

一个可以运行音频和视频多种格式的录影、转换、流功能的自由软件

FFmpeg转码

可以使用CPU/GPU两种方式进行视频编码,分别称为软编码和硬编码

软编码和硬编码如何区分

​ 软编码:使用CPU进行编码

​ 硬编码:使用非CPU进行编码,如显卡GPU、专用的DSP、FPGA、ASIC芯片等

软编码和硬编码比较

​ 软编码:实现直接、简单,参数调整方便,升级易,但CPU负载重,性能较硬编码低,低码率下质量通常比硬编码要好一点。

​ 硬编码:性能高,低码率下通常质量低于软编码器,但部分产品在GPU硬件平台移植了优秀的软编码算法(如X264)的,质量基本等同于软编码。

本文介绍GPU硬编码对视频转码的加速

硬件加速(HWAccel)是什么?有哪些GPU支持硬件加速?FFmpeg怎么做HWAccel?看FFmpeg官方文档:https://trac.ffmpeg.org/wiki/HWAccelIntro

可见,目前使用较多的是NVIDIA的GPU,相关资料也比较丰富。看NVIDIA官方文档:https://developer.nvidia.com/FFmpeg

(视频编码、解码和转码是 FFmpeg 的主要应用。 由于 FFmpeg 和 libav 社区的支持和 NVIDIA 工程师的贡献,这两个工具现在都支持通过集成 NVIDIA 视频编解码器 SDK 的硬件加速视频编码和解码。

利用 FFmpeg 的音频编解码器、流切换和 RTP 协议,FFmpeg 与 NVIDIA 视频编解码器 SDK 的集成使得高性能硬件加速的视频管道成为可能。

FFmpeg硬件加速

1. 下载FFmpeg及依赖库

安装依赖工具

1
> yum install autoconf automake bzip2 cmake freetype-devel gcc gcc-c++ git libtool make mercurial pkgconfig zlib-devel

ffmpeg官网下载 https://ffmpeg.org/download.html

2.下载安装NVIDIA驱动

https://www.nvidia.com/Download/index.aspx?lang=en-us 选择相应驱动下载

安装必要组件

1
> yum install gcc kernel-devel kernel-headers

找到kernel source,执行安装

1
> ./NVIDIA-Linux-x86_64-418.67.run --kernel-source-path=/usr/src/kernels/3.10.0-862.el7.x86_64 -k $(uname -r)

(中间可能会出错,参考https://askubuntu.com/questions/149206/how-to-install-nvidia-run 加上 –no-x-check 参数可解决)

会先安装32位兼容库,然后安装驱动

检查安装是否成功

1
> nvidia-smi

3.下载安装CUDA工具包

NVIDIA CUDA工具包为创建高性能GPU应用程序提供了开发环境 https://developer.nvidia.com/cuda-toolkit

官网下载CUDA:https://developer.nvidia.com/cuda-downloads?target_os=Linux&target_arch=x86_64&target_distro=CentOS&target_version=7&target_type=runfilelocal

执行安装

1
> ./cuda_10.1.105_418.39_linux.run

出错,查看安装日志 /var/log/cuda-installer.log。 You appear to be running an X server

执行

1
2
3
4
5
6
7
> service lightdm stop

> init 3

> ps ax | grep X

> kill -9 {X pid}

再次安装,成功。除了CUDA toolkits,还装上了samples,可供验证

配置环境变量 /etc/profile

1
2
export PATH=/usr/local/cuda-10.1/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-10.1/lib64:$LD_LIBRARY_PATH
1
> source /etc/profile

到samples目录,使用CUDA,例如对于deviceQuery例子,运行得到:

1
2
deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 10.1, CUDA Runtime Version = 10.1, NumDevs = 1
Result = PASS

4.编译FFmpeg

先安装 NVIDIA headers

1
2
3
4
5
6
7
> git clone https://[git.videolan.org/git](http://git.videolan.org/git)/ffmpeg/nv-codec-headers.git

> cd nv-codec-headers

> make

> sudo make install

接着编译FFmpeg

1
./configure   --prefix="$HOME/ffmpeg_build"   --pkg-config-flags="--static"   --extra-cflags="-I$HOME/ffmpeg_build/include -I/usr/local/cuda/include"   --extra-ldflags="-L$HOME/ffmpeg_build/lib -L/usr/local/cuda/lib64"   --extra-libs=-lpthread   --extra-libs=-lm   --bindir="$HOME/bin"   --enable-gpl   --enable-libfdk_aac    --enable-libmp3lame --enable-nonfree   --enable-cuda   --enable-cuvid   --enable-nvenc --enable-libnpp --enable-libx264

其中,libfdk_cc是ACC音频编码器,libmp3lame是MP3音频编码器,libx264是H.264视频编码器,这三项对x264编码视频是必须的。

cuda, cuvid, nvenc 是GPU加速相关的,必备。

gpl, libnpp未知,但也需要编译进去,否则转码带分辨率参数时会报错。

另外,nasm 和 yasm 两个汇编编译器需要提前安装,编译某些依赖库时会需要用到。

5.FFmpeg相关使用

help

1
> ffmpeg -h

通过ffprobe命令识别并输出视频信息

1
> ffprobe -v error -show_streams -print_format json <input>

查看是否支持编码

1
> ffmpeg -h encoder=libx264

查看支持的硬件加速选项

1
> ffmpeg -hwaccels

查看cuvid提供的GPU编解码器

1
> ffmpeg -codecs | grep cuvid

转码一个单一的视频文件:

不用GPU加速

1
> time ffmpeg -i 001.mp4 -c:v libx264 -b:v 2048k -vf scale=1280:-1 -y 001_output.mp4

使用GPU加速

1
> time ffmpeg -hwaccel cuvid -c:v h264_cuvid -i 001.mp4 -b:v 2048k -vf scale=1280:-1 -y -c:v h264_nvenc 002_output.mp4
  • -c:v:指定编码器,编码器列表可以使用ffmpeg -codecs查看
  • -vf scale:指定输出视频的宽高,高-1代表按照比例自动适应
  • -b:v:指定输出视频的码率,即输出视频每秒的bit数
  • -hwaccel cuvid:指定使用cuvid硬件加速
  • -c:v h264_cuvid:使用h264_cuvid进行视频解码
  • -c:v h264_nvenc:使用h264_nvenc进行视频编码
  • -vf scale_npp=1280:-1:指定输出视频的宽高,注意,这里和软解码时使用的-vf scale=x:x不一样