Skip to content

Instantly share code, notes, and snippets.

@Ghostbird
Last active November 5, 2024 17:03
Show Gist options
  • Save Ghostbird/0445ebe0d9f6d945c3978702ad455103 to your computer and use it in GitHub Desktop.
Save Ghostbird/0445ebe0d9f6d945c3978702ad455103 to your computer and use it in GitHub Desktop.
Build FFMPEG with NVIDIA hardware accelleration libraries on Debian 12. Includes non-free libnpp!

Obsolete

It is no longer necessary to use this script to have hardware acceleration in ffmpeg on Debian. The default Debian ffmpeg and dependencies now support this out of the box.

See: #gistcomment-5095112

#!/bin/bash
# Automatically compile and install FFMPEG with NVIDIA hardware acceleration on Debian 12
# Includes cuvid, cuda, nvenc, nvdec, and non-free libnpp
# Based on:
# https://www.tal.org/tutorials/ffmpeg_nvidia_encode
# https://developer.nvidia.com/blog/nvidia-ffmpeg-transcoding-guide/
# Abort on error
set -e
suite=$(source /etc/os-release && echo $VERSION_CODENAME)*
# Install libavcodec-extra manually so the build-deps step doesn't pull the problematic libavcodec59
# libjs-bootstrap is a dependency of ffmpeg-doc
# devscripts contains the dch command
sudo apt-get install libavcodec-extra libjs-bootstrap devscripts
sudo apt-mark auto libavcodec-extra libjs-bootstrap devscripts
sudo apt-get build-dep ffmpeg -t $suite
sudo apt-get install nvidia-cuda-toolkit -t $suite
mkdir -p ffmpeg-deb/src
cd ffmpeg-deb
if [[ -d nv-codec-headers ]]
then
cd nv-codec-headers
git fetch --tags
else
git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git
cd nv-codec-headers
fi
# Checkout latest release, intead of HEAD. The Debian driver in stable may not yet support the pre-release API.
git checkout $(git describe --tags $(git rev-list --tags --max-count=1))
make
sudo make install
cd ../src
rm -rf ./*
apt-get source ffmpeg -t $suite
cd ffmpeg-*
sed -i 's/--enable-sdl2/--enable-sdl2 --enable-cuda --enable-cuvid --enable-nvdec --enable-nvenc --enable-libnpp --enable-nonfree/' debian/rules
DEBEMAIL="root@local" DEBFULLNAME="script" dch --local "+nvidiasupport" "Compiled with support for nvidia hardware acceleration"
DEB_BUILD_OPTIONS="nocheck notest" dpkg-buildpackage -r -nc --jobs=auto --no-sign
cd ..
# Install all built packages, except the non-extra variants of libavfilter, libavcodec and libavformat
sudo dpkg -i $(ls *.deb | grep -Ev "(libavfilter|libavcodec|libavformat)[0-9]+_")
echo "Verification:"
ffmpeg -codecs 2> /dev/null | grep nvenc
# Script ends here, lines below are to restore your system to Debian default binaries
exit 0
# Undo package changes by this script, and restore Debian default binaries:
# Make temporary directory and switch to it.
cd $(mktemp -d)
# First forcibly remove all the custom packages, regardless of what depends on them.
# After this step your system is partially broken.
sudo dpkg --remove --force-all ffmpeg ffmpeg-dbgsym ffmpeg-doc libavcodec59 libavcodec59-dbgsym libavcodec-dev libavcodec-extra libavcodec-extra59 libavcodec-extra59-dbgsym libavdevice59 libavdevice59-dbgsym libavdevice-dev libavfilter8 libavfilter8-dbgsym libavfilter-dev libavfilter-extra libavfilter-extra8 libavfilter-extra8-dbgsym libavformat59 libavformat59-dbgsym libavformat-dev libavformat-extra libavformat-extra59 libavformat-extra59-dbgsym libavutil57 libavutil57-dbgsym libavutil-dev libpostproc56 libpostproc56-dbgsym libpostproc-dev libswresample4 libswresample4-dbgsym libswresample-dev libswscale6 libswscale6-dbgsym libswscale-dev
# Now download the default debian binary versions of the just removed packages.
# This ensures we don't accidentally install the cached self-built packages again.
apt-get download ffmpeg ffmpeg-doc libavdevice59 libavcodec-dev libavcodec-extra libavcodec-extra59 libavdevice-dev libavfilter-dev libavfilter-extra libavfilter-extra8 libavformat-dev libavformat-extra libavformat-extra59 libavutil57 libavutil-dev libpostproc56 libpostproc-dev libswresample4 libswresample-dev libswscale6 libswscale-dev
# Finally install those packages as replacements for the just removed ones. This should fix the system again.
sudo dpkg -i *.deb
@weskerty
Copy link

Thank you. It helped me.

@Ghostbird
Copy link
Author

Oddly, the added manual install of libavcodec-extra line suggested above today caused a problem and removing that package from the installation solved it.

The message was that libavcodec-extra59-XXX could not be installed because libavcodec-extra-59-XXX+nvidiasupport1 was already installed. (XXX is the same version identifier in both cases, but I forgot which one exactly it was).

@dariogriffo
Copy link

Thanks for this script! I'm getting an error while building

/tmp/ffconf.0SkOoHk4/test.c:1:10: fatal error: npp.h: No such file or directory
    1 | #include <npp.h>
      |          ^~~~~~~
compilation terminated.
ERROR: libnpp not found

any idea why this could be happening?
I'm building on a fresh bookworm with cuda toolkit 12.5

@Ghostbird
Copy link
Author

Ghostbird commented Jun 18, 2024

On a clean bookworm install? That's extremely odd. The file npp.h is provided by nvidia-cuda-dev, which is automatically installed when you install nvidia-cuda-toolkit, which this script does. Can you check:

  • Is nvidia-cuda-dev installed?
    dpkg-query -W nvidia-cuda-dev should list a version number.
  • Is /usr/include/npp.h present on the system?

If either of those is missing, it sounds like a bad situation for a fresh system. I'd sooner expect things like that on my nine years old Frankendebian.

Anyway, if either of those steps show something is missing, I'd suggest you reinstall nvidia-cuda-toolkit:

sudo apt-get install --reinstall nvidia-cuda-toolkit

And then recheck for nvidia-cuda-dev and /usr/include/npp.h.

@dariogriffo
Copy link

Thank you! I managed to fix everything.
There is actually no need to compile ffmpeg to have nvenc support on debian is out of the box!
I will write down the steps but debian official ffmpeg is all that is required

@Ghostbird
Copy link
Author

Ghostbird commented Jun 22, 2024

@dariogriffo It seems you're right. I don't understand why it works though, as the ffmpeg banner doesn't show that any of the libraries are compiled with support for these things. I don't know when this was added, but it might be related with NVIDIA open sourcing the GPU kernel modules two years ago1. The original script2 that this one is based on, is from before that time.

I added a section to the bottom of the script that restores your system to Debian default "extra" binaries.

I've run that myself, and ran some tests3 that show:

  • NVENC works out of the box
  • NVDEC works out of the box
  • CUVID works out of the box
  • CUDA acceleration works partially out of the box
    • Complex filter notation works: ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 -noautoscale -filter_complex [0:0]scale_cuda=1280:-2[out] -map [out] -c:v hevc_nvenc -cq 28 output.mkv
    • Simple scale_cuda filter notation doesn't seem to work, complains about the autoscale function not being implemented. Just adding -noautoscale doesn't fix it. ffmpeg -hwaccel_device 0 -hwaccel cuda -i input.mp4 -vf scale_cuda=-1:720 -c:v h264_nvenc -preset slow output.mkv
  • libnpp and cuda-nvcc are NOT supported. At least libnpp IS supported when you use this script. However:

    cuda-nvcc has basically been replaced with ffnvcodec + cuda-llvm, scale_npp with scale_cuda. 4

In conclusion:

  • It seems this script is no longer needed if you just need CUDA, CUVID, NVENC or NVDEC support in ffmpeg.
  • This script is still needed if you need libnpp, but most likely your workflow can be adapted to use the more modern CUDA alternatives for libnpp instead.
  • This script can still provide a nice basis for FFMPEG builds with specific needs. I, for example, have a modified version running on my local production studio graphics server. Instead of adding nv-codec-headers and compiling with NVIDIA libraries, it adds the BlackmagicDesign Decklink SDK and compiles with the --enable-decklink option to add support for BlackmagicDesign Decklink SDI video I/O.

Footnotes

  1. https://developer.nvidia.com/blog/nvidia-releases-open-source-gpu-kernel-modules/

  2. https://gist.github.com/Ghostbird/11b62ae6370a4f42babc7c8164f44d9d/revisions

  3. https://trac.ffmpeg.org/wiki/HWAccelIntro#NVDECCUVID

  4. https://trac.ffmpeg.org/wiki/HWAccelIntro#cuda-nvccandlibnpp

@dariogriffo
Copy link

No worries you made a great work setting my thinking in the right direction.
Also really happy we can get majority of things simple users need out of the box.
I use it for OBS and works just fine.
Have a great weekend!

@Ghostbird
Copy link
Author

Yeah, I originally needed this for OBS, because I had to live-stream events when COVID hit. It's nice that things have improved to the point where this functionality is available out of the box.

@dariogriffo
Copy link

Here is a full guide on how I got everything working
My blog

@Ghostbird
Copy link
Author

Ghostbird commented Jun 22, 2024

Thanks. Any reason why you install the CUDA toolkit from NVIDIA, instead of the one that comes with Debian1?

I think that step is not needed. You can probably just:

sudo apt-get install nvidia-drivers nvidia-cuda-toolkit

Did you maybe not enable the non-free Debian repositories? On machines where I need these kinds of drivers, I always install Debian with an installer that has non-free enabled a priori.

Footnotes

  1. https://packages.debian.org/bookworm/nvidia-cuda-toolkit

@dariogriffo
Copy link

Just that is way more updated and wanted to make sure I have as much support as possible. First time installing an Nvidia card in Linux.
But is the only thing I installed outside the official stable mirrors.
I use the desktop for work, so I need a stable environment.
I don't need bleed edge packages. Quite conservative I'm 😆

@Ghostbird
Copy link
Author

Ghostbird commented Jun 26, 2024

An ironic statement, since you're going out of your way to install a bleeding edge package. But I think you meant you don't need other bleeding edge packages.
You might want to reflect that in your blog, so users don't think you need to do that.
I had to install NVIDIA drivers and CUDA toolkit on my work machine yesterday and these were the steps I had to do:

  1. Add non-free to your source.list lines1
  2. sudo apt-get update
  3. sudo apt-get install nvidia-driver nvidia-cuda-toolkit

Note that the CUDA toolkit is big. I normally reserve a 30GiB partition for the root filesystem on my Debian installs, but installing these two packages eats up more than 4GiB of that. Before installing it, my entire system libraries were only slightly over 8GiB, and that already included some big non-standard packages.

Footnotes

  1. https://serverfault.com/questions/240920/how-do-i-enable-non-free-packages-on-debian/240921#240921

@dariogriffo
Copy link

An ironic statement, since you're going out of your way to install a bleeding edge package.

Indeed it is, but as said is the only package I have installed this way :)

But I think you meant you don't need other bleeding edge packages. You might want to reflect that in your blog, so users don't think you need to do that.

You are correct I'll update the blog. Thanks for the heads-up

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