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)