Recently, I am developing a video analysis system based on video streams. When using the browser to play the finished video, the browser needs the fmp4 format stream, which needs to be transcoded by ffmpeg. During the development phase, the CPU version of ffmpeg was used, but the online deployment was very unsatisfactory. So I compiled a GPU version.

System Architecture

1
2
3
4
5
6
7
+----------------------------------------------------------------+
|                                                                |
|                          /--queue-->ffmpeg-->\                 |
| rtsp h.264--open cv --->                      -->merge--> web  |
|                          \--queue-->models-->/                 |
|                                                                |
+----------------------------------------------------------------+

Compile

Compiling hardware-accelerated ffmpeg from source code requires several steps

  1. Download the ffmpeg source code https://git.ffmpeg.org/ffmpeg.git
  2. download the Nvidia driver
  3. install CUDA toolkit
  4. download nv-codec-headers source code https://github.com/FFmpeg/nv-codec-headers.git
  5. install nasm yasm pkgconf

Compilation steps

Since I have the specified version of the Nvidia driver and CUDA toolkit installed locally, I skip these two steps.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
apt install -y nasm yasm pkgconf
git clone https://git.ffmpeg.org/ffmpeg.git
git clone https://github.com/FFmpeg/nv-codec-headers.git

# 切换到你想要的tag版本,我这里nv-codec-headers使用的n9.0.18.3,ffmpeg使用的n4.2.2

# 设置 nv-codec-headers
cd nv-codec-headers
git checkout n9.0.18.3
make install
cd ..

# 编译ffmpeg
cd ffmpeg
git checkout n4.2.2
./configure --enable-cuda --enable-cuvid --enable-nvenc --enable-nonfree --enable-libnpp --extra-cflags=-I/usr/local/cuda/include  --extra-ldflags=-L/usr/local/cuda/lib64
make -j$(nproc)
make install

After the above steps, the GPU version of ffmpeg is compiled and tested to see if it works.

The original CPU version of the transcode command.

1
ffmpeg -i input.mp4 -c:a copy -c:v h264 -b:v 5M output.mp4

Modify the transcoding command to the GPU version.

1
ffmpeg -vsync 0 -hwaccel cuvid -c:v h264_cuvid -i input.mp4 -c:a copy -c:v h264_nvenc -b:v 5M output.mp4

The conversion was tested successfully.

Of course, in the video analysis system, it is not directly transcoded using the command line in this way, but through the input and output pipeline, and the input parameters and output parameters also need to be adjusted accordingly according to the actual encoding format.