Compile ffmpeg with NV codec in WSL Ubuntu 22.04
=
###### tags: `Note`
* Create a working directory for the compilation
```bash= !
mkdir -p ~/ffmpeg-build
cd ~/ffmpeg-build
```
1. Install build dependencies (some of them are probably optional but I don't wanna figure it out, just install all of them already!)
```bash= !
sudo apt update
sudo apt install -y \
autoconf \
automake \
build-essential \
cmake \
git \
libass-dev \
libfreetype6-dev \
libgnutls28-dev \
libmp3lame-dev \
libsdl2-dev \
libtool \
libva-dev \
libvdpau-dev \
libvorbis-dev \
libxcb1-dev \
libxcb-shm0-dev \
libxcb-xfixes0-dev \
meson \
ninja-build \
pkg-config \
texinfo \
wget \
yasm \
nasm \
zlib1g-dev
```
2. Install codec libraries
```bash= !
sudo apt install -y \
libx264-dev \
libx265-dev \
libvpx-dev \
libopus-dev \
libmp3lame-dev \
libvorbis-dev \
libaom-dev \
libfdk-aac-dev
```
3. Install CUDA tool kit
```bash= !
# This will install CUDA V11.5.119 if you're using Ubuntu 22.04
sudo apt install nvidia-cuda-toolkit
```
4. Download and install NVIDIA video codec SDK headers
```bash= !
cd ~/ffmpeg-build
git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git && cd nv-codec-headers
sudo make install
```
5. Optional: Install VMAF
* Install libvmaf Prerequisites
```bash= !
# Install system dependencies
sudo apt install -y python3 python3-pip python3-venv xxd doxygen
# meson and ninja should already be installed from Step 1
# If not, install them:
# sudo apt install -y meson ninja-build
# Verify versions (libvmaf requires: Python 3.6+, Meson 0.56.1+, Ninja 1.7.1+)
python3 --version
meson --version
ninja --version
```
* Optional: Use Python Virtual Environment (Recommended by libvmaf developers)
```bash= !
# Create and activate virtual environment
python3 -m pip install virtualenv
python3 -m virtualenv ~/ffmpeg-build/.venv
source ~/ffmpeg-build/.venv/bin/activate
# Install meson in virtual environment
pip install meson
# When done building, deactivate with:
# deactivate
```
* Compile and Install libvmaf
```bash= !
cd ~/ffmpeg-build
git clone https://github.com/Netflix/vmaf.git && cd vmaf
# List available tags
git tag | grep -E "^v[0-9]" | tail -20
# Checkout specific tag
git checkout v3.0.0 && cd libvmaf
# Configure build with meson
# Basic build (recommended):
meson setup build --buildtype release --prefix=/usr/local
# Advanced build options (optional):
# Add -Denable_cuda=true for CUDA-accelerated VMAF (requires CUDA >= 11)
# Add -Denable_avx512=true for faster processing on AVX-512 CPUs
# Add -Denable_float=true for floating-point feature extractors
# Add -Dbuilt_in_models=false to disable built-in models (reduces library size)
# Build
ninja -vC build
# Optional: Run tests to verify build
ninja -vC build test
# Install (installs libvmaf library, headers, and 'vmaf' CLI tool)
sudo ninja -vC build install
# Update library cache
sudo ldconfig
```
6. Clone FFmpeg source repository
```bash= !
cd ~/ffmpeg-build
git clone https://git.ffmpeg.org/ffmpeg.git && cd ffmpeg
# List available tags
git tag | grep -E "^n[0-9]" | tail -20
# Checkout specific tag
git checkout n8.0
```
7. Configure ffmpeg with NVIDIA GPU support
```bash= !
./configure \
--prefix=/usr/local \
--enable-gpl \
--enable-version3 \
--enable-nonfree \
--enable-shared \
--enable-static \
--enable-libx264 \
--enable-libx265 \
--enable-libvpx \
--enable-libopus \
--enable-libmp3lame \
--enable-libvorbis \
--enable-libaom \
--enable-libfdk-aac \
--enable-cuda-nvcc \
--enable-cuvid \
--enable-nvdec \
--enable-nvenc \
--enable-cuda-llvm \
--enable-libnpp \
--extra-cflags="-I/usr/local/cuda/include" \
--extra-ldflags="-L/usr/local/cuda/lib64" \
--nvccflags="-gencode arch=compute_86,code=sm_86 -O2"
# If you want to included VMAF, add: --enable-libvmaf
```
**Note on NVCC architecture:** The `nvccflags` parameter specifies GPU compute capability:
- `sm_52`: Maxwell (GTX 9xx, GTX 10xx)
- `sm_61`: Pascal (GTX 10xx)
- `sm_75`: Turing (RTX 20xx)
- `sm_86`: Ampere (RTX 30xx)
- `sm_89`: Ada Lovelace (RTX 40xx)
8. Compile
```bash= !
make -j $(nproc)
# Install (optional)
sudo make install
```
9. Usage example
* Trim
```bash= !
ffmpeg -hwaccel cuda -hwaccel_output_format cuda \
-i input.mp4 -fps_mode passthrough \
-ss 00:00:30 -to 00:01:00 \
-c:v hevc_nvenc -preset p7 -qp 22 \
-c:a copy \
trimed.mp4
```
* Downscale to 1080p (for social media)
```bash= !
ffmpeg -hwaccel cuda -hwaccel_output_format cuda \
-i input.mp4 -fps_mode passthrough \
-vf scale_cuda=-1:1080 \
-c:v h264_nvenc -preset p7 -qp 32 \
-c:a aac -ar 48k -b:a 128k \
1080p.mp4
```
* Speed up to 2x\
This will double the FPS, use `-fps_mode vfr` to maintain the FPS (half of the frames will be dropped).
```bash= !
ffmpeg -hwaccel cuda -hwaccel_output_format cuda \
-i ./input.mp4 -fps_mode passthrough \
-filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2[a]" \
-map "[v]" -c:v hevc_nvenc -preset p7 -qp 22 \
-map "[a]" -c:a aac -ar 48k -b:a 320k \
2x.mp4
```
* Speed up to 20x
This will blend every 20 frames, add `-an` to disable audio.
```bash= !
ffmpeg -hwaccel cuda \
-i ./input.mp4 -fps_mode passthrough \
-filter_complex "[0:v]tmix=frames=20:weights='1',select='not(mod(n\,20))',setpts=0.05*PTS[v];[0:a]atempo=20[a]" \
-map "[v]" -c:v hevc_nvenc -preset p7 -qp 22 \
-map "[a]" -c:a aac -ar 48k -b:a 320k \
20x.mp4
```
* VMAF
```bash=
ffmpeg -hwaccel cuda \
-r 60 -i reference.mp4 \
-r 60 -i distorted.mp4 \
-lavfi "[0:v]setpts=PTS-STARTPTS[reference]; \
[1:v]setpts=PTS-STARTPTS[distorted]; \
[distorted][reference]libvmaf=log_fmt=xml:log_path=/dev/stdout:model='path={your_vmaf_dir}/model/vmaf_v0.6.1.json':n_threads=$(nproc)" \
-f null -
```
10. Extra: GPU status viewer
```bash= !
sudo apt install nvtop
nvtop
```
## References
[How to install FFmpeg with NVIDIA GPU acceleration on Linux](https://www.cyberciti.biz/faq/how-to-install-ffmpeg-with-nvidia-gpu-acceleration-on-linux/)
[Install FFmpeg with Nvidia nvdec and nvenc on Ubuntu 20.04 with CUDA](https://igor.technology/install-ffmpeg-on-ubuntu-20-04-with-cuda/)
[Using FFmpeg with NVIDIA GPU Hardware Acceleration](https://docs.nvidia.com/video-technologies/video-codec-sdk/12.0/ffmpeg-with-nvidia-gpu/index.html)