92 lines
4.0 KiB
Bash
Executable File
92 lines
4.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# build-ffmpeg-nvenc-matched.sh — build an ffmpeg that matches your NVIDIA
|
|
# driver's NVENC API version, installed to ~/.local (shadows the distro
|
|
# ffmpeg via ~/.local/bin precedence in PATH).
|
|
#
|
|
# WHY THIS EXISTS
|
|
# ---------------
|
|
# ffmpeg builds are compiled against a specific NVENC API (nv-codec-headers
|
|
# "gen") and the installed NVIDIA driver must be at least that new. If your
|
|
# card is on a legacy driver branch (e.g. 580 is the LAST branch supporting
|
|
# Pascal cards like the GTX 10xx), you cannot upgrade the driver to what a
|
|
# bleeding-edge ffmpeg wants — e.g.:
|
|
#
|
|
# [hevc_nvenc @ ...] Driver does not support the required nvenc API
|
|
# version. Required: 13.1 Found: 13.0
|
|
#
|
|
# The fix is the inverse: build ffmpeg against the API your driver DOES
|
|
# provide (Found: X.Y → nv-codec-headers nX.Y.*). OpenTranscode's probe
|
|
# picks ~/.local/bin/ffmpeg up automatically on the next launch (PATH
|
|
# order) and the Auto engine will start using the GPU.
|
|
#
|
|
# USAGE
|
|
# -----
|
|
# ./build-ffmpeg-nvenc-matched.sh # auto-detect driver API
|
|
# ./build-ffmpeg-nvenc-matched.sh 13.0 # explicit gen
|
|
#
|
|
# Requires: git, make, gcc, nasm, pkg-config, clang (for --enable-cuda-llvm;
|
|
# the script drops that flag automatically if clang is absent).
|
|
set -euo pipefail
|
|
|
|
FF_VER="${FF_VER:-n9.0.2}"
|
|
PREFIX="${PREFIX:-$HOME/.local}"
|
|
BUILD_DIR="${BUILD_DIR:-/tmp/ffmpeg-nvenc-build}"
|
|
BASE_CONF="${BASE_CONF:-}" # optional: a configure line to copy (e.g. distro ffmpeg)
|
|
|
|
if [[ $# -ge 1 ]]; then
|
|
GEN="$1"
|
|
else
|
|
# First two components of the driver's NVENC API, from the error ffmpeg
|
|
# prints (or run `nvidia-smi` — 580/550/etc. drivers ↔ gen 13.0/12.2).
|
|
read -rp "NVENC API gen to build against (e.g. 13.0): " GEN
|
|
fi
|
|
HEADERS_TAG="n${GEN}.19.1" # any n<GEN>.* tag provides that gen
|
|
mkdir -p "$BUILD_DIR"
|
|
|
|
echo "==> nv-codec-headers $HEADERS_TAG → $PREFIX"
|
|
if [[ ! -d "$BUILD_DIR/nv-codec-headers" ]]; then
|
|
git clone --quiet https://github.com/FFmpeg/nv-codec-headers.git "$BUILD_DIR/nv-codec-headers"
|
|
fi
|
|
git -C "$BUILD_DIR/nv-codec-headers" fetch --quiet --depth 1 origin tag "$HEADERS_TAG" || true
|
|
git -C "$BUILD_DIR/nv-codec-headers" checkout --quiet "$HEADERS_TAG"
|
|
make -C "$BUILD_DIR/nv-codec-headers" install "PREFIX=$PREFIX" >/dev/null
|
|
|
|
echo "==> ffmpeg $FF_VER source → $BUILD_DIR/src"
|
|
if [[ ! -d "$BUILD_DIR/src" ]]; then
|
|
git clone --quiet --depth 1 --branch "$FF_VER" \
|
|
https://github.com/FFmpeg/ffmpeg.git "$BUILD_DIR/src"
|
|
fi
|
|
|
|
CONF_ARGS="${BASE_CONF:-}"
|
|
if [[ -z "$CONF_ARGS" && -x /usr/bin/ffmpeg ]]; then
|
|
# Copy the distro build's feature set so the result is a drop-in.
|
|
CONF_ARGS=$(/usr/bin/ffmpeg -version 2>/dev/null | sed -n 3p | sed 's/^configuration: //')
|
|
fi
|
|
if [[ -z "$CONF_ARGS" ]]; then
|
|
CONF_ARGS="--enable-gpl --enable-libx264 --enable-libx265 --enable-libvpx --enable-libsvtav1 --enable-libopus --enable-libvorbis --enable-libdav1d"
|
|
fi
|
|
CONF_ARGS=${CONF_ARGS/--prefix=*\/usr /} # strip distro prefix
|
|
CONF_ARGS=$(echo "$CONF_ARGS" | sed 's/--prefix=[^ ]*//')
|
|
# --enable-rpath is CRITICAL: without it the installed binary resolves its
|
|
# SONAME libs (libavcodec.so etc.) from /usr/lib — the DISTRO build — and
|
|
# silently keeps demanding the newer NVENC API. rpath pins it to
|
|
# $PREFIX/lib where our NVENC-13.0-matched libs live.
|
|
CONF_ARGS="--prefix=$PREFIX $CONF_ARGS --enable-nvenc --enable-nvdec --enable-rpath"
|
|
command -v clang >/dev/null || CONF_ARGS=$(echo "$CONF_ARGS" | sed 's/--enable-cuda-llvm //')
|
|
|
|
echo "==> configure"
|
|
export PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig:${PKG_CONFIG_PATH:-}"
|
|
cd "$BUILD_DIR/src"
|
|
# shellcheck disable=SC2086
|
|
./configure $CONF_ARGS
|
|
|
|
echo "==> make ($(nproc) jobs) — this takes a few minutes"
|
|
make -j"$(nproc)"
|
|
make install
|
|
|
|
echo
|
|
echo "==> done. Verify (all three must succeed):"
|
|
echo " ldd $PREFIX/bin/ffmpeg | grep avcodec # MUST print $PREFIX/lib/..."
|
|
echo " hash -r; which ffmpeg # should print $PREFIX/bin/ffmpeg"
|
|
echo " $PREFIX/bin/ffmpeg -hide_banner -loglevel error -f lavfi -i 'color=c=black:s=256x256:d=0.2' -c:v hevc_nvenc -f null -"
|