Fast video encoding on Linux with Nvidia NVENC with SDK 7.5 and ffmpeg 3.0.2 on Nvidia GTX 960/970/980
- Tutorial

This article was written based on the article Effective video encoding in Linux with Nvidia NVENC: part 1, general , but has its own peculiarities and unlike the original article, at the time of writing of which there was no patch, which will be discussed later, I applied the reworked Nvidia Acceleration patch for FFmpeg 3.0.2, in addition to the nvenc encoder, it also received a quick resize filter - nvresize.
In total, I got the opportunity to hardware-encode video in H.264 and HEVC using the Nvidia GTX 960 graphics card on a rather weak computer (Xeon L5420) with a speed (for H.264) exceeding the capabilities of this processor by up to 10 times (and 3 times relative Core i7)! And on my favorite Debian 8 Jessie.
So, let's begin!
Technology
Nvidia NVENC is a technology that provides video encoding in H.264 and HEVC on GPU computing power. Important note: at the time of writing this article (May 2016), only second-generation Maxwell cards can provide any kind of high-quality and fast encoding, and for desktop ones: GM206 (GTX 950, GTX 960), GM204 (GTX 970 and GTX 980) (for references: there are still expensive Nvidia Tesla / Quadro / GRID professional lines, a full list can be found here) Moreover, the NVENC module works at the same speed on all cards and the number of CUDA cores does not affect performance, however strange it may sound, therefore it makes sense to take older versions only if the platform is used (in addition to coding) for games, and even more so, GM206 cards more appropriate since In addition to the encoder, they also received a hardware HEVC decoder. Important Note: The entire GeForce line has a license limit of 2 simultaneous streams. You can try to get around it using the method specified in the second part of YourChief article .
Implementation (FFmpeg)
The whole variety of Nvidia CUDA implementations can be viewed here . From myself, I want to say that for video the most common is the popular tool - FFmpeg. We will use it.
Hardware
Although this is commonplace, I will list the minimum necessary set of hardware requirements (based on real experience):
- Motherboard: with PCI-E support. I recommend the Intel platform because of the close connection of Intel-Nvidia and personal friendliness. Forgive me AMD fans!
- Processor: dual core, at least Core2 Duo. I recommend Core i3 and some cheap Xeon (yes!).
- Memory: DDR2 / 3/4, at least 2 GB. An interesting fact, with two coding streams, my total memory consumption is ~ 0.7 GB.
- Video card: any Nvidia 900 Series video card (I recommend GM206: GTX 950, GTX 960 or GM204: GTX 970, GTX 980). 2 GB or 4 GB, gaming or not - it does not matter! The main thing is to keep an eye on the dimensions and keep in mind that for all the GTX 960 models that I saw, additional power is connected from above.
- ATX PSU with additional power connector (6 pin is enough for our task). I recommend a power of at least 400 watts.
Software
Further narration is based on a certain basis of systems, programs and their specific versions. I will especially note that I specifically used Debian, and not Ubuntu, for which there is even an off. SDK packages I wanted to try to configure everything in my favorite distribution.
- Operating system: Debian 8 Jessie with optional Deb Multimedia repository
- Nvidia CUDA 7.5.18
- Nvidia SDK 6.0.1
- Ffmpeg 3.0.2
- Nvidia Acceleration patch , modified by me for compatibility with FFmpeg 3.0.2
Assembly
The most important of the files is the first one, with the driver. Only it is needed if you immediately want to install the package after it is built.
cd /usr/src
wget 'http://developer.download.nvidia.com/compute/cuda/7.5/Prod/local_installers/cuda_7.5.18_linux.run'
wget --no-check-certificate 'https://developer.nvidia.com/video-sdk-601' -O 'video-sdk-601.zip'
wget 'http://developer.download.nvidia.com/compute/redist/ffmpeg/1511-patch/cudautils.zip'
wget 'http://ffmpeg.org/releases/ffmpeg-3.0.2.tar.bz2'
wget 'http://kuzko.com/dl/ffmpeg_NVIDIA_gpu_acceleration.3.0.2.patch'4b3bcecf0dfc35928a0898793cf3e4c6 cuda_7.5.18_linux.run
24af45272ed2881f88ed534d3211b584 video-sdk-601.zip
f3f890bd314a568c47191810453cad2c cudautils.zip
7db5efb1070872823143e1365fdfcd53 ffmpeg-3.0.2.tar.bz2
a4f59f92675e02a0fa5c6cd124eda64e ffmpeg_NVIDIA_gpu_acceleration.3.0.2.patch0f366a88968b9eee01044de197e27764bc1567d6 cuda_7.5.18_linux.run
e57c7b4cfb298d4c725a0bb4477928e228dabb1c video-sdk-601.zip
edc818bef432d708466c5454974b9851523a86ba cudautils.zip
c40731a221fbfaa50671d69fe894bedd664f91e2 ffmpeg-3.0.2.tar.bz2
f305832ed42beeff7d7c26a00f79668b63b322ec ffmpeg_NVIDIA_gpu_acceleration.3.0.2.patchAdd the Deb Multimedia repository (it is required if you want to get / use FFmpeg, which is as close as possible to the one that Deb Multimedia uploads). This repository is required for my build!
echo -e 'deb http://www.deb-multimedia.org jessie main non-free\ndeb http://www.deb-multimedia.org jessie-backports main' > /etc/apt/sources.list.d/deb-multimedia.listNext we perform apt-get updateAnd set keyring: apt-get install deb-multimedia-keyringNow we update the system and install the packages required for building the driver. This step is also necessary!
apt-get update
apt-get -y dist-upgrade
apt-get -y install build-essential checkinstall dkms ccache pkg-config libglu1-mesa-dev libx11-dev libxi-dev libxmu-dev libxcb-shm0
Install Nvidia Driver, accept the agreement (accept), all other answers by default. If they warn that the system is not suitable, do not worry, this is normal! You can pass the -silent switch for quick installation, but go ahead yourself.
cd /usr/src
chmod +x cuda_7.5.18_linux.run
./cuda_7.5.18_linux.runThe choice of further action is up to you. You can either trust me and download the finished deb file (created through checkinstall) and skip the next steps, or perform manual assembly by installing the necessary libraries and compiling the package yourself through checkinstall.
cd /usr/src
wget 'http://kuzko.com/dl/ffmpeg_3.0.2-nvenc-7.5.18-nvresize-cudautils-20160523-1_amd64.deb'
dpkg -i ffmpeg_3.0.2-nvenc-7.5.18-nvresize-cudautils-20160523-1_amd64.deb
apt-get -f installIf you chose the bright side of the force, then let's continue, install the libraries required for the assembly (for this, among other things, we needed Deb Multimedia), prepare the header files, cudautils and apply the patch:
apt-get install -y --force-yes unzip libfdk-aac-dev libopencv-dev libiec61883-dev libavc1394-dev libass-dev libbluray-dev libbs2b-dev libkvazaar-dev libilbc2 libilbc-dev libopenh264-dev libsnappy-dev libsoxr-dev libxv1 libxcb-shape0 libxcb-shm0 yasm frei0r-plugins-dev libgnutls28-dev libopenjpeg-dev libopus-dev libpulse-dev librtmp-dev libspeex-dev libutvideo-dev libvidstab-dev libvo-amrwbenc-dev libvpx-dev libx265-dev libzvbi-dev libssl-dev libcdio-dev libcdio-paranoia-dev
cd /usr/src
unzip video-sdk-601.zip;
/bin/cp -prf nvidia_video_sdk_6.0.1/Samples/common/inc/nvCPUOPSys.h /usr/include
/bin/cp -prf nvidia_video_sdk_6.0.1/Samples/common/inc/nvEncodeAPI.h /usr/include
/bin/cp -prf nvidia_video_sdk_6.0.1/Samples/common/inc/nvFileIO.h /usr/include
/bin/cp -prf nvidia_video_sdk_6.0.1/Samples/common/inc/NvHWEncoder.h /usr/include
/bin/cp -prf nvidia_video_sdk_6.0.1/Samples/common/inc/nvUtils.h /usr/include
unzip cudautils.zip
cd cudautils
make
cd /usr/src
tar jxf ffmpeg-3.0.2.tar.bz2
cd ffmpeg-3.0.2
sed -i 's/ctx->outputs\[i\]->closed/ctx->outputs\[i\]->status/g' ../ffmpeg_NVIDIA_gpu_acceleration.3.0.2.patch
patch -Np1 -i ../ffmpeg_NVIDIA_gpu_acceleration.3.0.2.patchNow we are ready to execute the three main commands for building the package (configure / make / checkinstall).
I note a few points that you can change for yourself:
- --Enable-nvenc and --enable-nvresize were added (where without them!)
- Modified --extra-cflags and --extra-ldflags to include cudautils
- Removed --enable-opencl (could not find a library for it) and --enable-libtesseract (extra module in my opinion)
- FFmpeg is built without --enable-shared, although nothing prevents you from getting it back
- make -j10 can be changed to a specific one for your system (I used a build machine where threads + 2 = 10)
- I inserted the dependencies in checkinstall so that when installing from scratch, it was enough to run apt-get -f install and install the required packages, and not look through ldd for what else you need to install
- Also, due to imperfections, checkinstall had to perform several optional actions (removing conflicting dev packages and creating the / usr / share / ffmpeg folder)
cd /usr/src
cd ffmpeg-3.0.2
./configure --prefix=/usr --extra-cflags='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -I../cudautils ' --extra-ldflags='-Wl,-z,relro -L../cudautils ' --cc='ccache cc' --enable-libmp3lame --enable-gpl --enable-nonfree --enable-libvorbis --enable-pthreads --enable-libfaac --enable-libxvid --enable-postproc --enable-x11grab --enable-libgsm --enable-libtheora --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libx264 --enable-libspeex --enable-nonfree --enable-libvpx --enable-libschroedinger --disable-encoder=libschroedinger --enable-version3 --enable-libopenjpeg --enable-librtmp --enable-avfilter --enable-libfreetype --disable-decoder=amrnb --enable-libvo-amrwbenc --libdir=/usr/lib/x86_64-linux-gnu --disable-vda --enable-libbluray --enable-libcdio --enable-gnutls --enable-frei0r --enable-openssl --enable-libass --enable-libopus --enable-fontconfig --enable-libpulse --disable-mipsdsp --disable-mips32r2 --disable-msa --disable-mipsfpu --disable-mipsdspr2 --enable-libvidstab --enable-libzvbi --enable-avresample --enable-libutvideo --enable-libfdk-aac --enable-libx265 --enable-libbs2b --enable-libilbc --enable-libopenh264 --enable-libkvazaar --enable-libsnappy --enable-libsoxr --enable-libiec61883 --enable-vaapi --enable-libdc1394 --disable-altivec --shlibdir=/usr/lib/x86_64-linux-gnu --enable-nvenc --enable-nvresize
make -j10
apt-get -y remove libswscale-dev libavcodec-dev libswresample-dev libavutil-dev
mkdir -p /usr/share/ffmpeg
checkinstall --pkgname=ffmpeg --pkgversion "10:3.0.2-nvenc-7.5.18-nvresize-cudautils-`date +%Y%m%d`" --backup=no --requires='libcdio-paranoia1,libjack0,libasound2,libsdl1.2debian,libdc1394-22,libavc1394-0,libiec61883-0,libvidstab1.0,libbs2b0,libva1,libzvbi0,libx265-79,libx264-148,libvpx1,libvo-amrwbenc0,libutvideo15,libtheora0,libspeex1,libsoxr0,libsnappy1,libschroedinger-1.0-0,libopus0,libopenjpeg5,libopenh264-1,libopencore-amrwb0,libopencore-amrnb0,libmp3lame0,libkvazaar3,libilbc2,libgsm1,libfdk-aac1,libfaac0,libbluray1,libass5,libxcb-xfixes0,libcrystalhd3,libxvidcore4,libxv1,libxcb-shape0,libxcb-shm0' --defaultIf as a result you received a deb file, then accept my congratulations!
By the way, checkinstall may swear when installing the package. Not scary. Install (if not installed) the package manually via dpkg -i ffmpeg_3.0.2-nvenc-7.5.18-nvresize-cudautils-20160523-1_amd64.deb and then apt-get -f install to install the dependencies.
Nvenc and nvresize options
For some reason, not everyone knows what parameters nvenc and nvresize accept, and for this you just need to run ffmpeg with the -h switch:
Encoder nvenc_h264 [NVIDIA NVENC h264 encoder]:
General capabilities: delay
Threading capabilities: none
Supported pixel formats: yuv420p nv12
nvenc_h264 AVOptions:
-preset E..V.... Set the encoding preset (one of slow = hq 2pass, medium = hq, fast = hp, hq, hp, bd, ll, llhq, llhp, default) (default "hq")
-profile E..V.... Set the encoding profile (high, main, baseline)
-level E..V.... Set the encoding level restriction (auto, 1.0, 1.0b, 1.1, 1.2, ..., 4.2, 5.0, 5.1)
-tier E..V.... Set the encoding tier (main or high)
-cbr E..V.... Use cbr encoding mode (default false)
-2pass E..V.... Use 2pass encoding mode (default auto)
-gpu E..V.... Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on. (from 0 to INT_MAX) (default 0)
-delay E..V.... Delays frame output by the given amount of frames. (from 0 to INT_MAX) (default INT_MAX)
-enableaq E..V.... set to 1 to enable AQ (default false) Encoder nvenc_hevc [NVIDIA NVENC hevc encoder]:
General capabilities: delay
Threading capabilities: none
Supported pixel formats: yuv420p nv12
nvenc_hevc AVOptions:
-preset E..V.... Set the encoding preset (one of slow = hq 2pass, medium = hq, fast = hp, hq, hp, bd, ll, llhq, llhp, default) (default "hq")
-profile E..V.... Set the encoding profile (high, main, baseline)
-level E..V.... Set the encoding level restriction (auto, 1.0, 1.0b, 1.1, 1.2, ..., 4.2, 5.0, 5.1)
-tier E..V.... Set the encoding tier (main or high)
-cbr E..V.... Use cbr encoding mode (default false)
-2pass E..V.... Use 2pass encoding mode (default auto)
-gpu E..V.... Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on. (from 0 to INT_MAX) (default 0)
-delay E..V.... Delays frame output by the given amount of frames. (from 0 to INT_MAX) (default INT_MAX)
-enableaq E..V.... set to 1 to enable AQ (default false) Filter nvresize
GPU accelerated video resizer.
Inputs:
#0: default (video)
Outputs:
dynamic (depending on the options)
nvresize AVOptions:
outputs ..FV.... set number of outputs (from 1 to 16) (default 1)
readback ..FV.... read result back to FB (from 0 to 1) (default 0)
size ..FV.... set video size (default false)
s, ..FV.... set video size (default false)
gpu ..FV.... Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on. (from 0 to INT_MAX) (default 0)
force_original_aspect_ratio ..FV.... decrease or increase w/h if necessary to keep the original AR (from 0 to 2) (default 0) Expediency. What is all this for?
I will not give detailed benchmarks here (unless the community asks me to conduct certain tests), they are enough on the Internet, and the encoding speed of the card directly is approximately the same and more depends on the source video, resolution / bit rate of the encoded and additional processing (audio encoding, filtering).
frame = 7500 fps = 58 q = -1.0 Lsize = 107951kB time = 00: 05: 00.00 bitrate = 2947.8kbits / s speed = 2.32x
576p source, nvenc_h264, bitrate set to 3000k:
frame = 7500 fps = 804 q = -0.0 Lsize = 116997kB time = 00: 05: 00.00 bitrate = 3194.8kbits / s speed = 32.2x
At 1080p source (37 megabytes of source data at 10-15 megabits) the speed is 0.42x and 4.2x - Nvidia is again about 10 times faster .
When encoding 1080p in HEVC, it is painful to look at the processor, there the numbers are 0.08x and below, the card produces about 3x.
For a system on Core i7, the difference is not so big, but still the card is 3-4 times faster than x265 on HEVC 1080p (15000k) and 13 times on HEVC 576p (3000k). And this despite the fact that the i7 processor usually costs as much as the GTX 960 and more expensive.
As for the quality. I am a perfectionist, but I think that there are many applications for hardware encoding, as the decrease in quality is actually noticeably weak (I looked at both the Dell 24 "professional monitor and the 60" TV - all from close range) and only with the so-called pixel hunting. But the speed makes it possible to solve problems that are usually not able to be performed in real time on the processor.
I deliberately omitted details on the speed of nvresize, except for its parameters, because Although this is a very interesting and fast filter, its use is beyond the scope of this article.
I hope that my work will not be in vain and will help even more people to join the technology of hardware coding, bypassing some of the pitfalls, which I spent a lot of time solving. But it was worth it!
Article Updates
- TODO: Apply the patch to ffmpeg 3.1, because there appeared a hardware decoder (cuvid), which seriously helps with heavy coding.
- 08/18/2016: I fixed the patch before applying: ctx-> outputs [i] -> closed to ctx-> outputs [i] -> status, the file itself decided not to change so that the hashes converged.
- 05/25/2016: Added the GTX 950 to the list of supported ones, this is the latest GM206, like the GTX 960 and removed the untrue remark about the Quadro line, which also came out on the basis of the GM204 and GM206.
Only registered users can participate in the survey. Please come in.
Do you use hardware video encoding?
- 5.1% Yes, AMD VCE 11
- 19.5% Yes, Intel QSV 42
- 26.5% Yes, Nvidia NVENC 57
- 0.9% Yes, other (I will indicate in the comments) 2
- 12.5% No, quality above all 27
- 36.7% No, I do not encode video 79
- 9.3% What is it? 20