Skip to content

Instantly share code, notes, and snippets.

@SergeyKozlov
Created February 27, 2018 13:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SergeyKozlov/f3d7cecde6585d72a0b821f9551c85d0 to your computer and use it in GitHub Desktop.
Save SergeyKozlov/f3d7cecde6585d72a0b821f9551c85d0 to your computer and use it in GitHub Desktop.
This gist will show you how to build a minimalist, statically-linked ffmpeg binary under the ~/bin subdirectory on your home on Ubuntu 16.04LTS. Comes with NPP, CUDA and NVENC capabilities.

Minimalist static FFmpeg build on Ubuntu 16.04 with Nvidia NVENC enabled.

Original guide with a standard build is here.

With this guide, I'm adding more instructions to enable support for NVIDIA CUVID and NVIDIA NPP for enhanced encode and decode performance.

First, prepare for the build and create the work space directory:

cd ~/
mkdir ~/ffmpeg_sources
sudo apt-get -y update && apt-get dist-upgrade -y
sudo apt-get -y install autoconf automake build-essential libass-dev \
  libtool \
  pkg-config texinfo zlib1g-dev

Install CUDA 8 SDK from Nvidia's repository:

Note that this phase will prompt you to install the device driver. Skip it, and skip the samples too.We will install the driver later. Fetch the installers first:

mkdir ~/cuda && cd ~/cuda
 wget -c -v -nc https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda_8.0.61_375.26_linux-run

wget -c -v https://developer.nvidia.com/compute/cuda/8.0/Prod2/patches/2/cuda_8.0.61.2_linux-run

chmod +x cuda_*

Now, install the SDK, and skip the device driver setup:

./cuda_8.0.61_375.26_linux-run

When you're done, proceed to deploy the patch, accept the license and proceed:

./cuda_8.0.61.2_linux-run

Now, set up the environment variables for CUDA:

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

CUDA_HOME=/usr/local/cuda-8.0

Now, append the PATH variable with the following:

/usr/local/cuda/bin

When done, remember to source the file:

source /etc/environment

Now, create a custom conf file for the CUDA library path under /etc/ld.so.conf.d/cuda.conf, with the following entries:

nano /etc/ld.so.conf.d/cuda.conf

Content:

/usr/local/cuda-8.0/lib64

And also run:

ldconfig -vvvv

(This phase assumes that you're logged in as root).

Now, deploy the device driver:

sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt-get update
sudo apt-get install nvidia-384

(This phase assumes that you're logged in as root).

Install dependencies for NVENC:

sudo apt-get -y install glew-utils libglew-dbg libglew-dev libglew1.13 \
libglewmx-dev libglewmx-dbg freeglut3 freeglut3-dev freeglut3-dbg libghc-glut-dev \
libghc-glut-doc libghc-glut-prof libalut-dev libxmu-dev libxmu-headers libxmu6 \
libxmu6-dbg libxmuu-dev libxmuu1 libxmuu1-dbg 

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're using the latest release candidate, and not the stable version as of the time of writing.

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

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
wget http://download.videolan.org/pub/x264/snapshots/last_x264.tar.bz2
tar xjvf last_x264.tar.bz2
cd x264-snapshot*
PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --enable-static --disable-opencl
PATH="$HOME/bin:$PATH" make -j88
make -j$(nproc) install
make -j$(nproc) distclean

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.

sudo apt-get install cmake mercurial
cd ~/ffmpeg_sources
hg clone https://bitbucket.org/multicoreware/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)
make -j$(nproc) install
make -j$(nproc) clean

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
wget -O fdk-aac.tar.gz https://github.com/mstorsjo/fdk-aac/tarball/master
tar xzvf fdk-aac.tar.gz
cd mstorsjo-fdk-aac*
autoreconf -fiv
./configure --prefix="$HOME/ffmpeg_build" --disable-shared
make -j$(nproc)
make -j$(nproc) install
make -j$(nproc) distclean

Deploy NVENC SDK: At this phase, we will assume that the end user has rebooted the node prior to proceeding with this phase. If not, proceed via:

sudo systemctl reboot

Then proceed to download the latest Nvidia NVENC SDK from the Nvidia Developer portal when the host is booted up:

We are using the latest NVENC SDK for this.

Ensure that the SDK is downloaded to your ~/ffmpeg_sources directory (cd ~/ffmpeg_sources to be sure) so as to maintain the needed directory structure.

Extract and copy the NVENC SDK headers as needed:

Then navigate to the extracted directory:

unzip Video_Codec_SDK_*.zip
cd Video_Codec_SDK_*/Samples

From within the SDK directory, do:

sudo cp -vr Samples/common/inc/GL/* /usr/include/GL/
sudo cp -vr Samples/common/inc/*.h /usr/include/

When done,do:

cd ~/ffmpeg_sources
mv Video_Codec_SDK_* nv_sdk

That will allow us to statically link to the SDK with ease, below.

Note that there may be a newer version of the SDK available at the time, please adjust as appropriate.

Building a static ffmpeg binary with the required options:

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 \
  --prefix="$HOME/ffmpeg_build" \
  --pkg-config-flags="--static" \
  --extra-cflags="-I$HOME/ffmpeg_build/include" \
  --extra-ldflags="-L$HOME/ffmpeg_build/lib" \
  --bindir="$HOME/bin" \
  --enable-cuda-sdk \
  --enable-cuvid \
  --enable-libnpp \
  --extra-cflags=-I../nv_sdk \
  --extra-ldflags=-L../nv_sdk \
  --extra-cflags="-I/usr/local/cuda/include/" \
  --extra-ldflags=-L/usr/local/cuda/lib64/ \
  --enable-gpl \
  --enable-libass \
  --enable-libfdk-aac \
  --enable-libx264 \
  --enable-libx265 \
  --enable-nvenc \
  --enable-nonfree
PATH="$HOME/bin:$PATH" make -j$(nproc)
make -j$(nproc) install
make -j$(nproc) distclean
hash -r

You may also want to tune your build further by calling uon NVCC to generate a build optimized for your GPU's CUDA architecture only.

The example below shows the build options to pass for Pascal's GM10x-series GPUs, with an SM version of 6.1:

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 \
  --prefix="$HOME/ffmpeg_build" \
  --pkg-config-flags="--static" \
  --extra-cflags="-I$HOME/ffmpeg_build/include" \
  --extra-ldflags="-L$HOME/ffmpeg_build/lib" \
  --bindir="$HOME/bin" \
  --enable-cuda-sdk \
  --enable-cuvid \
  --enable-libnpp \
  --extra-cflags=-I../nv_sdk \
  --extra-ldflags=-L../nv_sdk \
  --extra-cflags="-I/usr/local/cuda/include/" \
  --extra-ldflags=-L/usr/local/cuda/lib64/ \
  --nvccflags="-gencode arch=compute_61,code=sm_61 -O2" \
  --enable-gpl \
  --enable-libass \
  --enable-libfdk-aac \
  --enable-libx264 \
  --extra-libs=-lpthread \
  --enable-libx265 \
  --enable-nvenc \
  --enable-nonfree
PATH="$HOME/bin:$PATH" make -j$(nproc)
make -j$(nproc) install
make -j$(nproc) distclean
hash -r

If ~/bin is already in your path, you can call up ffmpeg directly. Note that the build instructions assume that the NVIDIA CUDA toolkit is on the system path, as is recommended during setup.

Hint: Use this guide to learn how to launch ffmpeg in multiple instances for faster NVENC based encoding on capable hardware.

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