GPU视频转码研究

参考文档

CUDA 简介

CUDA (Compute Unified Device Architecture)

CUDA® is a parallel computing platform and programming model developed by NVIDIA for general computing on graphical processing units (GPUs).

With CUDA, developers are able to dramatically speed up computing applications by harnessing the power of GPUs.

In GPU-accelerated applications, the sequential part of the workload runs on the CPU – which is optimized for single-threaded performance – while the compute intensive portion of the application runs on thousands of GPU cores in parallel.

When using CUDA, developers program in popular languages such as C, C++, Fortran, Python and MATLAB and express parallelism through extensions in the form of a few basic keywords.

NVENC & NVDEC

FFmpeg可通过Nvidia的GPU进行加速,其中高层接口是通过Video Codec SDK来实现GPU资源的调用。

Video Codec SDK包含完整的的高性能工具、源码及文档,支持,可以运行在Windows和Linux系统之上。

从软件上来说,SDK包含两类硬件加速接口:

  • 用于编码加速的 NVENCODE API
  • 用于解码加速的 NVDECODE API(之前被称为NVCUVID API)

VCSDK_006a.png

从硬件上来说,Nvidia GPU有一到多个编解码器(解码器又称硬件加速引擎),它们独立于CUDA核

Video Codec SDK已经被集成在ffmpeg工程中,但是ffmpeg对编解码器配置参数较少,如果需要充分的发挥编解码器特性,还需要直接使用SDK进行编程。

服务器硬盘情况

## 分区
fdisk -l  
mkfs.ext4 /dev/sdb

mkdir /sas  
mount /dev/sdb /sas

mkfs.ext4 /dev/sdc  
mkdir /test  
mount /dev/sdc /test

df -h

## 开机挂载
# 查看磁盘UUID信息
blkid  
# 在 /etc/fstab 追加以下信息
echo "UUID=xxx  /test  ext4    defaults 0 0" >> /etc/fstab  
echo "UUID=xxx  /test1  ext4    defaults 0 0" >> /etc/fstab  
OR  
echo "/dev/sdb                /sas                    ext4    defaults        0 0" >> /etc/fstab  
echo "/dev/sdc                /test                   ext4    defaults        0 0" >> /etc/fstab  
# 或者使用 vim

服务器硬件检测

# 查看CPU信息(型号)
[root@localhost ~]# cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c
32  Intel(R) Xeon(R) CPU E5-2620 v4 @ 2.10GHz

# 查看物理CPU个数
[root@localhost ~]# cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
2

# 查看每个物理CPU中core的个数(即核数)
[root@localhost ~]# cat /proc/cpuinfo| grep "cpu cores"| uniq
cpu cores    : 8

# 查看逻辑CPU的个数
[root@localhost ~]# cat /proc/cpuinfo| grep "processor"| wc -l
32

# 查看内存
[root@localhost ~]# cat /proc/meminfo | grep MemTotal
MemTotal:       32759216 kB

# 查看显卡
lspci -vnn | grep VGA -A 12

# 查看显卡驱动
lspci | grep -i vga  
# 查看显卡驱动详情
lspci -v -s XX:XX.X

# 对于nvidia显卡的话可以用nvidia-smi命令来查
nvidia-smi

# lshw 也可以获取显卡信息
#yum install -y lshw
lshw -C display

# 查看当前 Linux 系统上所使用的显卡驱动名称
lshw -c video | grep configuration

# 检查显卡驱动详情
modinfo ${driver}  
modinfo nvidia  

ffmpeg HLS 转码命令

# 测试命令
TRANSTIME=`date +%Y%m%d%H%M%S`"_"${i}  
mkdir -p /test/outputs/$TRANSTIME/  
ffmpeg -y -hide_banner -hwaccel cuvid -c:v h264_cuvid -i /test/Batman.mkv -c:v h264_nvenc -c:a aac -map 0 -f ssegment -segment_format mpegts -segment_list /test/outputs/$TRANSTIME/batman.m3u8 -segment_time 10 /test/outputs/$TRANSTIME/out%03d.ts

### 压缩硬字幕
-codec:s dvdsub -f vob 
-codec:s dvdsub
### 对于有软字幕
-c:s mov_text

ffmpeg -y -hide_banner -hwaccel cuvid -c:v h264_cuvid -i /test/Inception.mkv  -codec:s dvdsub -f vob -c:v h264_nvenc -c:a aac -map 0 -f ssegment -segment_format mpegts -segment_list /test/outputs/$TRANSTIME/Inception.m3u8 -segment_time 10 /test/outputs/$TRANSTIME/out%03d.ts  

其中部分参数含义:

-y :同文件覆盖的支持
-hide_banner :隐藏编译信息
-hwaccel cuvid :开启GPU硬件转码支持
-i :原始文件路径
-c:v :视频编/解码(放在 -i 前,为指定解码器)
-c:a :音频编/解码
...

使用GPU转码时,不同的视频编码需要对应不同的 cuvid 视频解码器支持

使用如下命令可查看 nvidia 硬件解码器支持:

# ffmpeg -hide_banner -codecs | grep cuvid

...
 DEV.LS h264                 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (decoders: h264 h264_cuvid ) (encoders: libx264 libx264rgb h264_nvenc nvenc nvenc_h264 )
 DEV.L. hevc                 H.265 / HEVC (High Efficiency Video Coding) (decoders: hevc hevc_cuvid ) (encoders: nvenc_hevc hevc_nvenc )
 DEVIL. mjpeg                Motion JPEG (decoders: mjpeg mjpeg_cuvid )
 DEV.L. mpeg1video           MPEG-1 video (decoders: mpeg1video mpeg1_cuvid )
 DEV.L. mpeg2video           MPEG-2 video (decoders: mpeg2video mpegvideo mpeg2_cuvid )
 DEV.L. mpeg4                MPEG-4 part 2 (decoders: mpeg4 mpeg4_cuvid )
 D.V.L. vc1                  SMPTE VC-1 (decoders: vc1 vc1_cuvid )
 D.V.L. vp8                  On2 VP8 (decoders: vp8 vp8_cuvid )
 D.V.L. vp9                  Google VP9 (decoders: vp9 vp9_cuvid )

使用如下命令可查看 nvidia 硬件编码器支持:

# ffmpeg -hide_banner -codecs | grep nvenc
...
 DEV.LS h264                 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (decoders: h264 h264_cuvid ) (encoders: libx264 libx264rgb h264_nvenc nvenc nvenc_h264 )
 DEV.L. hevc                 H.265 / HEVC (High Efficiency Video Coding) (decoders: hevc hevc_cuvid ) (encoders: nvenc_hevc hevc_nvenc )

其中前缀含义如下:

D….. = Decoding supported
.E…. = Encoding supported
..V… = Video codec
..A… = Audio codec
..S… = Subtitle codec
…I.. = Intra frame-only codec
….L. = Lossy compression
…..S = Lossless compression

查看视频文件编码(metadata)

不要使用 ffmpeg

ffmpeg -hide_banner -i xxx.mp4  
# 会报 At least one output file must be specified 错误,不利于程序获取

使用 ffprobe 查看:

ffprobe -hide_banner xxx.mp4  

具体可参考:查看媒体文件头信息工具ffprobe

ffmpeg 编译命令

[root@download opt]# /opt/ffmpeg-3.4.2-acc-cuda/bin/ffmpeg -h
ffmpeg version 3.4.2 Copyright (c) 2000-2018 the FFmpeg developers  
  built with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-18)
  configuration: --enable-shared --prefix=/opt/ffmpeg-3.4.2-acc-cuda --enable-libnpp --enable-libmp3lame --enable-libvorbis --enable-gpl --enable-pthreads --enable-debug --enable-version3 --enable-nonfree --enable-libfdk-aac --enable-libx264 --enable-ffserver --enable-ffplay --enable-cuda --enable-cuvid --enable-nvenc --enable-nonfree --disable-x86asm --extra-cflags=-I/usr/local/cuda-9.1/include --extra-ldflags=-L/usr/local/cuda-9.1/lib64
  libavutil      55. 78.100 / 55. 78.100
  libavcodec     57.107.100 / 57.107.100
  libavformat    57. 83.100 / 57. 83.100
  libavdevice    57. 10.100 / 57. 10.100
  libavfilter     6.107.100 /  6.107.100
  libswscale      4.  8.100 /  4.  8.100
  libswresample   2.  9.100 /  2.  9.100
  libpostproc    54.  7.100 / 54.  7.100
Hyper fast Audio and Video encoder  
./configure --enable-shared --prefix=/opt/ffmpeg-3.4.2-acc-cuda  --enable-libnpp --enable-libmp3lame --enable-libvorbis --enable-gpl --enable-pthreads --enable-debug --enable-version3 --enable-nonfree --enable-libfdk-aac --enable-libx264 --enable-ffserver --enable-ffplay --enable-cuda --enable-cuvid --enable-nvenc --enable-nonfree --disable-x86asm --extra-cflags="-I/usr/local/cuda-9.1/include" --extra-ldflags="-L/usr/local/cuda-9.1/lib64" 

详细安装方法见编译安装ffmpeg3.4.2