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
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 |
Thanks for the feedback.
I have another clarification that encoder av1_nvenc is not included:-
ffmpeg -hide_banner -encoders | grep nvenc
V....D h264_nvenc NVIDIA NVENC H.264 encoder (codec h264)
V....D hevc_nvenc NVIDIA NVENC hevc encoder (codec hevc)
Is it possible to compile this av1_nvenc into ffmpeg ?
According to Nvidia SDK v12 it is part of it:-
The NVENC plugin in FFMPEG supports the following codecs: h264_nvenc - H264 Encoder hevc_nvenc - HEVC Encoder av1_nvenc - AV1 Encoder The command lines in this document use h264_nvenc, and should be replaced by hevc_nvenc for HEVC encode and av1_nvenc for AV1 encode.
Thanks
I'd expect it to be included automatically, however I don't know for sure, and I can't test it. On my system it is not present after the compilation, simply because my hardware doesn't support it. You should check your hardware support here
I have verified that RTX-4060 Ti 8GB Nvidia GPU Card is listed to support AV1 in here.
If it is automatically complied to include encoder av1_nvenc, can I verify it in the log & what key word to look out for ?
Thanks
I see that the NVIDIA page on compiling FFMPEG lists a configuration flag --enable-cuda-nvcc
. I have no idea whether it'll work, but you can try adding that to the sed
line in the script. In the line that starts with sed -i
, add --enable-cuda-nvcc
after --enable-cuda
and see whether that works. I'm not sure whether that's valid, but it's worth a quick try. If it isn't valid you'll probably get an error an you'll have to remove it again.
If it is automatically complied to include encoder av1_nvenc, can I verify it in the log & what key word to look out for ?
The script greps for nvenc
at the end. If the encoder av1_nvenc
is present, it would show up in the verification output at the end of the script. The fact that you haven't seen it already probably means it really isn't present.
I've update it with a mechanism that works for me, give it a try once you have the time.
I've used
suite=$(source /etc/os-release && echo $VERSION_CODENAME)*
which yieldsbookworm*
on my system. This seems to work.However
suite=$(source /etc/os-release && echo $VERSION_ID)*
which yields12*
works just as well.I opted for the code name because it's clearer what it means. When you see (e.g. in a log) an apt command that includes a version number you won't instantly know whether it's a software version number or an OS version number. When you see a Debian code-name, it's obviously an OS version and not a software version.
Testing this out, it doesn't seem to work at all on bullseye:
root@bullseye:~# apt-get build-dep ffmpeg -t bullseye
[...]
The following packages have unmet dependencies:
[...]
E: Unable to correct problems, you have held broken packages.
The other options do even worse (same result for 11 and 11*):
root@bullseye:~# apt-get build-dep ffmpeg -t bullseye*
Reading package lists... Done
E: Unable to find a source package for ffmpeg
On bookworm it works as long as the wildcard is specified:
root@bookworm:~# apt-get build-dep ffmpeg -t bookworm
[...]
The following packages have unmet dependencies:
[...]
E: Unable to correct problems, you have held broken packages.
root@bookworm:~# apt-get build-dep ffmpeg -t bookworm*
[...]
After this operation, 1,040 MB of additional disk space will be used.
Do you want to continue? [Y/n]
root@bookworm:~# apt-get build-dep ffmpeg -t 12
Reading package lists... Done
E: Unable to find a source package for ffmpeg
root@bookworm:~# apt-get build-dep ffmpeg -t 12*
[...]
After this operation, 1,040 MB of additional disk space will be used.
Do you want to continue? [Y/n]
So in short, I think the solution of using $VERSION_CODENAME* is the best for the clarity reasons you bring up.
While poking at this, I fixed some other issues I ran into, feel free to incorporate them if they seem useful to you:
libavcodec59
package, so I added a line manually installing libavcodec-extra
, which dpkg can replace without issue.libjs-bootstrap
) and removed the "nodoc" that doesn't seem to do anything.+nvidiasupport
) to stop that happening.Here's the diff covering all the above changes:
2c2
< # Automatically compile and install FFMPEG with NVIDIA hardware acceleration on Debian 11
---
> # Automatically compile and install FFMPEG with NVIDIA hardware acceleration on Debian 12
12a13,18
> # 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
>
31a38
>
34c41,42
< DEB_BUILD_OPTIONS="nocheck nodoc notest" dpkg-buildpackage -r -nc -j4 --no-sign
---
> 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
35a44
>
I will probably set something up to automatically build the package again when there is a newer version in apt, I can share the result if that seems interesting to you.
/T
Odd that it didn't work on Bullseye. I've added your changes and it worked perfectly on my system. How the libavcodec59
problem happened, I don't know. The inverse grep
in the subcommand that generates the package list for dpkg
should have excluded it based on the regular expression.
I had no idea that I had left -j4
in there. --jobs=auto
is of course much more desirable. I didn't know that option existed. I normally used -j$(nproc)
.
I have edited your message above. The word acceleration
was somehow word-wrapped using a newline character, which broke the patch file.
UPDATE: Actually I didn't realise, but the new script broke some stuff on my system, but it was fixed after removing a lot of :i386
packages that I didn't need anyway.
I see that the NVIDIA page on compiling FFMPEG lists a configuration flag
--enable-cuda-nvcc
. I have no idea whether it'll work, but you can try adding that to thesed
line in the script. In the line that starts withsed -i
, add--enable-cuda-nvcc
after--enable-cuda
and see whether that works. I'm not sure whether that's valid, but it's worth a quick try. If it isn't valid you'll probably get an error an you'll have to remove it again.
I have tried by adding --enable-cuda-nvcc
after --enable-cuda
, the script stopped with error log shown below:-
. . . . . . .
nvcc -gencode arch=compute_60,code=sm_60 -O2 -std=c++11 -m64 -ptx -c -o /tmp/ffconf.jCphOBPP/test.o /tmp/ffconf.jCphOBPP/test.cu
ERROR: No supported gcc/g++ host compiler found, but clang-14 is available.
Use 'nvcc -ccbin clang-14' to use that instead.
ERROR: failed checking for nvcc.
make[1]: Leaving directory '/home/user233l/ffmpeg-deb/src/ffmpeg-5.1.3'
make[1]: *** [debian/rules:257: configure_standard] Error 1
make: *** [debian/rules:250: binary] Error 2
dpkg-buildpackage: error: debian/rules binary subprocess returned exit status 2
Interesting, I can't help you much with that, but you can look at NVIDIA/cuda-samples#46 as a starting point.
does this work on debian sid? i really need obs right now
Give it a try. You can run the first 43 lines of the script, and see whether it compiles, without changing your system too much.
Thank you. It helped me.
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).
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
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:
nvidia-cuda-dev
installed?dpkg-query -W nvidia-cuda-dev
should list a version number./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
.
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
@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:
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
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:
libnpp
, but most likely your workflow can be adapted to use the more modern CUDA alternatives for libnpp
instead.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.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!
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.
Here is a full guide on how I got everything working
My blog
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.
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 😆
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:
non-free
to your source.list lines1sudo apt-get update
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.
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