NVIDIA Encoding and Decoding Hardware
NVIDIA GPUs ship with an on-chip hardware encoder and decoder unit often referred to as NVENC and NVDEC. Separate from the CUDA cores, NVENC/NVDEC run encoding or decoding workloads without slowing the execution of graphics or CUDA workloads running at the same time.
NVENC and NVDEC support the many important codecs for encoding and decoding. Figure 1 lists many of the codecs, format and features supported with current NVIDIA hardware. Actual support depends on the GPU that is used. An up-to-date support matrix can be found at the Video Encode and Decode Support Matrix page.
Figure 1: GPU hardware capabilities
Hardware accelerated transcoding with FFmpeg
Separate from the CUDA cores, NVENC/NVDEC run encoding or decoding workloads without slowing the execution of graphics or CUDA workloads running at the same time.
Using the FFmpeg library is common practice when transcoding video data. Hardware acceleration dramatically improves the performance of the workflow. Figure 2 shows the different elements of the transcoding process with FFmpeg.
Figure 2: Transcoding pipeline with FFmpeg using NVIDIA hardware acceleration
FFmpeg supports hardware accelerated decoding and encoding via the hwaccel cuda, h264_cuvid, hevc_cuvid and h264_nvenc, hevc_nvenc modules. Activating support for hardware acceleration when building from source requires some extra steps:
- Clone the FFmpeg git repository https://git.ffmpeg.org/ffmpeg.git
- Download and install a compatible driver from the NVIDIA web site
- Download and install the CUDA toolkit
- Clone the nv-codec-headers repository and install using this repository as header-only: make install
- Configure FFmpeg using the following command (use correct CUDA library path):
./configure --enable-cuda --enable-cuvid --enable-nvdec --enable-nvenc --enable-nonfree --enable-libnpp --extra-cflags=-I/usr/local/cuda/include --extra-ldflags=-L/usr/local/cuda/lib64
- Build with multiple processes to increase build speed and suppress excessive output: make -j -s
Using FFmpeg to do software 1:1 transcode is simple:
ffmpeg -i input.mp4 -c:a copy -c:v h264 -b:v 5M output.mp4
But this is going to be slow slow since it only uses the CPU-based software encoder and decoder. Using the hardware encoder NVENC and decoder NVDEC requires adding some more parameters to tell ffmpeg which encoder and decoders to use.
Maximizing the transcoding speed also means making sure that the decoded image is kept in GPU memory so the encoder can efficiently access it.
ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 -c:v h264_nvenc -b:v 5M output.mp4
-hwaccel cuda |
cho |