HW accel codecs bypass the CPU entirely — SIMD-optimized software paths are irrelevant. Dropping x86asm removes ffmpeg's build-time nasm dependency. nasm stays in setup.sh for x264 and libjpeg. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
206 lines
6.6 KiB
Bash
Executable File
206 lines
6.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -e
|
|
|
|
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
|
cd "$DIR"
|
|
|
|
PLATFORM="$(uname -s)"
|
|
FFMPEG_VERSION="7.1"
|
|
ZLIB_VERSION="da607da739fa6047df13e66a2af6b8bec7c2a498" # v1.3.2
|
|
X264_BRANCH="stable"
|
|
LIBDRM_VERSION="libdrm-2.4.124"
|
|
LIBVA_VERSION="2.22.0"
|
|
INSTALL_DIR="$DIR/ffmpeg/install"
|
|
|
|
NJOBS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)"
|
|
CC="ccache ${CC:-cc}"
|
|
PREFIX="$DIR/build/prefix"
|
|
mkdir -p "$DIR/build"
|
|
|
|
# --- Build zlib (static) ---
|
|
if [ ! -d "zlib-src/.git" ]; then
|
|
rm -rf zlib-src
|
|
git clone --depth 1 https://github.com/madler/zlib.git zlib-src
|
|
fi
|
|
git -C zlib-src fetch --depth 1 origin "$ZLIB_VERSION"
|
|
git -C zlib-src checkout --force "$ZLIB_VERSION"
|
|
|
|
cd zlib-src
|
|
./configure --prefix="$PREFIX" --static
|
|
make -j"$NJOBS"
|
|
make install
|
|
cd "$DIR"
|
|
|
|
# --- Build x264 (static) ---
|
|
if [ ! -d "x264-src/.git" ]; then
|
|
rm -rf x264-src
|
|
git clone --depth 1 https://code.videolan.org/videolan/x264.git x264-src
|
|
fi
|
|
git -C x264-src fetch --depth 1 origin "$X264_BRANCH"
|
|
git -C x264-src checkout --force FETCH_HEAD
|
|
|
|
cd x264-src
|
|
CFLAGS="-fno-finite-math-only" ./configure \
|
|
--prefix="$PREFIX" \
|
|
--enable-static \
|
|
--disable-shared \
|
|
--disable-cli \
|
|
--disable-opencl \
|
|
--enable-pic
|
|
make -j"$NJOBS"
|
|
make install
|
|
cd "$DIR"
|
|
|
|
# --- Build nv-codec-headers (Linux only, for CUDA/NVDEC) ---
|
|
if [ "$PLATFORM" = "Linux" ]; then
|
|
if [ ! -d "nv-codec-headers-src/.git" ]; then
|
|
rm -rf nv-codec-headers-src
|
|
git clone --depth 1 https://git.videolan.org/git/ffmpeg/nv-codec-headers.git nv-codec-headers-src
|
|
fi
|
|
make -C nv-codec-headers-src PREFIX="$PREFIX" install
|
|
fi
|
|
|
|
# --- Build Vulkan-Headers from source (Linux only, need >= 1.3.277 for FFmpeg 7.1) ---
|
|
if [ "$PLATFORM" = "Linux" ]; then
|
|
if [ ! -d "vulkan-headers-src/.git" ]; then
|
|
rm -rf vulkan-headers-src
|
|
git clone --depth 1 https://github.com/KhronosGroup/Vulkan-Headers.git vulkan-headers-src
|
|
fi
|
|
cmake -S vulkan-headers-src -B vulkan-headers-src/build -DCMAKE_INSTALL_PREFIX="$PREFIX" >/dev/null
|
|
cmake --install vulkan-headers-src/build >/dev/null
|
|
fi
|
|
|
|
# --- Build libdrm + libva statically (Linux only, for VAAPI without runtime deps) ---
|
|
if [ "$PLATFORM" = "Linux" ]; then
|
|
if ! command -v meson &>/dev/null; then
|
|
pip3 install --quiet meson ninja 2>/dev/null || python3 -m pip install --quiet meson ninja 2>/dev/null || true
|
|
command -v meson &>/dev/null || { echo "error: meson is required (apt install meson or pip install meson)" >&2; exit 1; }
|
|
fi
|
|
|
|
if [ ! -d "libdrm-src/.git" ]; then
|
|
rm -rf libdrm-src
|
|
git clone --depth 1 --branch "$LIBDRM_VERSION" https://gitlab.freedesktop.org/mesa/drm.git libdrm-src
|
|
fi
|
|
rm -rf libdrm-src/builddir
|
|
meson setup libdrm-src/builddir libdrm-src \
|
|
--prefix="$PREFIX" --libdir=lib --default-library=static \
|
|
-Dintel=disabled -Dradeon=disabled -Damdgpu=disabled -Dnouveau=disabled \
|
|
-Dvmwgfx=disabled -Dtests=false -Dman-pages=disabled -Dcairo-tests=disabled \
|
|
-Dvalgrind=disabled
|
|
ninja -C libdrm-src/builddir install
|
|
|
|
if [ ! -d "libva-src/.git" ]; then
|
|
rm -rf libva-src
|
|
git clone --depth 1 --branch "$LIBVA_VERSION" https://github.com/intel/libva.git libva-src
|
|
fi
|
|
rm -rf libva-src/builddir
|
|
# libva hardcodes shared_library(); patch to library() so --default-library=static works
|
|
sed -i 's/shared_library(/library(/g' libva-src/va/meson.build
|
|
PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" \
|
|
meson setup libva-src/builddir libva-src \
|
|
--prefix="$PREFIX" --libdir=lib --default-library=static \
|
|
-Ddisable_drm=false -Dwith_x11=no -Dwith_glx=no -Dwith_wayland=no \
|
|
-Dwith_win32=no -Denable_docs=false
|
|
ninja -C libva-src/builddir install
|
|
fi
|
|
|
|
# --- Build FFmpeg ---
|
|
if [ ! -d "ffmpeg-src/.git" ]; then
|
|
rm -rf ffmpeg-src
|
|
git clone --depth 1 https://github.com/FFmpeg/FFmpeg.git ffmpeg-src
|
|
fi
|
|
git -C ffmpeg-src fetch --depth 1 origin "n${FFMPEG_VERSION}"
|
|
git -C ffmpeg-src checkout --force FETCH_HEAD
|
|
|
|
cd ffmpeg-src
|
|
|
|
# Platform-specific hardware acceleration flags
|
|
HW_FLAGS=()
|
|
if [ "$PLATFORM" = "Linux" ]; then
|
|
HW_FLAGS+=(
|
|
# NVIDIA CUDA/NVDEC (uses dlopen at runtime)
|
|
--enable-ffnvcodec --enable-cuda --enable-cuvid --enable-nvdec
|
|
--enable-hwaccel=h264_nvdec,hevc_nvdec
|
|
--enable-decoder=h264_cuvid,hevc_cuvid
|
|
|
|
# VAAPI (Intel/AMD — libva linked statically, driver loaded via dlopen at runtime)
|
|
--enable-vaapi
|
|
--enable-hwaccel=h264_vaapi,hevc_vaapi
|
|
|
|
# V4L2 Memory-to-Memory (embedded: RPi, Qualcomm, Rockchip)
|
|
--enable-v4l2-m2m
|
|
--enable-decoder=h264_v4l2m2m,hevc_v4l2m2m
|
|
--enable-encoder=h264_v4l2m2m,hevc_v4l2m2m
|
|
|
|
# Vulkan video decode/encode (uses dlopen at runtime)
|
|
--enable-vulkan
|
|
--enable-hwaccel=h264_vulkan,hevc_vulkan
|
|
--enable-encoder=h264_vulkan,hevc_vulkan
|
|
)
|
|
elif [ "$PLATFORM" = "Darwin" ]; then
|
|
HW_FLAGS+=(
|
|
# VideoToolbox (Apple Silicon / macOS)
|
|
--enable-videotoolbox
|
|
--enable-hwaccel=h264_videotoolbox,hevc_videotoolbox
|
|
--enable-encoder=h264_videotoolbox,hevc_videotoolbox
|
|
)
|
|
fi
|
|
|
|
PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" \
|
|
./configure \
|
|
--cc="${CC:-cc}" \
|
|
--prefix="$PREFIX" \
|
|
--enable-gpl \
|
|
--enable-static \
|
|
--disable-shared \
|
|
--enable-zlib \
|
|
--enable-libx264 \
|
|
--enable-pic \
|
|
--disable-doc \
|
|
--disable-ffplay \
|
|
--disable-autodetect \
|
|
--disable-x86asm \
|
|
--disable-everything \
|
|
--enable-encoder=libx264,aac,ffvhuff,rawvideo,png,mjpeg \
|
|
--enable-decoder=h264,hevc,ffvhuff,aac,rawvideo,png,mjpeg,mp3,pcm_s16le \
|
|
--enable-muxer=mpegts,matroska,mp4,hevc,rawvideo,image2,null,mov,framehash \
|
|
--enable-demuxer=hevc,matroska,mpegts,mov,rawvideo,image2,aac,concat \
|
|
--enable-parser=h264,hevc,aac,mpegaudio \
|
|
--enable-protocol=file,pipe \
|
|
--enable-filter=blend,vflip,format,scale,aformat,anull,aresample,null \
|
|
--enable-bsf=extract_extradata,h264_mp4toannexb,hevc_mp4toannexb \
|
|
--extra-cflags="-I$PREFIX/include" \
|
|
--extra-ldflags="-L$PREFIX/lib" \
|
|
"${HW_FLAGS[@]}"
|
|
make -j"$NJOBS"
|
|
make install
|
|
cd "$DIR"
|
|
|
|
# Copy to package install dir
|
|
rm -rf "$INSTALL_DIR"
|
|
mkdir -p "$INSTALL_DIR"/{bin,lib,include}
|
|
|
|
# Binaries
|
|
cp "$PREFIX/bin/ffmpeg" "$INSTALL_DIR/bin/"
|
|
cp "$PREFIX/bin/ffprobe" "$INSTALL_DIR/bin/"
|
|
|
|
# Libraries
|
|
LIBS="libavformat.a libavcodec.a libavutil.a libswresample.a libx264.a libz.a"
|
|
if [ "$PLATFORM" = "Linux" ]; then
|
|
LIBS="$LIBS libva.a libva-drm.a libdrm.a"
|
|
fi
|
|
for lib in $LIBS; do
|
|
cp "$PREFIX/lib/$lib" "$INSTALL_DIR/lib/"
|
|
done
|
|
|
|
# Headers
|
|
for dir in libavformat libavcodec libavutil libswresample; do
|
|
cp -r "$PREFIX/include/$dir" "$INSTALL_DIR/include/"
|
|
done
|
|
|
|
# Strip binaries
|
|
strip "$INSTALL_DIR/bin/ffmpeg" "$INSTALL_DIR/bin/ffprobe" 2>/dev/null || true
|
|
|
|
echo "Installed ffmpeg to $INSTALL_DIR"
|
|
du -sh "$INSTALL_DIR"
|