Skip to content

Instantly share code, notes, and snippets.

@ProTechEx
Last active May 20, 2022 15:56
Show Gist options
  • Save ProTechEx/23ff36be2c059c88024a8db9b7236470 to your computer and use it in GitHub Desktop.
Save ProTechEx/23ff36be2c059c88024a8db9b7236470 to your computer and use it in GitHub Desktop.
simplified-ffmpeg-build-qsv-nvenc-vaapi.md

FFmpeg build for NVIDIA & Intel hardware on Ubuntu 18.04LTS+:

Build platform: Ubuntu 18.04LTS

Goals: Generate an FFmpeg build that can utilize NVENC hardware acceleration on NVIDIA-based systems on Ubuntu 18.04LTS+.

First steps:

Purge all NVIDIA drivers first:

sudo apt -y purge nvidia* && sudo apt -y autoremove

We will install new drivers down the line.

Ensure the platform is up to date:

sudo apt update && sudo apt -y upgrade && sudo apt -y dist-upgrade

Install baseline dependencies first (inclusive of OpenCL headers+)

sudo apt-get -y install autoconf automake build-essential libass-dev libtool \
pkg-config texinfo zlib1g-dev cmake mercurial \
git libssl-dev rtmpdump librtmp-dev libunistring2 libunistring-dev \
libz3-dev libzvbi-dev libzvbi0 ninja-build perl clang \
asciidoc libfont-ttf-perl xmlto \
libxml2 libxml2-dev libxml2-doc libxml2-utils meson

Prepare the workspace:

You will need extras for QSV+VAAPI enablement. Install them now:

sudo apt-get -y install libdrm-dev git libx11-dev \
libperl-dev libpciaccess-dev libpciaccess0 xorg-dev \
intel-gpu-tools opencl-headers libwayland-dev xutils-dev libssl-dev

Setup build environment:

Work space init:

mkdir -p ~/vaapi
mkdir -p ~/ffmpeg_build
mkdir -p ~/ffmpeg_sources
mkdir -p ~/bin

Build the dependency chain as shown, starting with installing the latest build of libdrm. This is needed to enable the cl_intel_va_api_media_sharing extension, needed when deriving OpenCL device initialization interop in FFmpeg, as illustrated later on in the documentation:

cd ~/vaapi
git clone https://gitlab.freedesktop.org/mesa/drm
cd drm
mkdir -p build
cd build
meson --prefix=/usr -Dudev=true
ninja
sudo ninja install
sudo ldconfig -vvvv

Then proceed with libva:

1. Libva :

Libva is an implementation for VA-API (Video Acceleration API)

VA-API is an open-source library and API specification, which provides access to graphics hardware acceleration capabilities for video processing. It consists of a main library and driver-specific acceleration backends for each supported hardware vendor. It is a prerequisite for building the VAAPI driver components below.

cd ~/vaapi
git clone https://github.com/intel/libva
cd libva
./autogen.sh --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu
time make -j$(nproc) VERBOSE=1
sudo make -j$(nproc) install
sudo ldconfig -vvvv

2. Gmmlib:

The Intel(R) Graphics Memory Management Library provides device specific and buffer management for the Intel(R) Graphics Compute Runtime for OpenCL(TM) and the Intel(R) Media Driver for VAAPI.

The component is a prerequisite to the Intel Media driver build step below.

To build this, create a workspace directory within the vaapi sub directory and run the build:

mkdir -p ~/vaapi/workspace
cd ~/vaapi/workspace
git clone https://github.com/intel/gmmlib
mkdir -p build
cd build
cmake -DCMAKE_BUILD_TYPE= Release ../gmmlib
make -j$(nproc)

Optional, SKIP as the media-driver step does this for you: Then install the package:

sudo make -j$(nproc) install 

And proceed.

3. Intel Media driver:

The Intel(R) Media Driver for VAAPI is a new VA-API (Video Acceleration API) user mode driver supporting hardware accelerated decoding, encoding, and video post processing for GEN based graphics hardware, released under the MIT license.

cd ~/vaapi/workspace
git clone https://github.com/intel/media-driver
cd media-driver
git submodule init
git pull
mkdir -p ~/vaapi/workspace/build_media
cd ~/vaapi/workspace/build_media

Configure the project with cmake:

cmake ../media-driver \
-DBS_DIR_GMMLIB=$PWD/../gmmlib/Source/GmmLib/ \
-DBS_DIR_COMMON=$PWD/../gmmlib/Source/Common/ \
-DBS_DIR_INC=$PWD/../gmmlib/Source/inc/ \
-DBS_DIR_MEDIA=$PWD/../media-driver \
-DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_INSTALL_LIBDIR=/usr/lib/x86_64-linux-gnu \
-DINSTALL_DRIVER_SYSCONF=OFF \
-DLIBVA_DRIVERS_PATH=/usr/lib/x86_64-linux-gnu/dri

Then build the media driver:

time make -j$(nproc) VERBOSE=1

Then install the project:

sudo make -j$(nproc) install VERBOSE=1

Add yourself to the video group:

sudo usermod -a -G video $USER

Now, export environment variables as shown below:

LIBVA_DRIVERS_PATH=/usr/lib/x86_64-linux-gnu/dri
LIBVA_DRIVER_NAME=iHD

Put that in /etc/environment.

And for the opensource driver (fallback, see notice below):

Export environment variables as shown below:

LIBVA_DRIVERS_PATH=/usr/lib/x86_64-linux-gnu/dri
LIBVA_DRIVER_NAME=iHD

Put that in /etc/environment.

Notice: You should ONLY use the i965 driver for testing and validation only. For QSV-based deployments in production, ensure that iHD is the value set for the LIBVA_DRIVER_NAME variable, otherwise FFmpeg's QSV-based encoders will fail to initialize. Note that VAAPI is also supported by the iHD driver albeit to a limited feature-set, as explained in the last section.

Fallback for the Intel Opensource VAAPI driver:

Again, this can be skipped safely as the PPA has the latest code:

  1. cmrt:

This is the C for Media Runtime GPU Kernel Manager for Intel G45 & HD Graphics family. it's a prerequisite for building the intel-hybrid-driver package on supported platforms.

cd ~/vaapi
git clone https://github.com/01org/cmrt
cd cmrt
./autogen.sh --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu
time make -j$(nproc) VERBOSE=1
sudo make -j$(nproc) install
  1. intel-hybrid-driver:

This package provides support for WebM project VPx codecs. GPU acceleration is provided via media kernels executed on Intel GEN GPUs. The hybrid driver provides the CPU bound entropy (e.g., CPBAC) decoding and manages the GEN GPU media kernel parameters and buffers.

This package grants access to the VPX-series hybrid decode capabilities on supported hardware configurations,, namely Haswell and Skylake. Do not build this target on unsupported platforms.

Related, see this commit regarding the hybrid driver initialization failure on platforms where its' not relevant.

cd ~/vaapi
git clone https://github.com/01org/intel-hybrid-driver
cd intel-hybrid-driver
./autogen.sh --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu
time make -j$(nproc) VERBOSE=1
sudo make -j$(nproc) install
  1. intel-vaapi-driver:

This package provides the VA-API (Video Acceleration API) user mode driver for Intel GEN Graphics family SKUs. The current video driver back-end provides a bridge to the GEN GPUs through the packaging of buffers and commands to be sent to the i915 driver for exercising both hardware and shader functionality for video decode, encode, and processing.

it also provides a wrapper to the intel-hybrid-driver when called up to handle VP8/9 hybrid decode tasks on supported hardware (when configured with the --enable-hybrid-codec option as shown below:).

cd ~/vaapi
git clone https://github.com/01org/intel-vaapi-driver
cd intel-vaapi-driver
./autogen.sh --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu --enable-hybrid-codec
time make -j$(nproc) VERBOSE=1
sudo make -j$(nproc) install

However, on Kabylake and newer, omit this as shown since its' not needed:

cd ~/vaapi
git clone https://github.com/intel/intel-vaapi-driver
cd intel-vaapi-driver
./autogen.sh --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu 
time make -j$(nproc) VERBOSE=1
sudo make -j$(nproc) install

Proceed:

4. libva-utils:

This package provides a collection of tests for VA-API, such as vainfo, needed to validate a platform's supported features (encode, decode & postproc attributes on a per-codec basis by VAAPI entry points information).

cd ~/vaapi
git clone https://github.com/intel/libva-utils
cd libva-utils
./autogen.sh --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu
time make -j$(nproc) VERBOSE=1
sudo make -j$(nproc) install

At this point, issue a reboot:

sudo systemctl reboot

Then on resume, proceed with the steps below, installing the Intel OpenCL platform (Neo):

Before you proceed with the iMSDK:

It is recommended that you install the Intel Neo OpenCL runtime:

Justification: This will allow for Intel's MediaSDK OpenCL inter-op back-end to be built.

Note: There's also a Personal Package Archive (PPA) for this that you can add, allowing you to skip the manual build step, as shown:

sudo add-apt-repository ppa:intel-opencl/intel-opencl
sudo apt-get update

Then install the packages:

sudo apt install intel-mkl-full libigc libigc-dev intel-opencl-icd libze-intel-gpu --install-recommends -y

Then proceed.

Testing:

Use clinfo and confirm that the ICD is detected.

4. Build Intel's MSDK:

This package provides an API to access hardware-accelerated video decode, encode and filtering on Intel® platforms with integrated graphics. It is supported on platforms that the intel-media-driver is targeted for.

For supported features per generation, see this.

Build steps:

Fetch its' dependencies:

sudo apt -y install libx11-xcb1 libx11-xcb-dev libx11-xcb-perl libxcb-present0 libxcb-present-dev \
libxcb-dri3-0 libxcb-dri3-dev

(a). Fetch the sources into the working directory ~/vaapi:

cd ~/vaapi
git clone https://github.com/Intel-Media-SDK/MediaSDK msdk
cd msdk
git submodule init
git pull

(b). Configure the build:

mkdir -p ~/vaapi/build_msdk
cd ~/vaapi/build_msdk
cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_WAYLAND=ON -DENABLE_X11_DRI3=ON -DENABLE_OPENCL=ON  ../msdk
time make -j$(nproc) VERBOSE=1
sudo make install -j$(nproc) VERBOSE=1

CMake will automatically detect the platform you're on and enable the platform-specific hooks needed for a working build.

Create a library config file for the iMSDK:

sudo nano /etc/ld.so.conf.d/imsdk.conf

Content:

/opt/intel/mediasdk/lib
/opt/intel/mediasdk/include

Then run:

sudo ldconfig -vvvv

To proceed.

When done, issue a reboot:

 sudo systemctl reboot

Install CUDA 11 SDK :

Ensure that you have the latest driver:

sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt-get update && sudo apt-get -y upgrade && sudo apt -y autoremove

On Ubuntu 18.04LTS+ server systems, this will do:

sudo apt -y install nvidia-headless-450 nvidia-utils-450 libnvidia-common-450 libnvidia-encode-450 libnvidia-decode-450 libnvidia-fbc1-450

On Ubuntu 18.04LTS+ desktop, this should be enough for the device driver:

sudo apt-get -y install nvidia-kernel-source-450 nvidia-driver-450

For R455+:

sudo apt-get -y install nvidia-kernel-source-455 nvidia-driver-455

See to it that HWE is also installed IF you are on Ubuntu 18.04:

sudo apt-get -y install --install-recommends linux-generic-hwe-18.04

We keep the device driver up to the latest version so as to pass ffnvcodec driver version check.

Install CUDA from the repository:

(a). Ubuntu 20.04 LTS:

cd ffmpeg_sources
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/7fa2af80.pub
sudo add-apt-repository "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/ /"
sudo apt-get update
apt-get -y install cuda-compiler-11-1 cuda-libraries-11-1 cuda-libraries-dev-11-1

(b). Ubuntu 18.04LTS:

cd ffmpeg_sources
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin
sudo mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub
sudo add-apt-repository "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/ /"
sudo apt-get update
apt-get -y install cuda-compiler-11-0 cuda-libraries-11-0 cuda-libraries-dev-11-0

Notes:

For Maxwell GPUs, stick to cuda-10-2 instead:

(a). Ubuntu 20.04 LTS:

cd ffmpeg_sources
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/7fa2af80.pub
sudo add-apt-repository "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/ /"
sudo apt-get update
sudo apt-get -y install cuda-compiler-10-2 cuda-libraries-10-2 cuda-libraries-dev-10-2

(b). Ubuntu 18.04LTS:

cd ffmpeg_sources
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin
sudo mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub
sudo add-apt-repository "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/ /"
sudo apt-get update
sudo apt-get -y install cuda-compiler-10-2 cuda-libraries-10-2 cuda-libraries-dev-10-2

Then create the symlink to cuda:

(a). For CUDA 11:

sudo ln -s /usr/local/cuda-11.0 /usr/local/cuda

(b). For CUDA 10:

sudo ln -s /usr/local/cuda-10-2 /usr/local/cuda

(c). For CUDA 11.1x:

sudo ln -s /usr/local/cuda-11.1 /usr/local/cuda

Confirm that the library configuration file for CUDA libraries also exists with the correct settings:

/etc/ld.so.conf.d/cuda-11-0.conf

Or:

/etc/ld.so.conf.d/cuda-10-2.conf

Depending on what version of the CUDA SDK is present.

The content should be similar to:

/usr/local/cuda-$version/targets/x86_64-linux/lib

When done, load the new configuration:

sudo ldconfig -vvvv

Now, set up the environment variables for CUDA:

Edit the /etc/environment file and append the following:

CUDA_HOME=/usr/local/cuda

Now, append the PATH variable with the following:

/usr/local/cuda/bin:$HOME/bin

When done, remember to source the file:

source /etc/environment

And proceed.

Build the dependency chain as shown:

On NVENC enablement:

Take note that changes to the inclusion of third party headers affects new builds, and this is fixed by:

cd ~/ffmpeg_sources
git clone https://github.com/FFmpeg/nv-codec-headers
cd nv-codec-headers
make
make install PREFIX="$HOME/ffmpeg_build"

After installing the ffnvcodec headers package, proceed to install the nv-video-info package:

cd ~/ffmpeg_sources
git clone https://github.com/philipl/nv-video-info
cd nv-video-info
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./autogen.sh --prefix ~/
make
make install

Then you can run the applications generated, ie nvencinfo and nvdecinfo. Note that the build will fail if ffnvcodec package is missing. These tools are useful in validating NVENC capabilities on your machine.

Run them as:

nvencinfo

And:

nvdecinfo

Now proceed to install the rest of the software stack.

Build a usable FFmpeg binary:

Include extra components as needed:

(a). Build and deploy nasm: Nasm is an assembler for x86 optimizations used by x264 and FFmpeg. Highly recommended or your resulting build may be very slow.

Note that we've now switched away from Yasm to nasm, as this is the current assembler that x265,x264, among others, are adopting.

cd ~/ffmpeg_sources
wget https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.gz
tar xzvf nasm-2.15.05.tar.gz
cd nasm-2.15.05
./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin"
make -j$(nproc)
make -j$(nproc) install
make -j$(nproc) distclean

(b). Build and deploy libx264 statically: This library provides a H.264 video encoder. See the H.264 Encoding Guide for more information and usage examples. This requires ffmpeg to be configured with --enable-gpl --enable-libx264.

cd ~/ffmpeg_sources
git clone http://git.videolan.org/git/x264.git
cd x264/
PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" --enable-static --enable-pic --bit-depth=all
PATH="$HOME/bin:$PATH" make -j$(nproc) VERBOSE=1
make -j$(nproc) install VERBOSE=1
make -j$(nproc) distclean

(c ). Build and configure libx265: This library provides a H.265/HEVC video encoder. See the H.265 Encoding Guide for more information and usage examples.

cd ~/ffmpeg_sources
git clone https://github.com/videolan/x265
cd ~/ffmpeg_sources/x265/build/linux
PATH="$HOME/bin:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg_build" -DENABLE_SHARED:bool=off ../../source
make -j$(nproc) VERBOSE=1
make -j$(nproc) install VERBOSE=1
make -j$(nproc) clean VERBOSE=1

(d). Build and deploy the libfdk-aac library: This provides an AAC audio encoder. See the AAC Audio Encoding Guide for more information and usage examples. This requires ffmpeg to be configured with --enable-libfdk-aac (and --enable-nonfree if you also included --enable-gpl).

cd ~/ffmpeg_sources
git clone https://github.com/mstorsjo/fdk-aac
cd fdk-aac
autoreconf -fiv
./configure --prefix="$HOME/ffmpeg_build" --disable-shared
make -j$(nproc)
make -j$(nproc) install
make -j$(nproc) distclean

(e) Build FFmpeg

i. Turing:

cd ~/ffmpeg_sources
git clone https://github.com/FFmpeg/FFmpeg -b master
cd FFmpeg
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure \
  --pkg-config-flags="--static" \
  --enable-static --disable-shared \
  --prefix="$HOME" \
  --bindir="$HOME/bin" \
  --enable-cuda-nvcc \
  --enable-cuvid \
  --enable-libnpp \
  --extra-cflags="-I/usr/local/cuda/include/" \
  --extra-ldflags=-L/usr/local/cuda/lib64/ \
  --extra-cflags="-I/opt/intel/mediasdk/include" \
  --extra-ldflags="-L/opt/intel/mediasdk/lib" \
  --extra-ldflags="-L/opt/intel/mediasdk/plugins" \
  --enable-libmfx \
  --enable-vaapi \
  --enable-opencl \
  --enable-libdrm --enable-nvenc \
  --enable-libass \
  --disable-debug \
  --enable-gpl \
  --cpu=native \
  --enable-libfdk-aac \
  --enable-libx264 \
  --enable-libx265 \
  --enable-openssl \
  --enable-librtmp \
  --enable-libzvbi \
  --enable-version3 \
  --enable-pic \
  --nvccflags="-gencode arch=compute_75,code=sm_75 -O2" \
  --extra-libs="-lpthread -lm -lz -ldl" \
  --enable-nonfree 
PATH="$HOME/bin:$PATH" time make -j$(nproc) 
time make -j$(nproc) install 
time make -j$(nproc) distclean 
hash -r

Use this for releases:

cd ~/ffmpeg_sources && rm -fr FFmpeg
git clone https://github.com/FFmpeg/FFmpeg -b release/4.3
cd FFmpeg
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure \
  --pkg-config-flags="--static" \
  --enable-static --disable-shared \
  --prefix="$HOME" \
  --bindir="$HOME/bin" \
  --enable-cuda-nvcc \
  --enable-cuvid \
  --enable-libnpp \
  --extra-cflags="-I/usr/local/cuda/include/" \
  --extra-ldflags=-L/usr/local/cuda/lib64/ \
  --extra-cflags="-I/opt/intel/mediasdk/include" \
  --extra-ldflags="-L/opt/intel/mediasdk/lib" \
  --extra-ldflags="-L/opt/intel/mediasdk/plugins" \
  --enable-libmfx \
  --enable-vaapi \
  --enable-opencl \
  --enable-libdrm --enable-nvenc \
  --enable-libass \
  --disable-debug \
  --enable-gpl \
  --cpu=native \
  --enable-libfdk-aac \
  --enable-libx264 \
  --enable-libx265 \
  --enable-openssl \
  --enable-librtmp \
  --enable-libzvbi \
  --enable-version3 \
  --enable-pic \
  --nvccflags="-gencode arch=compute_75,code=sm_75 -O2" \
  --extra-libs="-lpthread -lm -lz -ldl" \
  --enable-nonfree 
PATH="$HOME/bin:$PATH" time make -j$(nproc) 
time make -j$(nproc) install 
time make -j$(nproc) distclean 
hash -r

ii. Maxwell:

cd ~/ffmpeg_sources
git clone https://github.com/FFmpeg/FFmpeg -b master
cd FFmpeg
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure \
  --pkg-config-flags="--static" \
  --enable-static --disable-shared \
  --prefix="$HOME" \
  --bindir="$HOME/bin" \
  --enable-cuda-nvcc \
  --enable-cuvid \
  --enable-libnpp \
  --extra-cflags="-I/usr/local/cuda/include/" \
  --extra-ldflags=-L/usr/local/cuda/lib64/ \
  --extra-cflags="-I/opt/intel/mediasdk/include" \
  --extra-ldflags="-L/opt/intel/mediasdk/lib" \
  --extra-ldflags="-L/opt/intel/mediasdk/plugins" \
  --enable-libmfx \
  --enable-vaapi \
  --enable-opencl \
  --enable-libdrm --enable-nvenc \
  --enable-libass \
  --disable-debug \
  --enable-gpl \
  --cpu=native \
  --enable-libfdk-aac \
  --enable-libx264 \
  --enable-libx265 \
  --enable-openssl \
  --enable-librtmp \
  --enable-libzvbi \
  --enable-version3 \
  --enable-pic \
  --nvccflags="-gencode arch=compute_52,code=sm_52 -O2" \
  --extra-libs="-lpthread -lm -lz -ldl" \
  --enable-nonfree 
PATH="$HOME/bin:$PATH" time make -j$(nproc) 
time make -j$(nproc) install 
time make -j$(nproc) distclean 
hash -r

iii. Pascal Consumer:

cd ~/ffmpeg_sources
git clone https://github.com/FFmpeg/FFmpeg -b master
cd FFmpeg
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure \
  --pkg-config-flags="--static" \
  --enable-static --disable-shared \
  --prefix="$HOME" \
  --bindir="$HOME/bin" \
  --enable-cuda-nvcc \
  --enable-cuvid \
  --enable-libnpp \
  --extra-cflags="-I/usr/local/cuda/include/" \
  --extra-ldflags=-L/usr/local/cuda/lib64/ \
  --extra-cflags="-I/opt/intel/mediasdk/include" \
  --extra-ldflags="-L/opt/intel/mediasdk/lib" \
  --extra-ldflags="-L/opt/intel/mediasdk/plugins" \
  --enable-libmfx \
  --enable-vaapi \
  --enable-opencl \
  --enable-libdrm --enable-nvenc \
  --enable-libass \
  --disable-debug \
  --enable-gpl \
  --cpu=native \
  --enable-libfdk-aac \
  --enable-libx264 \
  --enable-libx265 \
  --enable-openssl \
  --enable-librtmp \
  --enable-libzvbi \
  --enable-version3 \
  --enable-pic \
  --nvccflags="-gencode arch=compute_61,code=sm_61 -O2" \
  --extra-libs="-lpthread -lm -lz -ldl" \
  --enable-nonfree
PATH="$HOME/bin:$PATH" time make -j$(nproc) 
time make -j$(nproc) install 
time make -j$(nproc) distclean 
hash -r

Component upgrades:

  1. nv-codec-headers:
cd ~/ffmpeg_sources/nv-codec-headers
git pull
make
make install PREFIX="$HOME/ffmpeg_build"

After upgrading the ffnvcodec headers package, proceed to upgrade the nv-video-info package:

cd ~/ffmpeg_sources/nv-video-info
git pull
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./autogen.sh --prefix ~/
make
make install

Then you can run the applications generated, ie nvencinfo and nvdecinfo. Note that the build will fail if ffnvcodec package is missing. These tools are useful in validating NVENC capabilities on your machine.

Run them as:

nvencinfo

And:

nvdecinfo

Now proceed to upgrade FFmpeg.

2. Upgrade libx264:

This library provides a H.264 video encoder. See the H.264 Encoding Guide for more information and usage examples. This requires ffmpeg to be configured with --enable-gpl --enable-libx264.

cd ~/ffmpeg_sources/x264
git pull
PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" --enable-static --enable-pic --bit-depth=all
PATH="$HOME/bin:$PATH" make -j$(nproc) VERBOSE=1
make -j$(nproc) install VERBOSE=1
make -j$(nproc) distclean

3. Upgrade libx265:

This library provides a H.265/HEVC video encoder. See the H.265 Encoding Guide for more information and usage examples.

cd ~/ffmpeg_sources/x265
hg pull
hg update
cd ~/ffmpeg_sources/x265/build/linux
PATH="$HOME/bin:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg_build" -DENABLE_SHARED:bool=off ../../source
make -j$(nproc) VERBOSE=1
make -j$(nproc) install VERBOSE=1
make -j$(nproc) clean VERBOSE=1

4. Upgrade the libfdk-aac library:

This provides an AAC audio encoder. See the AAC Audio Encoding Guide for more information and usage examples. This requires ffmpeg to be configured with --enable-libfdk-aac (and --enable-nonfree if you also included --enable-gpl).

cd ~/ffmpeg_sources/fdk-aac
git pull
autoreconf -fiv
./configure --prefix="$HOME/ffmpeg_build" --disable-shared
make -j$(nproc)
make -j$(nproc) install
make -j$(nproc) distclean

14. Upgrade FFmpeg build:

Use:

cd ~/ffmpeg_sources/FFmpeg
git pull
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure \
  --pkg-config-flags="--static" \
  --enable-static --disable-shared \
  --prefix="$HOME" \
  --bindir="$HOME/bin" \
  --enable-cuda-nvcc \
  --enable-cuvid \
  --enable-libnpp \
  --extra-cflags="-I/usr/local/cuda/include/" \
  --extra-ldflags=-L/usr/local/cuda/lib64/ \
  --extra-cflags="-I/opt/intel/mediasdk/include" \
  --extra-ldflags="-L/opt/intel/mediasdk/lib" \
  --extra-ldflags="-L/opt/intel/mediasdk/plugins" \
  --enable-libmfx \
  --enable-vaapi \
  --enable-opencl \
  --enable-libdrm --enable-nvenc \
  --enable-libass \
  --disable-debug \
  --enable-gpl \
  --cpu=native \
  --enable-libfdk-aac \
  --enable-libx264 \
  --enable-libx265 \
  --enable-openssl \
  --enable-librtmp \
  --enable-libzvbi \
  --enable-version3 \
  --enable-pic \
  --nvccflags="-gencode arch=compute_61,code=sm_61 -O2" \
  --extra-libs="-lpthread -lm -lz -ldl" \
  --enable-nonfree 
PATH="$HOME/bin:$PATH" time make -j$(nproc) 
time make -j$(nproc) install 
time make -j$(nproc) distclean 
hash -r

Note: To get debug builds, add the --enable-debug=3 configuration flag and omit the distclean step and you'll find the ffmpeg_g binary under the sources subdirectory.

We only want the debug builds when an issue crops up and a gdb trace may be required for debugging purposes. Otherwise, leave this omitted for production environments.

Building FFmpeg build without the CUDA proprietary SDK:

In-place upgrade:

Note that llvm (and clang) must be installed. The advantage of this method is that the proprietary CUDA SDK is not needed.

cd ~/ffmpeg_sources/FFmpeg
git pull
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure \
  --pkg-config-flags="--static" \
  --enable-static --disable-shared \
  --prefix="$HOME" \
  --bindir="$HOME/bin" \
  --extra-cflags="-I$HOME/include" \
  --extra-ldflags="-L$HOME/lib" \
  --extra-cflags="-I/opt/intel/mediasdk/include" \
  --extra-ldflags="-L/opt/intel/mediasdk/lib" \
  --extra-ldflags="-L/opt/intel/mediasdk/plugins" \
  --enable-libmfx \
  --enable-vaapi \
  --enable-opencl \
  --enable-libdrm \  
  --enable-cuda-llvm \
  --nvcc=clang --enable-nvenc \
  --enable-libass \
  --disable-debug \
  --enable-gpl \
  --cpu=native \
  --enable-libfdk-aac \
  --enable-libx264 \
  --enable-libx265 \
  --enable-openssl \
  --enable-librtmp \
  --enable-libzvbi \
  --enable-version3 \
  --enable-pic \
  --nvccflags="--cuda-gpu-arch=sm_60 -O2" \
  --extra-libs="-lpthread -lm -lz -ldl" \
  --enable-nonfree 
PATH="$HOME/bin:$PATH" time make -j$(nproc) 
time make -j$(nproc) install 
time make -j$(nproc) distclean 
hash -r

Warning: You must be careful to pass the correct --nvccflags option(s) to FFmpeg. In this case, the syntax for nvccflags is --nvccflags="--cuda-gpu-arch=sm_$gen -O2"

Where $gen is the sm value of the GPU's generation. See the example above for Turing. Adjust as needed.

Note that this build will not have the scale_npp filters in place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment