From 4f802136929fbd67cd458697cfe98b0ac72026a1 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 18 Jun 2026 07:50:54 +0000 Subject: [PATCH 1/2] Add AMF support --- README.md | 5 + docker-images/8.0/amf2404/Dockerfile | 212 +++++ docker-images/8.0/amf2404/build_source.sh | 464 ++++++++++ .../8.0/amf2404/download_tarballs.sh | 143 +++ ...enerate-source-of-truth-ffmpeg-versions.py | 845 ++++++++++++++++++ docker-images/8.0/amf2404/install_ffmpeg.sh | 128 +++ docker-images/8.1/amf2404/Dockerfile | 212 +++++ docker-images/8.1/amf2404/build_source.sh | 464 ++++++++++ .../8.1/amf2404/download_tarballs.sh | 143 +++ ...enerate-source-of-truth-ffmpeg-versions.py | 845 ++++++++++++++++++ docker-images/8.1/amf2404/install_ffmpeg.sh | 128 +++ docker-images/github-actions-matrix.json | 46 + docker-images/gitlab-ci.yml | 27 + templates/Dockerfile-env-amf | 96 ++ templates/Dockerfile-run-amf | 31 + templates/Dockerfile-template.amf2404 | 85 ++ update.py | 9 + 17 files changed, 3883 insertions(+) create mode 100644 docker-images/8.0/amf2404/Dockerfile create mode 100755 docker-images/8.0/amf2404/build_source.sh create mode 100755 docker-images/8.0/amf2404/download_tarballs.sh create mode 100755 docker-images/8.0/amf2404/generate-source-of-truth-ffmpeg-versions.py create mode 100755 docker-images/8.0/amf2404/install_ffmpeg.sh create mode 100644 docker-images/8.1/amf2404/Dockerfile create mode 100755 docker-images/8.1/amf2404/build_source.sh create mode 100755 docker-images/8.1/amf2404/download_tarballs.sh create mode 100755 docker-images/8.1/amf2404/generate-source-of-truth-ffmpeg-versions.py create mode 100755 docker-images/8.1/amf2404/install_ffmpeg.sh create mode 100644 templates/Dockerfile-env-amf create mode 100644 templates/Dockerfile-run-amf create mode 100644 templates/Dockerfile-template.amf2404 diff --git a/README.md b/README.md index 20ac1279..0b124ec3 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ Below is a table that provides examples for the nomenclature: | ffmpeg-8.1-ubuntu2404 | 24.04 | 8.x | amd64, arm64 | [ubuntu](https://releases.ubuntu.com/) | external libraries are installed from os packages, and ffmpeg is built from source. See [Ubuntu Compilation Guide](https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu) for details on this. | | ffmpeg-8.1-ubuntu2404-edge | 24.04 | 8.x | amd64, arm64 | [ubuntu](https://releases.ubuntu.com/) | libs and ffmpeg are built from source. See [Ubuntu Compilation Guide](https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu) for details on this. | | ffmpeg-8.1-vaapi2404 | 24.04 | 8.x | amd64 | [ubuntu](https://releases.ubuntu.com/) | like: `ubuntu2404` but enables: [Video Acceleration API (VAAPI)](https://trac.ffmpeg.org/wiki/HWAccelIntro#VAAPI) in ffmpeg | +| ffmpeg-8.1-amf2404 | 24.04 | 8.x | amd64 | [ubuntu](https://releases.ubuntu.com/) | like: `ubuntu2404` but enables: [AMD Advanced Media Framework (AMF)](https://github.com/GPUOpen-LibrariesAndSDKs/AMF/wiki/Build-FFmpeg-with-AMF-Support) in ffmpeg | | ffmpeg-8.1-nvidia2404 | 24.04 | 8.x | amd64 | [ubuntu](https://releases.ubuntu.com/) | Built w/ [NVIDIA's hardware-accelerated encoding and decoding APIs](https://trac.ffmpeg.org/wiki/HWAccelIntro#CUDANVENCNVDEC) enabled | | ffmpeg-8.1-alpine320 | 3.20 | 8.x | amd64, arm64 | [alpine](https://alpinelinux.org/releases/) | vendor libs, but ffmpeg is built from source | | ffmpeg-8.1-scratch320 | 3.20 | 8.x | amd64, arm64 | [alpine](https://alpinelinux.org/releases/) | vendor libs, and ffmpeg are built from source. Also we make the distro as small as possible by not installing any packages in base and striping symbols of installed libs | @@ -43,6 +44,7 @@ Note: The current versions of ffmpeg supported are anything newer than 3 years o - ubuntu based images `ffmpeg:-ubuntu` or `ffmpeg:-ubuntu2404` (old versions with `ffmpeg:-ubuntu2004` , `ffmpeg:-ubuntu1804`) - ubuntu based nvidia images `ffmpeg:-nvidia` or `ffmpeg:-nvidia2404` (old versions with `ffmpeg:-nvidia2204`, `ffmpeg:-nvidia2004`) - ubuntu based vaapi images `ffmpeg:-vaapi2404` (old versions with `ffmpeg:-vaapi2004`, `ffmpeg:-vaapi1804`) + - ubuntu based amf images `ffmpeg:-amf2404` @@ -58,6 +60,9 @@ This image is just like the above `ubuntu2404` container image, except we build **vaapi2404** Based on `ubuntu2404` with [Video Acceleration API (VAAPI)](https://trac.ffmpeg.org/wiki/HWAccelIntro#VAAPI) enabled. +**amf2404** + Based on `ubuntu2404` with [AMD Advanced Media Framework (AMF)](https://github.com/GPUOpen-LibrariesAndSDKs/AMF/wiki/Build-FFmpeg-with-AMF-Support) enabled. + **nvidia2404** Based on `ubuntu2404` with [NVIDIA's hardware-accelerated encoding and decoding APIs](https://trac.ffmpeg.org/wiki/HWAccelIntro#CUDANVENCNVDEC) enabled. diff --git a/docker-images/8.0/amf2404/Dockerfile b/docker-images/8.0/amf2404/Dockerfile new file mode 100644 index 00000000..834321f5 --- /dev/null +++ b/docker-images/8.0/amf2404/Dockerfile @@ -0,0 +1,212 @@ +# ffmpeg - http://ffmpeg.org/download.html +# +# From https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu +# +# https://hub.docker.com/r/jrottenberg/ffmpeg/ +# +# +# Stage 1: Build +FROM ubuntu:24.04 AS builder + + +ENV FFMPEG_VERSION=8.0.2 + +ENV AMD_AMF_VERSION=v1.5.2 + +## opencore-amr - https://sourceforge.net/projects/opencore-amr/ +## x264 - http://www.videolan.org/developers/x264.html +## x265 - http://x265.org/ ( videolan ) +## libogg - https://www.xiph.org/ogg/ ( xiph ) +## libopus - https://www.opus-codec.org/ ( xiph ) +## - https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libopus +## libvorbis - https://xiph.org/vorbis/ ( xiph ) +## libvpx - https://www.webmproject.org/code/ +## - https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libvpx +## libwebp - https://developers.google.com/speed/webp/ +## libmp3lame - http://lame.sourceforge.net/ +## xvid - https://www.xvid.com/ (xvidcore) +## fdk-aac - https://github.com/mstorsjo/fdk-aac +## - https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libfdk-aac +## openjpeg - https://github.com/uclouvain/openjpeg +## freetype - https://www.freetype.org/ +## consider passing --no-install-recommends for this one its globbie (if you do, pass in libfreetype6) +## libvidstab - https://github.com/georgmartius/vid.stab +## fridibi - https://www.fribidi.org/ +## fontconfig - https://www.freedesktop.org/wiki/Software/fontconfig/ +## libass - https://github.com/libass/libass +## lib aom - https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libaom +## libsvtav1 - https://gitlab.com/AOMediaCodec/SVT-AV1.git +## - https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libsvtav1 +## libdav1d - https://code.videolan.org/videolan/dav1d +## - https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libdav1d +## util-macros - (x.org) (and supporting libraries) for screen capture https://xcb.freedesktop.org/ +## xorgproto - (x.org) +## libXau - +## libpthread - libpthread-stubs +## libxml2 - for libbluray +## libbluray - Requires libxml, freetype, and fontconfig +## libzmq - https://github.com/zeromq/libzmq/ +## this one pulls in a bunch of dependencies +## libpng - this one also pulls in a bunch of stuff +## libaribb24 - +## zimg - https://github.com/sekrit-twc/zimg +## libtheora - http://www.theora.org/ ( xiph ) +## - https://stackoverflow.com/questions/4810996/how-to-resolve-configure-guessing-build-type-failure +## libsrt - https://github.com/Haivision/srt +## Secure Reliable Transport UDP streaming library +## multiple flavors (OpenSSL flavour) and ( GnuTLS flavour) +ARG OPENCORE_PKGS="libopencore-amrnb-dev libopencore-amrnb0 libopencore-amrwb-dev libopencore-amrwb0" +ARG X264_PKGS="libx264-164 libx264-dev" +ARG X265_PKGS="libnuma1 libx265-199 libx265-dev" +# libnuma-dev +ARG OGG_PKGS="libogg-dev libogg0" +ARG OPUS_PKGS="libopus-dev libopus0" +ARG VORBIS_PKGS="libvorbis-dev libvorbis0a libvorbisenc2 libvorbisfile3" +ARG VPX_PKGS="libvpx-dev libvpx9" +ARG WEBP_PKGS="libsharpyuv-dev libsharpyuv0 libwebp-dev libwebp7 libwebpdecoder3 libwebpdemux2 libwebpmux3" +ARG MP3LAME_PKGS="libmp3lame-dev libmp3lame0" +ARG XVIDCORE_PKGS="libxvidcore-dev libxvidcore4" +ARG FDKAAC_PKGS="libfdk-aac-dev libfdk-aac2" +ARG OPENJP_PKGS="libopenjp2-7 libopenjp2-7-dev" +# bzip2-doc fontconfig-config fonts-dejavu-core fonts-dejavu-mono libaom3 libbrotli-dev +# libbrotli1 libbsd0 libbz2-dev libc-dev-bin libc-devtools libc6-dev libcrypt-dev libde265-0 +# libdeflate0 libfontconfig1 libfreetype6 libgd3 libheif-plugin-aomdec +# libheif-plugin-aomenc libheif-plugin-libde265 libheif1 libjbig0 libjpeg-turbo8 +# libjpeg8 liblerc4 libpng-dev libpng-tools libpng16-16t64 libsharpyuv0 libtiff6 +# libwebp7 libx11-6 libx11-data libxau6 libxcb1 libxdmcp6 libxpm4 linux-libc-dev +# manpages manpages-dev rpcsvc-proto zlib1g-dev +ARG FREETYPE_PKGS="libfreetype6-dev" +ARG FONTCONFIG_PKGS="fontconfig libfontconfig-dev libfontconfig1 fontconfig-config fonts-dejavu-core fonts-dejavu-mono" +ARG VIDSTAB_PKGS="libvidstab-dev libvidstab1.1" +ARG FRIBIDI_PKGS="libfribidi-dev libfribidi0" +# libass-dev wanted to install a boat-load of packages +ARG LIBASS_PKGS="libass-dev libass9" +ARG AOM_PKGS="libaom-dev libaom3" +ARG SVTAV1_PKGS="libsvtav1-dev libsvtav1enc-dev libsvtav1enc1d1 libsvtav1dec-dev libsvtav1dec0" +ARG DAV1D_PKGS="libdav1d-dev libdav1d7" +# LIBDRM_PKGS picks ups some of the XORG_MACROS_PKGS as well +ARG XORG_MACROS_PKGS="libxcb-shm0-dev libxcb-shm0 libxcb-xfixes0 libxcb-xfixes0-dev" +ARG XPROTO_PKGS="x11proto-core-dev x11proto-dev" +ARG XAU_PKGS="libxau-dev libxau6" +ARG PTHREADS_STUBS_PKGS="libpthread-stubs0-dev" +ARG XML2_PKGS="libxml2-dev libxml2" +ARG BLURAY_PKGS="libbluray-dev libbluray2" +ARG ZMQ_PKGS="libzmq3-dev libzmq5" +# libpng-tools +ARG PNG_PKGS="libpng-dev libpng16-16t64" +ARG ARIBB24_PKGS="libaribb24-dev" +ARG ZIMG_PKGS="libzimg-dev libzimg2" +ARG THEORA_PKGS="libtheora-dev libtheora0" +ARG SRT_PKGS="libssl-dev libsrt-openssl-dev libsrt1.5-openssl" +ARG LIBDRM_PKGS="libbsd0 libdrm-dev libdrm2 libxcb1-dev libxcb1" + +ENV MAKEFLAGS="-j4" +ENV PKG_CONFIG_PATH="/opt/ffmpeg/share/pkgconfig:/opt/ffmpeg/lib/pkgconfig:/opt/ffmpeg/lib64/pkgconfig:/opt/ffmpeg/lib/x86_64-linux-gnu/pkgconfig:/opt/ffmpeg/lib/aarch64-linux-gnu/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig" + +ENV PREFIX="/opt/ffmpeg" +ENV LD_LIBRARY_PATH="/opt/ffmpeg/lib:/opt/ffmpeg/lib64:/opt/ffmpeg/lib/aarch64-linux-gnu" + + +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get -yqq update && \ + apt-get install -yq --no-install-recommends curl jq python3 python3-requests less tree file vim + +RUN buildDeps="autoconf \ + automake \ + cmake \ + build-essential \ + texinfo \ + curl \ + wget \ + tar \ + bzip2 \ + libexpat1-dev \ + gcc \ + git \ + git-core \ + gperf \ + libtool \ + make \ + meson \ + ninja-build \ + nasm \ + perl \ + pkg-config \ + python3 \ + yasm \ + zlib1g-dev \ + libfreetype6-dev \ + libgnutls28-dev \ + libsdl2-dev \ + libva-dev \ + libvdpau-dev \ + libnuma-dev \ + libdav1d-dev \ + openssl \ + libssl-dev \ + expat \ + libgomp1" && \ + apt-get -yqq update && \ + apt-get install -yq --no-install-recommends ${buildDeps} + +WORKDIR /tmp/workdir + +COPY generate-source-of-truth-ffmpeg-versions.py /tmp/workdir +COPY download_tarballs.sh /tmp/workdir +COPY build_source.sh /tmp/workdir +COPY install_ffmpeg.sh /tmp/workdir + + + +RUN \ + echo "Installing dependencies..." && \ + apt-get install -yq --no-install-recommends ${OPENCORE_PKGS} ${X264_PKGS} ${X265_PKGS} ${OGG_PKGS} ${OPUS_PKGS} ${VORBIS_PKGS} ${VPX_PKGS} ${WEBP_PKGS} ${MP3LAME_PKGS} ${XVIDCORE_PKGS} ${FDKAAC_PKGS} ${OPENJP_PKGS} ${FREETYPE_PKGS} ${VIDSTAB_PKGS} ${FRIBIDI_PKGS} ${FONTCONFIG_PKGS} ${LIBASS_PKGS} ${AOM_PKGS} ${SVTAV1_PKGS} ${DAV1D_PKGS} ${XORG_MACROS_PKGS} ${XPROTO_PKGS} ${XAU_PKGS} ${PTHREADS_STUBS_PKGS} ${XML2_PKGS} ${BLURAY_PKGS} ${ZMQ_PKGS} ${PNG_PKGS} ${ARIBB24_PKGS} ${ZIMG_PKGS} ${THEORA_PKGS} ${SRT_PKGS} ${LIBDRM_PKGS} + +RUN \ + git clone --branch ${AMD_AMF_VERSION} --depth 1 https://github.com/GPUOpen-LibrariesAndSDKs/AMF.git /tmp/amf && \ + mkdir -p /usr/local/include/AMF && \ + cp -a /tmp/amf/amf/public/include/. /usr/local/include/AMF/ && \ + rm -rf /tmp/amf + +# apt install libdrm-dev + +## libvmaf https://github.com/Netflix/vmaf +## https://github.com/Netflix/vmaf/issues/788#issuecomment-756098059 +RUN \ + echo "Adding g++ for VMAF build" && \ + apt-get install -yq g++ + +# Note: pass '--library-list lib1,lib2,lib3 for more control. +# Here we have 3 libs that we have to build from source +RUN /tmp/workdir/generate-source-of-truth-ffmpeg-versions.py --library-list kvazaar,libvmaf,whisper +RUN /tmp/workdir/download_tarballs.sh +RUN /tmp/workdir/build_source.sh + +RUN /tmp/workdir/generate-source-of-truth-ffmpeg-versions.py --library-list ffmpeg-8.0 +RUN /tmp/workdir/download_tarballs.sh +RUN /tmp/workdir/build_source.sh + +## when debugging you can pass in || true to the end of the command +## to keep the build going even if one of the steps fails +RUN /tmp/workdir/install_ffmpeg.sh + + + +# Stage 2: Final Image ( shrink the size back down ) +FROM ubuntu:24.04 AS runtime +# Copy fonts and fontconfig from builder +COPY --from=builder /usr/share/fonts /usr/share/fonts +COPY --from=builder /usr/share/fontconfig /usr/share/fontconfig +COPY --from=builder /usr/bin/fc-* /usr/bin/ + +# Copy rest of the content +COPY --from=builder /usr/local /usr/local/ + +LABEL org.opencontainers.image.authors="julien@rottenberg.info" \ + org.opencontainers.image.source=https://github.com/jrottenberg/ffmpeg + +ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64 + +CMD ["--help"] +ENTRYPOINT ["ffmpeg"] diff --git a/docker-images/8.0/amf2404/build_source.sh b/docker-images/8.0/amf2404/build_source.sh new file mode 100755 index 00000000..19d96ef5 --- /dev/null +++ b/docker-images/8.0/amf2404/build_source.sh @@ -0,0 +1,464 @@ +#!/usr/bin/env bash + +# Stop execution on any error +# Note: we can override this in the Dockerfile RUN command with an || true. +# which is useful for debugging +set -e + +manifestJsonFile="/tmp/workdir/generated_build_manifest.json" +manifestJsonVersionsFile="/tmp/workdir/generated_build_versions_manifest.json" + +OS_NAME=$(uname -s) +is_ubuntu=false +is_alpine=false +if [[ "$OS_NAME" == "Linux" ]]; then + if grep -q "Ubuntu" /etc/os-release; then + is_ubuntu=true + elif grep -q "Alpine Linux" /etc/alpine-release; then + is_alpine=true + fi +fi + +ARCH=$(uname -m) +is_x86=false +if [[ "$ARCH" == "x86_64" ]]; then + is_x86=true +fi +######################### Callback build functions ######################### +build_libopencore-amr() { + ./configure --prefix="${PREFIX}" --enable-shared + make + make install +} + +build_libx264() { + ./configure --prefix="${PREFIX}" --enable-shared --enable-pic --disable-cli + make + make install +} + +build_libx265() { + cd build/linux + sed -i "/-DEXTRA_LIB/ s/$/ -DCMAKE_INSTALL_PREFIX=\${PREFIX}/" multilib.sh + sed -i "/^cmake/ s/$/ -DENABLE_CLI=OFF/" multilib.sh + if [ "$is_x86" = false ]; then + sed -i "/^cmake/ s/$/ -DENABLE_ASSEMBLY=OFF/" multilib.sh + fi + ./multilib.sh + make -C 8bit install +} + +build_libogg() { + ./configure --prefix="${PREFIX}" --enable-shared + make + make install +} + +build_libopus() { + ./configure --prefix="${PREFIX}" --enable-shared + make + make install +} + +build_libvorbis() { + ./configure --prefix="${PREFIX}" --with-ogg="${PREFIX}" --enable-shared + make + make install + # https://gitlab.xiph.org/xiph/vorbis + # cmake -G YOUR-PROJECT-GENERATOR -DBUILD_SHARED_LIBS=1 -DCMAKE_INSTALL_PREFIX="${PREFIX}" . + # make + # make install +} + +build_libvpx() { + local data=$(jq -r '.[] | select(.library_name == "libvpx")' $manifestJsonFile) + local dir=$(echo "$data" | jq -r '.build_dir') + local vpx_version=$(jq -r '.["libvpx"]' $manifestJsonVersionsFile) + if [ -n "$vpx_version" ] && [[ "$vpx_version" != "null" ]]; then + echo "Building [libvpx-${vpx_version}] in [${dir}]" + else + echo "Error: libvpx version is empty or unset" + fi + version="v${vpx_version}" + git -C libvpx pull 2> /dev/null || git clone --branch ${version} --depth 1 https://chromium.googlesource.com/webm/libvpx.git + cd libvpx + pwd + local vpx_configure_flags="--prefix=${PREFIX} --disable-examples --disable-unit-tests --enable-vp9-highbitdepth --enable-pic --enable-shared" + if [ "$is_x86" = true ]; then + vpx_configure_flags="${vpx_configure_flags} --as=yasm" + fi + ./configure ${vpx_configure_flags} + make + make install +} + +build_libwebp() { + ./configure --prefix="${PREFIX}" --enable-shared && \ + make && \ + make install +} + +build_libmp3lame() { + local nasm_flag="--enable-nasm" + if [ "$is_x86" = false ]; then + nasm_flag="--disable-nasm" + fi + ./configure --prefix="${PREFIX}" --bindir="${PREFIX}/bin" --enable-shared ${nasm_flag} --disable-frontend && \ + make && \ + make install +} + + +build_libxvid() { + # read doc/INSTALL + cd build/generic + ./configure --help + echo "Now guess" + ./configure --prefix="${PREFIX}" --bindir="${PREFIX}/bin --enable-shared" + make + make install +} + +build_libfdk-aac() { + autoreconf -fiv && \ + ./configure --prefix="${PREFIX}" --enable-shared + make + make install +} + +build_openjpeg() { + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="${PREFIX}" . && \ + make && \ + make install +} + +build_freetype() { + ./configure --prefix="${PREFIX}" --disable-static --enable-shared && \ + make && \ + make install +} + +build_libvidstab() { + cmake -DCMAKE_INSTALL_PREFIX="${PREFIX}" . && \ + make && \ + make install +} + +build_fribidi() { + # Currently broken, need to fix + # sed -i 's/^SUBDIRS =.*/SUBDIRS=gen.tab charset lib bin/' Makefile.am + # ./bootstrap --no-config --auto + ./configure --prefix="${PREFIX}" --disable-static --enable-shared + make -j1 + make install +} + +build_fontconfig() { + meson setup build --prefix="${PREFIX}" --default-library=shared && \ + ninja -C build && \ + ninja -C build install +} + +build_libass() { + ./autogen.sh && \ + ./configure --prefix="${PREFIX}" --disable-static --enable-shared && \ + make && \ + make install +} + +build_kvazaar() { + # ./autogen.sh && \ + ./configure --prefix="${PREFIX}" --disable-static --enable-shared && \ + make && \ + make install +} + +# aom is a git clone ( to get source, so not in the loop using the callback function) +build_aom() { + local data=$(jq -r '.[] | select(.library_name == "aom")' $manifestJsonFile) + local dir=$(echo "$data" | jq -r '.build_dir') + local aom_version=$(jq -r '.["aom"]' $manifestJsonVersionsFile) # Access value with key "aom" + if [ -n "$aom_version" ] && [[ "$aom_version" != "null" ]]; then + echo "Building [aom-${aom_version}] in [${dir}]" + else + echo "Error: aom version is empty or unset" + fi + version="v${aom_version}" + git clone --branch ${version} --depth 1 https://aomedia.googlesource.com/aom ${dir} && \ + cd ${dir} && \ + mkdir -p ./aom_build && \ + cd ./aom_build && \ + local nasm_flag="-DENABLE_NASM=on" + if [ "$is_x86" = false ]; then + nasm_flag="-DENABLE_NASM=off" + fi + cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="${PREFIX}" -DBUILD_SHARED_LIBS=1 ${nasm_flag} .. && \ + make && \ + make install +} + +build_nvidia-codec-headers() { + local dir=${1} + # git clone https://github.com/FFmpeg/nv-codec-headers ${dir} + # git checkout n${NVIDIA_HEADERS_VERSION} + make PREFIX="${PREFIX}" + make install PREFIX="${PREFIX}" +} + +build_libsvtav1() { + cd Build && \ + cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="${PREFIX}" -DCMAKE_BUILD_TYPE=Release -DBUILD_DEC=OFF -DBUILD_SHARED_LIBS=OFF .. \ + make && \ + make install +} + +build_xorg-macros() { + dir=${1} + ./configure --srcdir=${dir} --prefix="${PREFIX}" && \ + make && \ + make install +} + +build_xorgproto() { + meson setup build --prefix="${PREFIX}" && \ + ninja -C build && \ + ninja -C build install +} + +build_libxau() { + dir=${1} + ./configure --srcdir=${dir} --prefix="${PREFIX}" && \ + make && \ + make install +} + +build_libpthread-stubs() { + ./configure --prefix="${PREFIX}" && \ + make && \ + make install +} + +build_libxml2() { + ./autogen.sh --prefix="${PREFIX}" --with-ftp=no --with-http=no --with-python=no && \ + make && \ + make install +} + +build_libbluray() { + ## libbluray - Requires libxml, freetype, and fontconfig + ./configure --prefix="${PREFIX}" --disable-examples --disable-bdjava-jar --disable-static --enable-shared && \ + make && \ + make install +} + +build_libzmq() { + ./autogen.sh && \ + ./configure --prefix="${PREFIX}" && \ + make && \ + make install +} + +# another special, code clone situation ( actually currently using the tarball build approach ) +build_libpng() { + local dir = "/tmp/png" + # local libpng_version=$(jq -r '.["libpng"]' $manifestJsonVersionsFile) # Access value with key "libpng" + # git clone https://git.code.sf.net/p/libpng/code ${dir} -b v${libpng_version} --depth 1 && \ + ./autogen.sh && \ + ./configure --prefix="${PREFIX}" && \ + make check && \ + make install +} + +build_libaribb24() { + autoreconf -fiv && \ + ./configure CFLAGS="-I${PREFIX}/include -fPIC" --prefix="${PREFIX}" && \ + make && \ + make install +} + +build_zimg() { + ./autogen.sh && \ + ./configure --prefix="${PREFIX}" --enable-shared && \ + make && \ + make install +} + +# Dependancy on libogg +build_libtheora() { + ./configure --prefix="${PREFIX}" --with-ogg="${PREFIX}" --enable-shared --disable-examples + make + make install +} + +build_libsrt() { + # requires libssl-dev + cmake -DCMAKE_INSTALL_PREFIX="${PREFIX}" . && \ + make && \ + make install +} + +build_libvmaf() { + # https://github.com/Netflix/vmaf/issues/788#issuecomment-756098059 + mkdir ./libvmaf/build + cd ./libvmaf/build + meson setup -Denable_tests=false -Denable_docs=false --buildtype=release --default-library=static --prefix "${PREFIX}" .. && \ + # meson setup -Denable_tests=false -Denable_docs=false --buildtype=release --default-library=shared --prefix "${PREFIX}" .. + ninja + ninja install +} + +build_whisper() { + cmake -B build -S . \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=${PREFIX} \ + -DGGML_STATIC=OFF + + cmake --build build -j$(nproc) + + mkdir -p ${PREFIX}/include ${PREFIX}/lib ${PREFIX}/lib/pkgconfig + cp -av include/whisper.h ggml/include/ggml*.h ${PREFIX}/include/ + find ./build -name "*.so*" -exec cp -av {} ${PREFIX}/lib/ \; + cp ./build/whisper.pc ${PREFIX}/lib/pkgconfig/ +} + + + + +build_ffmpeg() { + # Here is a list of things that we enable in the ffmpeg build: that are not in the + # track configuration guide: https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#FFmpeg + # --enable-fontconfig + # --enable-libaribb24 + # --enable-libbluray + # --enable-libkvazaar + # --enable-libopencore-amrnb + # --enable-libopencore-amrwb + # --enable-libopenjpeg + # --enable-libsrt + # --enable-libtheora + # --enable-libvmaf + # --enable-libwebp + # --enable-libxvid + # --enable-libzimg + # --enable-libzmq + # --enable-openssl + # --enable-postproc + # --enable-small + # --enable-version3 + + ./configure --disable-debug \ + --disable-doc \ + --disable-ffplay \ + --enable-amf \ + --enable-fontconfig \ + --enable-gpl \ + --enable-libaom \ + --enable-libaribb24 \ + --enable-libass \ + --enable-libbluray \ + --enable-libdav1d \ + --enable-libfdk-aac \ + --enable-libfontconfig \ + --enable-libfreetype \ + --enable-libfribidi \ + --enable-libharfbuzz \ + --enable-libkvazaar \ + --enable-libmp3lame \ + --enable-libopencore-amrnb \ + --enable-libopencore-amrwb \ + --enable-libopenjpeg \ + --enable-libopus \ + --enable-libsrt \ + --enable-libsvtav1 \ + --enable-libtheora \ + --enable-libvidstab \ + --enable-libvmaf \ + --enable-libvorbis \ + --enable-libvpx \ + --enable-libwebp \ + --enable-libx264 \ + --enable-libx265 \ + --enable-libxvid \ + --enable-libzimg \ + --enable-libzmq \ + --enable-nonfree \ + --enable-openssl \ + --enable-shared \ + --enable-small \ + --enable-version3 \ + --enable-whisper \ + --extra-cflags="-I${PREFIX}/include -I/usr/local/include -I/usr/include/x86_64-linux-gnu -I/usr/include/aarch64-linux-gnu" \ + --extra-ldflags="-L${PREFIX}/lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/aarch64-linux-gnu -L/usr/lib" \ + --extra-ldflags=-L/opt/ffmpeg/lib/aarch64-linux-gnu \ + --extra-ldflags=-L/opt/ffmpeg/lib/x86_64-linux-gnu \ + --extra-libs=-ldl \ + --extra-libs=-lm \ + --extra-libs=-lpthread \ + --ld=g++ \ + --prefix="${PREFIX}" && \ + make && \ + make install && \ + make tools/zmqsend && cp -av tools/zmqsend ${PREFIX}/bin/ && \ + make distclean && \ + hash -r && \ + cd tools && \ + make qt-faststart && cp qt-faststart ${PREFIX}/bin/ +} +######################### Helper functions ######################### +extract_tarball() { + local tarball_name=$1 + # grab the extension of the tarball + local extension="${tarball_name##*.}" + # tar extraction args: -z, -j, -J, --lzma Compress archive with gzip/bzip2/xz/lzma + if [ "$extension" == "gz" ]; then + tar -zx --strip-components=1 -f ${tarball_name} + elif [ "$extension" == "bz2" ]; then + tar -jx --strip-components=1 -f ${tarball_name} + elif [ "$extension" == "xz" ]; then + tar -Jx --strip-components=1 -f ${tarball_name} + else + echo "Error while extract_tarball, got an unknown extension: $extension" + fi +} + +build_support_libraries() { + local librariesRaw="$(jq -r '.[] | .library_name' $manifestJsonFile)" + local libs=( $librariesRaw ) + for i in "${!libs[@]}"; do + lib_name=${libs[$i]} + # handle the clone source case's ( there are only two ) + # if [ "$lib_name" == "libsvtav1" ]; then + # echo "-------------------- Running callback: build_aom --------------------" + # echo "Building 'aom' before we build $lib_name" + # build_aom + # fi + # ffmpeg is in the lib_name string then the callback name is build_ffmpeg + callback_lib_name=${lib_name} + if [[ "$lib_name" == *"ffmpeg"* ]]; then + # take out the version numbers + callback_lib_name="ffmpeg" + fi + + local data=$(jq -r '.[] | select(.library_name == "'${lib_name}'")' $manifestJsonFile) + build_dir=$(echo "$data" | jq -r '.build_dir') + tarball_name=$(echo "$data" | jq -r '.tarball_name') + sha256sum=$(echo "$data" | jq -r '.sha256sum') + + echo "Building $lib_name: from ${build_dir}/$tarball_name" + cd $build_dir + extract_tarball $tarball_name + if [ -n "$sha256sum" ] && [[ "$sha256sum" != "null" ]]; then + echo "Checking sha256sum for $tarball_name" + echo $sha256sum | sha256sum --check + fi + # make a callback function to build the library + # if anything fails, we will exit with a non-zero status + echo "-------------------- Running callback: build_${lib_name} --------------------" + build_${callback_lib_name} ${build_dir} + echo "Finished building $lib_name removing build directory [${build_dir}]" + cd /tmp/workdir + rm -rf $build_dir + done +} + +build_support_libraries diff --git a/docker-images/8.0/amf2404/download_tarballs.sh b/docker-images/8.0/amf2404/download_tarballs.sh new file mode 100755 index 00000000..2fcf49aa --- /dev/null +++ b/docker-images/8.0/amf2404/download_tarballs.sh @@ -0,0 +1,143 @@ +#!/usr/bin/env bash + +# The point of this script is to read in the list of tarballs to download from generated_build_manifest.json +# using jq and then download them into their build directories. +# +# The point, we need robust re-tries, as sometimes the download fails, and we need to be able to re-try. +# and verify that the download was successful. + +manifestJsonFile="/tmp/workdir/generated_build_manifest.json" + +report_on_failed_downloads() { + local librariesRaw="$(jq -r '.[] | .library_name' $manifestJsonFile)" + local libs=( $librariesRaw ) + local count=0 + + for i in "${!libs[@]}"; do + lib_name=${libs[$i]} + local data=$(jq -r '.[] | select(.library_name == "'${lib_name}'")' $manifestJsonFile) + build_dir=$(echo "$data" | jq -r '.build_dir') + tarball_name=$(echo "$data" | jq -r '.tarball_name') + # if tarball_name does not exist, then it could be a source repo build + # just check the directory + if [ -z "$tarball_name" ]; then + if [ ! -d "$build_dir" ]; then + echo "Error: $build_dir does not exist" + ((count++)) + fi + fi + if [ ! -f "$build_dir/$tarball_name" ]; then + echo "Error: $build_dir/$tarball_name does not exist" + ((count++)) + fi + done + echo "Failed to download $count tarballs" +} + +actual_number_of_downloads_completed() { + local librariesRaw="$(jq -r '.[] | .library_name' $manifestJsonFile)" + local libs=( $librariesRaw ) + local count=0 + + for i in "${!libs[@]}"; do + lib_name=${libs[$i]} + local data=$(jq -r '.[] | select(.library_name == "'${lib_name}'")' $manifestJsonFile) + build_dir=$(echo "$data" | jq -r '.build_dir') + tarball_name=$(echo "$data" | jq -r '.tarball_name') + # if tarball_name does not exist, then it could be a source repo build + # just check the directory + if [[ -z "$tarball_name" || "$tarball_name" == "null" ]]; then + if [ -d "$build_dir" ]; then + ((count++)) + fi + fi + if [ -f "$build_dir/$tarball_name" ]; then + ((count++)) + fi + done + echo $count # Return the count as output +} +number_of_tarballs_to_download() { + local librariesRaw="$(jq -r '.[] | .library_name' $manifestJsonFile)" + local libs=( $librariesRaw ) + echo "${#libs[@]}" # return count as output +} + +download_tarballs() { + # the default argument of quiet is false + quiet=${1:-false} + local librariesRaw="$(jq -r '.[] | .library_name' $manifestJsonFile)" + local libs=( $librariesRaw ) + echo "Downloading (${#libs[@]} libraries)..." + for i in "${!libs[@]}"; do + # echo "Downloading ${libs[$i]}..." + lib_name=${libs[$i]} + # use double quotes around '${lib_name}', so Bash will expand the value. + build_dir=$(jq -r '.[] | select(.library_name == "'${lib_name}'") | .build_dir' $manifestJsonFile) + download_url=$(jq -r '.[] | select(.library_name == "'${lib_name}'") | .download_url' $manifestJsonFile) + tarball_name=$(jq -r '.[] | select(.library_name == "'${lib_name}'") | .tarball_name' $manifestJsonFile) + if [ -z "$build_dir" ]; then + echo "Error: build_dir, is empty" + exit 1 + fi + + # does the directory exist? if not make it + if [ ! -d "$build_dir" ]; then + mkdir -p "$build_dir" + fi + # handle edge case for source repo builds (git clone ) + if [[ -z "$tarball_name" || -z "$download_url" || "$tarball_name" == "null" || "$download_url" == "null" ]]; then + echo "Warning: tarball_name, or download_url is empty or unset (ok in a source repo build)" + continue + fi + echo "Downloading: ${download_url} to: ${build_dir} ${tarball_name}" + if [ -z "$build_dir" ] || [ -z "$download_url" ] || [ -z "$tarball_name" ]; then + echo "Error: build_dir, download_url, or tarball_name is empty" + exit 1 + fi + # if the tarball_file does not exhist then download it + if [ ! -f "$build_dir/$tarball_name" ]; then + echo "$build_dir/$tarball_name does not exist, downloading now..." + cd "$build_dir" + local http_code + http_code=$(curl -sL --retry 2 -o "$tarball_name" -w "%{http_code}" "$download_url") + if [ "$http_code" = "418" ]; then + echo "Got HTTP 418 (anti-bot) for ${download_url}, waiting 60s before retry..." + rm -f "$tarball_name" + sleep 60 + curl -fsSL --retry 2 -o "$tarball_name" "$download_url" + elif [ "$http_code" -ge 400 ] 2>/dev/null; then + echo "curl: HTTP $http_code for ${download_url}" + rm -f "$tarball_name" + fi + else + # if not quietly, then echo that we are skipping the download + [ "$quiet" = false ] && + echo "$build_dir/$tarball_name already exists, skipping download" + fi + done +} + +num_to_download=1 # at least 1 +num_completed=0 +number_of_times_to_retry=6 +download_tarballs_called_number=0 +num_completed=$(actual_number_of_downloads_completed) +num_to_download=$(number_of_tarballs_to_download) +echo "Starting to download ${num_to_download} tarball images" +while [ $num_completed -lt $num_to_download ] && [ $number_of_times_to_retry -gt $download_tarballs_called_number ]; do + ((download_tarballs_called_number++)) + download_tarballs + sleep 5 + num_completed=$(actual_number_of_downloads_completed) + num_to_download=$(number_of_tarballs_to_download) + echo "Downloaded ${num_completed} of ${num_to_download} tarball images on pass ${download_tarballs_called_number}" +done + +if [ $num_completed -lt $num_to_download ]; then + echo "Failed to download all tarballs after $download_tarballs_called_number attempts" + report_on_failed_downloads + exit 1 +fi +echo "Successfully Downloaded the ${num_completed} tarball images after $download_tarballs_called_number attempts" +exit 0 diff --git a/docker-images/8.0/amf2404/generate-source-of-truth-ffmpeg-versions.py b/docker-images/8.0/amf2404/generate-source-of-truth-ffmpeg-versions.py new file mode 100755 index 00000000..4a4e6eda --- /dev/null +++ b/docker-images/8.0/amf2404/generate-source-of-truth-ffmpeg-versions.py @@ -0,0 +1,845 @@ +#!/usr/bin/env python3 + +import argparse +import json +import sys +from collections import OrderedDict + +""" +------- Purpose ------- +...This is the source of truth... +1. This script generates a table of the libraries used by FFMPEG that + will be included in the main README.md file of the repository. +2. This script generates a 'build_manifest.json' file that contains the + the download links, build directories, and build tarball names for + each library. ( Required to generate a robust re-try download of the package tarballs) + +------- Setup ------- +This script is run in the container to generate 'build_manifest.json' +However, it is also used to generate a generated_versions_table.md file. +The steps for doing that are below. +To run this script you need the ?? library. You can install it with pip: +in a venv as follows: + +$ python3 -mvenv .venv +$ source .venv/bin/activate +$ pip install ?? +$ python3 ./generate-source-of-truth-ffmpeg-versions.py +$ deactivate +$ rm -rf .venv + +The output of this script will be a table in markdown format, which you can +paste into the README.md file of the repository. +""" + +# Library versions Source of truth +AOM = {"version": "3.10.0", "release_date": "2024-08-01"} +FDKAAC = {"version": "2.0.3", "release_date": "2023-12-21"} +FFMPEG_80 = {"version": "8.0", "release_date": "2025-08-22"} +FFMPEG_81 = {"version": "8.1", "release_date": "2025-11-28"} +FONTCONFIG = {"version": "2.15.0", "release_date": "2023-12-22"} +FREETYPE = {"version": "2.13.3", "release_date": "2024-08-12"} +KVAAZAAR = {"version": "2.3.1", "release_date": "2024-04-10"} +LAME = {"version": "3.100", "release_date": "2017-10-13"} +LIBARIBB24 = {"version": "1.0.3", "release_date": "2014-08-18"} +LIBASS = {"version": "0.17.3", "release_date": "2024-07-02"} +LIBBLURAY = {"version": "1.3.4", "release_date": "2022-11-26"} +LIBFRIDIBI = {"version": "1.0.16", "release_date": "2024-10-1"} +LIBPNG = {"version": "1.6.44", "release_date": "2024-09-12"} +LIBSRT = {"version": "1.5.3", "release_date": "2023-09-07"} +LIBVIDSTAB = {"version": "1.1.1", "release_date": "2022-05-30"} +LIBVMAF = {"version": "3.0.0", "release_date": "2023-12-07"} +LIBXML2 = {"version": "2.13.4", "release_date": "2024-09-01"} +LIBZMQ = {"version": "4.3.5", "release_date": "2023-10-9"} +NV_CODEC = {"version": "12.2.72.0", "release_date": "2024-03-31"} +OGG = {"version": "1.3.5", "release_date": "2021-06-04"} +OPENCOREAMR = {"version": "0.1.6", "release_date": "2022-08-01"} +OPENJPEG = {"version": "2.5.2", "release_date": "2024-02-28"} +OPUS = {"version": "1.5.2", "release_date": "2024-04-12"} +PTHREAD_STUBS = {"version": "0.5", "release_date": "2023-07-18"} +SVTAV1 = {"version": "2.2.1", "release_date": "2024-08-01"} +THEORA = {"version": "1.2.0", "release_date": "2025-03-29"} +VORBIS = {"version": "1.3.7", "release_date": "2020-07-04"} +VPX = {"version": "1.14.1", "release_date": "2024-05-30"} +WEBP = {"version": "1.4.0", "release_date": "2024-04-13"} +WHISPER = {"version": "1.7.6", "release_date": "2025-06-25"} +X264 = {"version": "20191217-2245-stable", "release_date": "2019-12-17"} +X265 = {"version": "4.0", "release_date": "2024-09-13"} +XAU = {"version": "1.0.11", "release_date": "2022-12-08"} +XORG_MACROS = {"version": "1.20.1", "release_date": "2024-04-16"} +XORGPROTO = {"version": "2024.1", "release_date": "2024-04-12"} +XVID = {"version": "1.3.7", "release_date": "2019"} +ZIMG = {"version": "3.0.5", "release_date": "2023-6-30"} + +# Library details, Source of truth +# TODO: store this in a yaml configuration file ( would probably be better ) +# flake8: noqa E501 +LIBRARIES = OrderedDict( + [ + ( + "whisper", + { + "link": "https://github.com/ggml-org/whisper.cpp", + "version": WHISPER["version"], + "version_link": "https://github.com/ggml-org/whisper.cpp/releases", + "release_date": WHISPER["release_date"], + "license_name": "MIT License", + "license_link": "https://github.com/ggml-org/whisper.cpp/blob/master/LICENSE", + "build_info": { + "download_link": f"https://github.com/ggml-org/whisper.cpp/archive/refs/tags/v{WHISPER['version']}.tar.gz", + "build_dir": "/tmp/whisper", + "tarball_name": f"whisper-v{WHISPER['version']}.tar.gz", + }, + }, + ), + ( + "libopencore-amr", + { + "link": "https://sourceforge.net/projects/opencore-amr/", + "version": OPENCOREAMR["version"], + "version_link": "https://sourceforge.net/projects/opencore-amr/files/opencore-amr/", + "release_date": OPENCOREAMR["release_date"], + "license_name": "Apache License", + "license_link": "https://sourceforge.net/p/opencore-amr/code/ci/master/tree/LICENSE", + "build_info": { + # this one of the finikie download link's ( and the reason we wrote the download_tarball.sh script) + "download_link": f"https://sourceforge.net/projects/opencore-amr/files/opencore-amr/opencore-amr-{OPENCOREAMR['version']}.tar.gz", + "build_dir": "/tmp/libopencore-amr", + "tarball_name": f"opencore-amr-{OPENCOREAMR['version']}.tar.gz", + }, + }, + ), + ( + "libx264", + { + "link": "https://www.videolan.org/developers/x264.html", + "version": X264["version"], + "version_link": "https://download.videolan.org/pub/videolan/x264/snapshots/", + "release_date": X264["release_date"], + "license_name": "GNU General Public License (GPL) version 2", + "license_link": "https://www.gnu.org/licenses/old-licenses/gpl-2.0.html", + "build_info": { + "download_link": f"https://download.videolan.org/pub/videolan/x264/snapshots/x264-snapshot-{X264['version']}.tar.bz2", + "build_dir": "/tmp/x264", + "tarball_name": f"x264-snapshot-{X264['version']}.tar.bz2", + }, + }, + ), + ( + "libx265", + { + "link": "http://x265.org/", + "version": X265["version"], + # "https://www.x265.org/downloads/", + "version_link": "http://ftp.videolan.org/pub/videolan/x265/", + "release_date": X265["release_date"], + "license_name": "GNU General Public License (GPL) version 2", + "license_link": "https://bitbucket.org/multicoreware/x265/raw/f8ae7afc1f61ed0db3b2f23f5d581706fe6ed677/COPYING", + "build_info": { + "download_link": f"http://ftp.videolan.org/pub/videolan/x265/x265_{X265['version']}.tar.gz", + "build_dir": "/tmp/x265", + "tarball_name": f"x265_{X265['version']}.tar.gz", + }, + }, + ), + ( + "libogg", + { + "link": "https://www.xiph.org/ogg/", + "version": OGG["version"], + "version_link": "https://xiph.org/downloads/", + "release_date": OGG["release_date"], + "license_name": "BSD-style license", + # TODO: check this link + "license_link": "https://git.xiph.org/?p=mirrors/ogg.git;a=blob_plain;f=COPYING;hb=HEAD", + "build_info": { + "download_link": f"https://downloads.xiph.org/releases/ogg/libogg-{OGG['version']}.tar.gz", + "build_dir": "/tmp/libogg", + "tarball_name": f"libogg-{OGG['version']}.tar.gz", + }, + }, + ), + ( + "libopus", + { + "link": "https://www.opus-codec.org/", + # https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libopus + "version": OPUS["version"], + "version_link": "https://www.opus-codec.org/downloads/", + # https://ftp.osuosl.org/pub/xiph/releases/opus/ + "release_date": OPUS["release_date"], + "license_name": "BSD-style license", + "license_link": "https://www.xiph.org/licenses/bsd/", # https://opus-codec.org/license/ + "build_info": { + "download_link": f"https://github.com/xiph/opus/releases/download/v{OPUS['version']}/opus-{OPUS['version']}.tar.gz", + "build_dir": "/tmp/opus", + "tarball_name": f"opus-{OPUS['version']}.tar.gz", + "sha256sum": "65c1d2f78b9f2fb20082c38cbe47c951ad5839345876e46941612ee87f9a7ce1 opus-1.5.2.tar.gz", + }, + }, + ), + ( + "libvorbis", + { + "link": "https://xiph.org/vorbis/", + "version": VORBIS["version"], + "version_link": "https://xiph.org/downloads/", + "release_date": VORBIS["release_date"], + "license_name": "BSD-style license", + "license_link": "https://www.xiph.org/licenses/bsd/", + "build_info": { + "download_link": f"http://downloads.xiph.org/releases/vorbis/libvorbis-{VORBIS['version']}.tar.gz", + "build_dir": "/tmp/vorbis", + "tarball_name": f"libvorbis-{VORBIS['version']}.tar.gz", + "sha256sum": "0e982409a9c3fc82ee06e08205b1355e5c6aa4c36bca58146ef399621b0ce5ab libvorbis-1.3.7.tar.gz", + }, + }, + ), + ( + "libvpx", + { + "link": "https://www.webmproject.org/code/", + # https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libvpx + "version": VPX["version"], + "version_link": "https://chromium.googlesource.com/webm/libvpx.git/", + "release_date": VPX["release_date"], + "license_name": "BSD-style license", + "license_link": "https://github.com/webmproject/libvpx/blob/master/LICENSE", + "build_info": { + # "download_link": f"https://chromium.googlesource.com/webm/libvpx/+archive/v{VPX['version']}.tar.gz", + "build_dir": "/tmp/libvpx", + # "tarball_name": f"libvpx-v{VPX['version']}.tar.gz", + }, + }, + ), + ( + "libwebp", + { + "link": "https://developers.google.com/speed/webp/", + # https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libwebp + "version": WEBP["version"], + "version_link": "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/index.html", + "release_date": WEBP["release_date"], + "license_name": "BSD-style license", + "license_link": "https://github.com/webmproject/libvpx/blob/master/LICENSE", + "build_info": { + "download_link": f"https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-{WEBP['version']}.tar.gz", + "build_dir": "/tmp/webp", + "tarball_name": f"libwebp-{WEBP['version']}.tar.gz", + }, + }, + ), + ( + "libmp3lame", + { + "link": "http://lame.sourceforge.net/", + "version": LAME["version"], + "version_link": "http://lame.sourceforge.net/download.php", + "release_date": LAME["release_date"], + "license_name": "GNU Lesser General Public License (LGPL) version 2.1", + "license_link": "http://lame.cvs.sourceforge.net/viewvc/lame/lame/LICENSE?revision=1.9", + "build_info": { + # this one is also testie + "download_link": f"https://sourceforge.net/projects/lame/files/lame/{LAME['version']}/lame-{LAME['version']}.tar.gz", + "build_dir": "/tmp/lame", + "tarball_name": f"lame-{LAME['version']}.tar.gz", + }, + }, + ), + ( + "libxvid", + { + "link": "https://www.xvid.com/", + "version": XVID["version"], + "version_link": "https://labs.xvid.com/source/", + "release_date": XVID["release_date"], + "license_name": "GNU General Public Licence (GPL) version 2", + "license_link": "http://websvn.xvid.org/cvs/viewvc.cgi/trunk/xvidcore/LICENSE?revision=851", + "build_info": { + "download_link": f"https://downloads.xvid.com/downloads/xvidcore-{XVID['version']}.tar.gz", + "build_dir": "/tmp/xvid", + "tarball_name": f"xvidcore-{XVID['version']}.tar.gz", + }, + }, + ), + ( + "libfdk-aac", + { + "link": "https://github.com/mstorsjo/fdk-aac", + # https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libfdk-aac + "version": FDKAAC["version"], + "version_link": "https://github.com/mstorsjo/fdk-aac/tags", + "release_date": FDKAAC["release_date"], + "license_name": "Liberal but not a license of patented technologies", + "license_link": "https://github.com/mstorsjo/fdk-aac/blob/master/NOTICE", + "build_info": { + "download_link": f"https://github.com/mstorsjo/fdk-aac/archive/refs/tags/v{FDKAAC['version']}.tar.gz", + "build_dir": "/tmp/fdk-aac", + "tarball_name": f"fdk-aac-{FDKAAC['version']}.tar.gz", + }, + }, + ), + ( + "openjpeg", + { + "link": "https://github.com/uclouvain/openjpeg", + "version": OPENJPEG["version"], + "version_link": "https://github.com/uclouvain/openjpeg/releases", + "release_date": OPENJPEG["release_date"], + "license_name": "BSD-style license", + "license_link": "https://github.com/uclouvain/openjpeg/blob/master/LICENSE", + "build_info": { + "download_link": f"https://github.com/uclouvain/openjpeg/archive/refs/tags/v{OPENJPEG['version']}.tar.gz", + "build_dir": "/tmp/openjpeg", + "tarball_name": f"openjpeg-{OPENJPEG['version']}.tar.gz", + }, + }, + ), + ( + "freetype", + { + "link": "https://www.freetype.org/", + "version": FREETYPE["version"], + "version_link": "http://download.savannah.gnu.org/releases/freetype/", + "release_date": FREETYPE["release_date"], + "license_name": "GNU General Public License (GPL) version 2", + "license_link": "https://www.freetype.org/license.html", + "build_info": { + "download_link": f"http://download.savannah.gnu.org/releases/freetype/freetype-{FREETYPE['version']}.tar.gz", + "build_dir": "/tmp/freetype", + "tarball_name": f"freetype-{FREETYPE['version']}.tar.gz", + }, + }, + ), + ( + "libvidstab", + { + "link": "https://github.com/georgmartius/vid.stab", + "version": LIBVIDSTAB["version"], + "version_link": "https://github.com/georgmartius/vid.stab/tags", + "release_date": LIBVIDSTAB["release_date"], + "license_name": "GNU General Public License (GPL) version 2", + "license_link": "https://github.com/georgmartius/vid.stab/blob/master/LICENSE", + "build_info": { + "download_link": f"https://github.com/georgmartius/vid.stab/archive/v{LIBVIDSTAB['version']}.tar.gz", + "build_dir": "/tmp/vid.stab", + "tarball_name": f"vid.stab-{LIBVIDSTAB['version']}.tar.gz", + }, + }, + ), + ( + "fribidi", + { + "link": "https://www.fribidi.org/", + "version": LIBFRIDIBI["version"], + "version_link": "https://github.com/fribidi/fribidi/releases", + "release_date": LIBFRIDIBI["release_date"], + "license_name": "GNU General Public License (GPL) version 2", + "license_link": "https://cgit.freedesktop.org/fribidi/fribidi/plain/COPYING", + "build_info": { + "download_link": f"https://github.com/fribidi/fribidi/archive/refs/tags/v{LIBFRIDIBI['version']}.tar.gz", + "build_dir": "/tmp/fribidi", + "tarball_name": f"fribidi-{LIBFRIDIBI['version']}.tar.gz", + "using_source_build": False, + # "sha256sum": "3fc96fa9473bd31dcb5500bdf1aa78b337ba13eb8c301e7c28923fea982453a8 fribidi-{LIBFRIDIBI['version']}.tar.gz" + }, + }, + ), + ( + "fontconfig", + { + "link": "https://gitlab.freedesktop.org/fontconfig/fontconfig", + "version": FONTCONFIG["version"], + "version_link": "https://gitlab.freedesktop.org/fontconfig/fontconfig/-/tags", + "release_date": FONTCONFIG["release_date"], + "license_name": "", + "license_link": "", + "build_info": { + "download_link": f"https://gitlab.freedesktop.org/fontconfig/fontconfig/-/archive/{FONTCONFIG['version']}/fontconfig-{FONTCONFIG['version']}.tar.gz", + "build_dir": "/tmp/fontconfig", + "tarball_name": f"fontconfig-{FONTCONFIG['version']}.tar.gz", + }, + }, + ), + ( + "libass", + { + "link": "https://github.com/libass/libass", + "version": LIBASS["version"], + "version_link": "https://github.com/libass/libass/releases", + "release_date": LIBASS["release_date"], + "license_name": "ISC License", + "license_link": "https://github.com/libass/libass/blob/master/COPYING", + "build_info": { + "download_link": f"https://github.com/libass/libass/releases/download/{LIBASS['version']}/libass-{LIBASS['version']}.tar.gz", + "build_dir": "/tmp/libass", + "tarball_name": f"libass-{LIBASS['version']}.tar.gz", + "using_source_build": False, + }, + }, + ), + ( + "kvazaar", + { + "link": "https://github.com/ultravideo/kvazaar", + "version": KVAAZAAR["version"], + "version_link": "https://github.com/ultravideo/kvazaar/releases", + "release_date": KVAAZAAR["release_date"], + "license_name": "BSD 3-Clause", + "license_link": "https://github.com/ultravideo/kvazaar/blob/master/LICENSE`", + "build_info": { + "download_link": f"https://github.com/ultravideo/kvazaar/releases/download/v{KVAAZAAR['version']}/kvazaar-{KVAAZAAR['version']}.tar.gz", + "build_dir": "/tmp/kvazaar", + "tarball_name": f"kvazaar-{KVAAZAAR['version']}.tar.gz", + }, + }, + ), + ( + "aom", + { + "link": "https://aomedia.googlesource.com/aom", + "version": AOM["version"], + "version_link": "https://aomedia.googlesource.com/aom/+refs", + "release_date": AOM["release_date"], + "license_name": "Alliance for Open Media", + "license_link": "https://aomedia.org/license/software-license/", + "build_info": { + "build_dir": "/tmp/aom", + }, + }, + ), + ( + "nvidia-codec-headers", + { + "link": "https://github.com/FFmpeg/nv-codec-headers", + "version": NV_CODEC["version"], + "version_link": "", + "release_date": NV_CODEC["release_date"], + "license_name": "", + "license_link": "", + "build_info": { + "download_link": f"https://github.com/FFmpeg/nv-codec-headers/releases/download/n{NV_CODEC['version']}/nv-codec-headers-{NV_CODEC['version']}.tar.gz", + # "download_link": f"https://github.com/FFmpeg/nv-codec-headers/archive/refs/tags/n{NV_CODEC['version']}.tar.gz", + "build_dir": "/tmp/nv-codec-headers", + "tarball_name": f"nv-codec-headers-{NV_CODEC['version']}.tar.gz", + }, + }, + ), + ( + "libsvtav1", + { + "link": "https://gitlab.com/AOMediaCodec/SVT-AV1", + "version": SVTAV1["version"], + "version_link": "https://gitlab.com/AOMediaCodec/SVT-AV1/-/tags", + "release_date": SVTAV1["release_date"], + "license_name": "BSD 3-Clause Clear License", + "license_link": "https://gitlab.com/AOMediaCodec/SVT-AV1/-/blob/master/LICENSE.md?ref_type=heads", + "build_info": { + "download_link": f"https://gitlab.com/AOMediaCodec/SVT-AV1/-/archive/v{SVTAV1['version']}/SVT-AV1-v{SVTAV1['version']}.tar.gz", + "build_dir": "/tmp/libsvtav1", + "tarball_name": f"SVT-AV1-v{SVTAV1['version']}.tar.gz", + }, + }, + ), + ( + "xorg-macros", + { + "link": "https://xcb.freedesktop.org/", + "version": XORG_MACROS["version"], + "version_link": "https://www.x.org/releases/individual/util/", + "release_date": XORG_MACROS["release_date"], + "license_name": "The MIT License", + "license_link": "https://opensource.org/licenses/MIT", + "build_info": { + "download_link": f"https://www.x.org/releases/individual/util/util-macros-{XORG_MACROS['version']}.tar.xz", + "build_dir": "/tmp/xorg-macros", + "tarball_name": f"util-macros-{XORG_MACROS['version']}.tar.xz", + "using_source_build": False, + }, + }, + ), + ( + "xorgproto", + { + "link": "https://www.x.org/releases/individual/proto/", + "version": XORGPROTO["version"], + "version_link": "https://www.x.org/releases/individual/proto/", + "release_date": XORGPROTO["release_date"], + "license_name": "The MIT License", + "license_link": "https://opensource.org/licenses/MIT", + "build_info": { + "download_link": f"https://www.x.org/releases/individual/proto/xorgproto-{XORGPROTO['version']}.tar.xz", + "build_dir": "/tmp/xorgproto", + "tarball_name": f"xorgproto-{XORGPROTO['version']}.tar.xz", + }, + }, + ), + ( + "libxau", + { + "link": "https://www.x.org/releases/individual/lib/", + "version": XAU["version"], + "version_link": "https://www.x.org/releases/individual/lib/", + "release_date": XAU["release_date"], + "license_name": "The MIT License", + "license_link": "https://opensource.org/licenses/MIT", + "build_info": { + "download_link": f"https://www.x.org/releases/individual/lib/libXau-{XAU['version']}.tar.xz", + "build_dir": "/tmp/libXau", + "tarball_name": f"libXau-{XAU['version']}.tar.xz", + "using_source_build": False, + }, + }, + ), + ( + "libpthread-stubs", + { + "link": "https://xcb.freedesktop.org/dist/", + "version": PTHREAD_STUBS["version"], + "version_link": "https://xcb.freedesktop.org/dist/", + "release_date": PTHREAD_STUBS["release_date"], + "license_name": "The MIT License", + "license_link": "https://opensource.org/licenses/MIT", + "build_info": { + "download_link": f"https://xcb.freedesktop.org/dist/libpthread-stubs-{PTHREAD_STUBS['version']}.tar.xz", + "build_dir": "/tmp/libpthread-stubs", + "tarball_name": f"libpthread-stubs-{PTHREAD_STUBS['version']}.tar.xz", + # "using_source_build": False, + }, + }, + ), + ( + "libxml2", + { + "link": "http://www.xmlsoft.org/", + "version": LIBXML2["version"], + "version_link": "http://www.xmlsoft.org/downloads.html", + "release_date": LIBXML2["release_date"], + "license_name": "MIT License", + "license_link": "http://www.xmlsoft.org/license.html", + "build_info": { + "download_link": f"https://gitlab.gnome.org/GNOME/libxml2/-/archive/v{LIBXML2['version']}/libxml2-v{LIBXML2['version']}.tar.gz", + "build_dir": "/tmp/libxml2", + "tarball_name": f"libxml2-{LIBXML2['version']}.tar.gz", + "using_source_build": False, + }, + }, + ), + ( + "libbluray", + { + "link": "https://www.videolan.org/developers/libbluray.html", + "version": LIBBLURAY["version"], + "version_link": "https://download.videolan.org/pub/videolan/libbluray/", + "release_date": LIBBLURAY["release_date"], + "license_name": "GNU General Public License (GPL) version 2", + "license_link": "https://www.gnu.org/licenses/old-licenses/gpl-2.0.html", + "build_info": { + "download_link": f"https://download.videolan.org/pub/videolan/libbluray/{LIBBLURAY['version']}/libbluray-{LIBBLURAY['version']}.tar.bz2", + "build_dir": "/tmp/libbluray", + "tarball_name": f"libbluray-{LIBBLURAY['version']}.tar.bz2", + }, + }, + ), + ( + "libzmq", + { + "link": "https://github.com/zeromq/libzmq/", + "version": LIBZMQ["version"], + "version_link": "https://github.com/zeromq/libzmq/releases/", + "release_date": LIBZMQ["release_date"], + "license_name": "Mozilla Public License (MPL) version 2.0", + "license_link": f"https://github.com/zeromq/libzmq/blob/v{LIBZMQ['version']}/LICENSE", + "build_info": { + "download_link": f"https://github.com/zeromq/libzmq/releases/download/v{LIBZMQ['version']}/zeromq-{LIBZMQ['version']}.tar.gz", + "build_dir": "/tmp/libzmq", + "tarball_name": f"zeromq-{LIBZMQ['version']}.tar.gz", + }, + }, + ), + ( + "libpng", + { + "link": "http://www.libpng.org/pub/png/libpng.html", + "version": LIBPNG["version"], + "version_link": "https://sourceforge.net/projects/libpng/files/libpng16/", + "release_date": LIBPNG["release_date"], + "license_name": "PNG Reference Library License version 2", + "license_link": "http://www.libpng.org/pub/png/src/libpng-LICENSE.txt", + "build_info": { + # sourceforge is a bit finikie + # https://sourceforge.net/projects/libpng/files/libpng16/1.6.44/libpng-1.6.44.tar.gz/download + # https://download.sourceforge.net/libpng/libpng-1.6.44.tar.xz + "download_link": f"https://download.sourceforge.net/libpng/libpng-{LIBPNG['version']}.tar.xz", + "build_dir": "/tmp/libpng", + "tarball_name": f"libpng-{LIBPNG['version']}.tar.xz", + "using_source_build": False, + }, + }, + ), + ( + "libaribb24", + { + "link": "https://github.com/nkoriyama/aribb24/", + "version": LIBARIBB24["version"], + "version_link": "https://github.com/nkoriyama/aribb24/releases", + "release_date": LIBARIBB24["release_date"], + "license_name": "GNU Lesser General Public License (LGPL) version 2.1 or newer", + "license_link": "https://github.com/nkoriyama/aribb24/issues/9", + "build_info": { + "download_link": f"https://github.com/nkoriyama/aribb24/archive/refs/tags/v{LIBARIBB24['version']}.tar.gz", + "build_dir": "/tmp/b24", + "tarball_name": f"aribb24-v{LIBARIBB24['version']}.tar.gz", + }, + }, + ), + ( + "zimg", + { + "link": "https://github.com/sekrit-twc/zimg", + "version": ZIMG["version"], + "version_link": "https://github.com/sekrit-twc/zimg/releases", + "release_date": ZIMG["release_date"], + "license_name": "WTFPL", + "license_link": "https://github.com/sekrit-twc/zimg?tab=WTFPL-1-ov-file", + "build_info": { + "download_link": f"https://github.com/sekrit-twc/zimg/archive/refs/tags/release-{ZIMG['version']}.tar.gz", + "build_dir": "/tmp/zimg", + "tarball_name": f"zimg-{ZIMG['version']}.tar.gz", + }, + }, + ), + ( + "libtheora", + { + "link": "https://xiph.org/downloads/", + "version": THEORA["version"], + "version_link": "https://xiph.org/downloads/", + "release_date": THEORA["release_date"], + "license_name": "BSD-style license", + "license_link": "https://git.xiph.org/?p=mirrors/theora.git;a=blob_plain;f=COPYING;hb=HEAD", + "build_info": { + "download_link": f"https://downloads.xiph.org/releases/theora/libtheora-{THEORA['version']}.tar.gz", + "build_dir": "/tmp/theora", + "tarball_name": f"libtheora-{THEORA['version']}.tar.gz", + }, + }, + ), + ( + "libsrt", + { + "link": "https://github.com/Haivision/srt", + "version": LIBSRT["version"], + "version_link": "https://github.com/Haivision/srt/releases/", + "release_date": LIBSRT["release_date"], + "license_name": "Mozilla Public License (MPL) version 2.0", + "license_link": "https://github.com/Haivision/srt/blob/master/LICENSE", + "build_info": { + "download_link": f"https://github.com/Haivision/srt/archive/refs/tags/v{LIBSRT['version']}.tar.gz", + "build_dir": "/tmp/srt", + "tarball_name": f"srt-v{LIBSRT['version']}.tar.gz", + }, + }, + ), + ( + "libvmaf", + { + "link": "https://github.com/Netflix/vmaf", + # https://github.com/Netflix/vmaf/issues/788 + "version": LIBVMAF["version"], + "version_link": "https://github.com/Netflix/vmaf/releases", + "release_date": LIBVMAF["release_date"], + "license_name": "BSD-2-Clause", + "license_link": "https://github.com/Netflix/vmaf/blob/master/LICENSE", + "build_info": { + "download_link": f"https://github.com/Netflix/vmaf/archive/refs/tags/v{LIBVMAF['version']}.tar.gz", + "build_dir": "/tmp/vmaf", + "tarball_name": f"vmaf-v{LIBVMAF['version']}.tar.gz", + }, + }, + ), + ( + "ffmpeg-8.1", + { + "link": "http://ffmpeg.org/", + "version": FFMPEG_81["version"], + "version_link": "http://ffmpeg.org/releases/", + "release_date": FFMPEG_81["release_date"], + "license_name": "GNU Lesser General Public License (LGPL) version 2.1", + "license_link": "https://ffmpeg.org/legal.html", + "build_info": { + "download_link": f"https://ffmpeg.org/releases/ffmpeg-{FFMPEG_81['version']}.tar.bz2", + "build_dir": "/tmp/ffmpeg", + "tarball_name": f"ffmpeg-{FFMPEG_81['version']}.tar.bz2", + }, + }, + ), + ( + "ffmpeg-8.0", + { + "link": "http://ffmpeg.org/", + "version": FFMPEG_80["version"], + "version_link": "http://ffmpeg.org/releases/", + "release_date": FFMPEG_80["release_date"], + "license_name": "GNU Lesser General Public License (LGPL) version 2.1", + "license_link": "https://ffmpeg.org/legal.html", + "build_info": { + "download_link": f"https://ffmpeg.org/releases/ffmpeg-{FFMPEG_80['version']}.tar.bz2", + "build_dir": "/tmp/ffmpeg", + "tarball_name": f"ffmpeg-{FFMPEG_80['version']}.tar.bz2", + }, + }, + ), + ] +) +# come back to this problem, I think yaml configuration might be better. +# with open('libraries.json', 'r') as f: +# data = json.load(f) # todo this should be yaml config +# order_list = data['build_order'] +# LIBRARIES = OrderedDict((key, data['libraries'][key]) for key in order_list) + + +def generate_library_table(filename): + """ + Generates a formatted table of FFmpeg libraries. + cut-n-paste this into the main projects README.md file. + """ + # open the filename for writing, overwrite if it exists + with open(filename, "w") as f: + f.write("## FFMPEG Supported Libraries\n") + f.write( + "The following libraries are used by FFMPEG. The version number and release date are provided along with the license information.\n" + ) + f.write( + "These version numbers are for the lib source builds, which are 'ubuntu2404-edge' and 'scratch320'.\n" + ) + f.write( + "These libs are included in the package images as well, but the version numbers might vary slightly.\n\n" + ) + + f.write( + "| Libraries | Version | Release Date | Download Source | Checksum | License |\n" + ) + f.write( + "|-----------|---------|--------------|------------ | --- | ---------|\n" + ) + for k, v in LIBRARIES.items(): + libname = f"[{k}]({v['link']})" # link to the library + libversion = f"[{v['version']}]({v['version_link']})" # link to the version + license = ( + f"[{v['license_name']}]({v['license_link']})" # link to the license + ) + # if build_info and build_info.tarball_name and build_info.download_link is avaliabl then set the download_source + download_source = "" + if ( + v.get("build_info") + and v["build_info"].get("tarball_name") + and v["build_info"].get("download_link") + ): + download_source = f"[{v['build_info']['tarball_name']}]({v['build_info']['download_link']})" + checksum = v["build_info"].get("sha256sum", "") + has_checksum = "Yes" if checksum else "No" + + using_source_build = v["build_info"].get("using_source_build", True) + # if we are not using the source build then do not display it in the table. + if using_source_build: + f.write( + f"| {libname} | {libversion} | {v.get('release_date', '')} | {download_source} | {has_checksum} | {license} |\n" + ) + print(f"Library table generated: {filename}") + sys.stdout.flush() + + +def generate_versions_manifest(output_file, ffmpeg_libraries=[]): + """ + Generates a 'generated_build_versions_manifest.json' file containing library version information. + + Args: + ffmpeg_libraries (dict): A dictionary containing FFmpeg library information. + output_file (str, optional): The filename for the build manifest. Defaults to "generated_build_versions_manifest.json". + """ + + manifest_data = {} + if not ffmpeg_libraries: + ffmpeg_libraries = LIBRARIES.keys() + for library_name in ffmpeg_libraries: + library_info = LIBRARIES.get(library_name, {}) + manifest_data[library_name] = library_info.get("version", "") + + with open(output_file, "w") as f: + json.dump(manifest_data, f, indent=4) + print(f"Versions manifest generated: {output_file}") + sys.stdout.flush() + + +def generate_build_manifest(output_file, ffmpeg_libraries=[]): + """ + Generates a 'generated_build_manifest.json' file containing library download information. + + Args: + ffmpeg_libraries (dict): A dictionary containing FFmpeg library information. + output_file (str, optional): The filename for the build manifest. Defaults to "generated_build_manifest.json". + """ + + manifest_data = [] + if not ffmpeg_libraries: + ffmpeg_libraries = LIBRARIES.keys() + for library_name in ffmpeg_libraries: + library_info = LIBRARIES.get(library_name, {}) + build_info = library_info.get("build_info", {}) + download_url = build_info.get("download_link", "") + build_dir = build_info.get("build_dir", "") + tarball_name = build_info.get("tarball_name", "") + sha256sum = build_info.get("sha256sum", "") + + if not all([build_dir]): + print( + f"Warning: Missing 'build_dir' information for {library_name} in build manifest generation." + ) + continue + + data = { + "library_name": library_name, + "build_dir": build_dir, + } + if download_url and tarball_name: + data["download_url"] = download_url + data["tarball_name"] = tarball_name + + if sha256sum: + data["sha256sum"] = sha256sum + manifest_data.append(data) + + with open(output_file, "w") as f: + json.dump(manifest_data, f, indent=4) + print(f"Build manifest generated: {output_file}") + sys.stdout.flush() + + +def list_of_strings(arg): + return arg.split(",") + + +def main(): + """ + Handles three modes: + 1. Generate both generated files (default) + 2. Generate library table + 3. Generate build manifest + """ + + parser = argparse.ArgumentParser(description="FFmpeg Library Information Script") + parser.add_argument("--library-list", type=list_of_strings, default=[]) + args = parser.parse_args() + + default_versions_table = "generated_versions_table.md" + default_generated_json_file = "generated_build_manifest.json" + default_generated_versions_json = "generated_build_versions_manifest.json" + + generate_library_table(default_versions_table) + generate_build_manifest(default_generated_json_file, args.library_list) + generate_versions_manifest(default_generated_versions_json, args.library_list) + + +if __name__ == "__main__": + main() diff --git a/docker-images/8.0/amf2404/install_ffmpeg.sh b/docker-images/8.0/amf2404/install_ffmpeg.sh new file mode 100755 index 00000000..7b4fb8b4 --- /dev/null +++ b/docker-images/8.0/amf2404/install_ffmpeg.sh @@ -0,0 +1,128 @@ +#!/bin/bash + +# Stop execution on any error +# Note: we can override this in the Dockerfile RUN command with an || true. +# which is useful for debugging +set -e +strip_libs=false + +# Parse command-line arguments +while [[ $# -gt 0 ]]; do + case "$1" in + --strip) + strip_libs=true + shift 1 + ;; + *) + echo "Unknown option: $1" + exit 1 + ;; + esac +done + +OS_NAME=$(uname -s) +is_ubuntu=false +is_alpine=false +if [[ "$OS_NAME" == "Linux" ]]; then + if grep -q "Ubuntu" /etc/os-release; then + is_ubuntu=true + elif [[ -f /etc/alpine-release ]]; then + is_alpine=true + fi +fi + +install_ffmpeg() { + echo "Installing ffmpeg" + ## cleanup + # This is used for both the source and packages version ( be robust about looking for libs to copy ) + if [ ! -f ${PREFIX}/bin/ffmpeg ]; then + echo "ERROR: ffmpeg not found in ${PREFIX}/bin" + exit 1 + fi + + ARCH=$(uname -m) + if [ "$ARCH" = "x86_64" ]; then + GNU_ARCH="x86_64-linux-gnu" + CUDA_ARCH="x86_64-linux" + elif [ "$ARCH" = "aarch64" ]; then + GNU_ARCH="aarch64-linux-gnu" + CUDA_ARCH="sbsa-linux" + else + GNU_ARCH="${ARCH}-linux-gnu" + CUDA_ARCH="${ARCH}-linux" + fi + + if ldd ${PREFIX}/bin/ffmpeg | grep ${GNU_ARCH} | cut -d ' ' -f 3 | grep -q . ; then + ldd ${PREFIX}/bin/ffmpeg | grep ${GNU_ARCH} | cut -d ' ' -f 3 | xargs -i cp -p {} /usr/local/lib/ + fi + if [[ -d /usr/local/cuda/targets/${CUDA_ARCH}/lib/ ]]; then + cp -p /usr/local/cuda/targets/${CUDA_ARCH}/lib/libnpp* /usr/local/lib + fi + + # Check if ffmpeg library is linked to opt/ffmpeg and copy it to /usr/local/lib + if ldd ${PREFIX}/bin/ffmpeg | grep opt/ffmpeg | cut -d ' ' -f 3 | grep -q . ; then + ldd ${PREFIX}/bin/ffmpeg | grep opt/ffmpeg | cut -d ' ' -f 3 | xargs -i cp -p {} /usr/local/lib/ + fi + + # Create symbolic links for shared libraries in /usr/local/lib + for lib in /usr/local/lib/*.so.*; do + ln -sf "${lib##*/}" "${lib%%.so.*}".so + done + + # Copy ffmpeg binaries and share directory to /usr/local + cp -r ${PREFIX}/bin/* /usr/local/bin/ + cp -r ${PREFIX}/share/ffmpeg /usr/local/share/ + + if [ ! -d /usr/local/include ]; then + mkdir -p /usr/local/include + fi + + # Build configuration and copy include directories + LD_LIBRARY_PATH=/usr/local/lib ffmpeg -buildconf + for lib in ${PREFIX}/include/libav* ${PREFIX}/include/libpostproc ${PREFIX}/include/libsw*; do + if [[ -d "$lib" ]]; then + cp -rp "$lib" /usr/local/include/ + else + echo "Warning: Directory '$lib' not found." + fi + done + + # Create pkgconfig directory and copy and modify pkgconfig files + mkdir -p /usr/local/lib/pkgconfig + for pc in ${PREFIX}/lib/pkgconfig/libav*.pc ${PREFIX}/lib/pkgconfig/libpostproc.pc ${PREFIX}/lib/pkgconfig/kvazaar.pc ${PREFIX}/lib/pkgconfig/libsw*.pc ${PREFIX}/lib/${GNU_ARCH}/pkgconfig/libvmaf*; do + if [[ -f "$pc" ]]; then + sed "s:${PREFIX}:/usr/local:g; s:/lib64:/lib:g" <"$pc" >/usr/local/lib/pkgconfig/"${pc##*/}"; \ + else + echo "Warning: File '$pc' not found." + fi + done +} + +fakeroot_install_with_striped_libs() { + echo "Installing ffmpeg with fakeroot and striped libs" + mkdir -p /tmp/fakeroot/lib + ldd ${PREFIX}/bin/ffmpeg | cut -d ' ' -f 3 | strings | xargs -I R cp R /tmp/fakeroot/lib/ + for lib in /tmp/fakeroot/lib/*; do strip --strip-all $lib; done + cp -r ${PREFIX}/bin /tmp/fakeroot/bin/ + cp -r ${PREFIX}/share/ffmpeg /tmp/fakeroot/share/ + LD_LIBRARY_PATH=/tmp/fakeroot/lib /tmp/fakeroot/bin/ffmpeg -buildconf +} + +fakeroot_install() { + echo "Using fakeroot to install ffmpeg" + mkdir -p /tmp/fakeroot/lib + ldd ${PREFIX}/bin/ffmpeg | cut -d ' ' -f 3 | strings | xargs -I R cp R /tmp/fakeroot/lib/ + cp -r ${PREFIX}/bin /tmp/fakeroot/bin/ + cp -r ${PREFIX}/share/ffmpeg /tmp/fakeroot/share/ + LD_LIBRARY_PATH=/tmp/fakeroot/lib /tmp/fakeroot/bin/ffmpeg -buildconf +} + +# if strip_libs is true then call the install_with_striped_libs function +# else if is_alpine is true then call the fakeroot_install function +if $strip_libs; then + fakeroot_install_with_striped_libs +elif $is_alpine; then + fakeroot_install +else + install_ffmpeg +fi diff --git a/docker-images/8.1/amf2404/Dockerfile b/docker-images/8.1/amf2404/Dockerfile new file mode 100644 index 00000000..08ed0d42 --- /dev/null +++ b/docker-images/8.1/amf2404/Dockerfile @@ -0,0 +1,212 @@ +# ffmpeg - http://ffmpeg.org/download.html +# +# From https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu +# +# https://hub.docker.com/r/jrottenberg/ffmpeg/ +# +# +# Stage 1: Build +FROM ubuntu:24.04 AS builder + + +ENV FFMPEG_VERSION=8.1.1 + +ENV AMD_AMF_VERSION=v1.5.2 + +## opencore-amr - https://sourceforge.net/projects/opencore-amr/ +## x264 - http://www.videolan.org/developers/x264.html +## x265 - http://x265.org/ ( videolan ) +## libogg - https://www.xiph.org/ogg/ ( xiph ) +## libopus - https://www.opus-codec.org/ ( xiph ) +## - https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libopus +## libvorbis - https://xiph.org/vorbis/ ( xiph ) +## libvpx - https://www.webmproject.org/code/ +## - https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libvpx +## libwebp - https://developers.google.com/speed/webp/ +## libmp3lame - http://lame.sourceforge.net/ +## xvid - https://www.xvid.com/ (xvidcore) +## fdk-aac - https://github.com/mstorsjo/fdk-aac +## - https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libfdk-aac +## openjpeg - https://github.com/uclouvain/openjpeg +## freetype - https://www.freetype.org/ +## consider passing --no-install-recommends for this one its globbie (if you do, pass in libfreetype6) +## libvidstab - https://github.com/georgmartius/vid.stab +## fridibi - https://www.fribidi.org/ +## fontconfig - https://www.freedesktop.org/wiki/Software/fontconfig/ +## libass - https://github.com/libass/libass +## lib aom - https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libaom +## libsvtav1 - https://gitlab.com/AOMediaCodec/SVT-AV1.git +## - https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libsvtav1 +## libdav1d - https://code.videolan.org/videolan/dav1d +## - https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libdav1d +## util-macros - (x.org) (and supporting libraries) for screen capture https://xcb.freedesktop.org/ +## xorgproto - (x.org) +## libXau - +## libpthread - libpthread-stubs +## libxml2 - for libbluray +## libbluray - Requires libxml, freetype, and fontconfig +## libzmq - https://github.com/zeromq/libzmq/ +## this one pulls in a bunch of dependencies +## libpng - this one also pulls in a bunch of stuff +## libaribb24 - +## zimg - https://github.com/sekrit-twc/zimg +## libtheora - http://www.theora.org/ ( xiph ) +## - https://stackoverflow.com/questions/4810996/how-to-resolve-configure-guessing-build-type-failure +## libsrt - https://github.com/Haivision/srt +## Secure Reliable Transport UDP streaming library +## multiple flavors (OpenSSL flavour) and ( GnuTLS flavour) +ARG OPENCORE_PKGS="libopencore-amrnb-dev libopencore-amrnb0 libopencore-amrwb-dev libopencore-amrwb0" +ARG X264_PKGS="libx264-164 libx264-dev" +ARG X265_PKGS="libnuma1 libx265-199 libx265-dev" +# libnuma-dev +ARG OGG_PKGS="libogg-dev libogg0" +ARG OPUS_PKGS="libopus-dev libopus0" +ARG VORBIS_PKGS="libvorbis-dev libvorbis0a libvorbisenc2 libvorbisfile3" +ARG VPX_PKGS="libvpx-dev libvpx9" +ARG WEBP_PKGS="libsharpyuv-dev libsharpyuv0 libwebp-dev libwebp7 libwebpdecoder3 libwebpdemux2 libwebpmux3" +ARG MP3LAME_PKGS="libmp3lame-dev libmp3lame0" +ARG XVIDCORE_PKGS="libxvidcore-dev libxvidcore4" +ARG FDKAAC_PKGS="libfdk-aac-dev libfdk-aac2" +ARG OPENJP_PKGS="libopenjp2-7 libopenjp2-7-dev" +# bzip2-doc fontconfig-config fonts-dejavu-core fonts-dejavu-mono libaom3 libbrotli-dev +# libbrotli1 libbsd0 libbz2-dev libc-dev-bin libc-devtools libc6-dev libcrypt-dev libde265-0 +# libdeflate0 libfontconfig1 libfreetype6 libgd3 libheif-plugin-aomdec +# libheif-plugin-aomenc libheif-plugin-libde265 libheif1 libjbig0 libjpeg-turbo8 +# libjpeg8 liblerc4 libpng-dev libpng-tools libpng16-16t64 libsharpyuv0 libtiff6 +# libwebp7 libx11-6 libx11-data libxau6 libxcb1 libxdmcp6 libxpm4 linux-libc-dev +# manpages manpages-dev rpcsvc-proto zlib1g-dev +ARG FREETYPE_PKGS="libfreetype6-dev" +ARG FONTCONFIG_PKGS="fontconfig libfontconfig-dev libfontconfig1 fontconfig-config fonts-dejavu-core fonts-dejavu-mono" +ARG VIDSTAB_PKGS="libvidstab-dev libvidstab1.1" +ARG FRIBIDI_PKGS="libfribidi-dev libfribidi0" +# libass-dev wanted to install a boat-load of packages +ARG LIBASS_PKGS="libass-dev libass9" +ARG AOM_PKGS="libaom-dev libaom3" +ARG SVTAV1_PKGS="libsvtav1-dev libsvtav1enc-dev libsvtav1enc1d1 libsvtav1dec-dev libsvtav1dec0" +ARG DAV1D_PKGS="libdav1d-dev libdav1d7" +# LIBDRM_PKGS picks ups some of the XORG_MACROS_PKGS as well +ARG XORG_MACROS_PKGS="libxcb-shm0-dev libxcb-shm0 libxcb-xfixes0 libxcb-xfixes0-dev" +ARG XPROTO_PKGS="x11proto-core-dev x11proto-dev" +ARG XAU_PKGS="libxau-dev libxau6" +ARG PTHREADS_STUBS_PKGS="libpthread-stubs0-dev" +ARG XML2_PKGS="libxml2-dev libxml2" +ARG BLURAY_PKGS="libbluray-dev libbluray2" +ARG ZMQ_PKGS="libzmq3-dev libzmq5" +# libpng-tools +ARG PNG_PKGS="libpng-dev libpng16-16t64" +ARG ARIBB24_PKGS="libaribb24-dev" +ARG ZIMG_PKGS="libzimg-dev libzimg2" +ARG THEORA_PKGS="libtheora-dev libtheora0" +ARG SRT_PKGS="libssl-dev libsrt-openssl-dev libsrt1.5-openssl" +ARG LIBDRM_PKGS="libbsd0 libdrm-dev libdrm2 libxcb1-dev libxcb1" + +ENV MAKEFLAGS="-j4" +ENV PKG_CONFIG_PATH="/opt/ffmpeg/share/pkgconfig:/opt/ffmpeg/lib/pkgconfig:/opt/ffmpeg/lib64/pkgconfig:/opt/ffmpeg/lib/x86_64-linux-gnu/pkgconfig:/opt/ffmpeg/lib/aarch64-linux-gnu/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig" + +ENV PREFIX="/opt/ffmpeg" +ENV LD_LIBRARY_PATH="/opt/ffmpeg/lib:/opt/ffmpeg/lib64:/opt/ffmpeg/lib/aarch64-linux-gnu" + + +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get -yqq update && \ + apt-get install -yq --no-install-recommends curl jq python3 python3-requests less tree file vim + +RUN buildDeps="autoconf \ + automake \ + cmake \ + build-essential \ + texinfo \ + curl \ + wget \ + tar \ + bzip2 \ + libexpat1-dev \ + gcc \ + git \ + git-core \ + gperf \ + libtool \ + make \ + meson \ + ninja-build \ + nasm \ + perl \ + pkg-config \ + python3 \ + yasm \ + zlib1g-dev \ + libfreetype6-dev \ + libgnutls28-dev \ + libsdl2-dev \ + libva-dev \ + libvdpau-dev \ + libnuma-dev \ + libdav1d-dev \ + openssl \ + libssl-dev \ + expat \ + libgomp1" && \ + apt-get -yqq update && \ + apt-get install -yq --no-install-recommends ${buildDeps} + +WORKDIR /tmp/workdir + +COPY generate-source-of-truth-ffmpeg-versions.py /tmp/workdir +COPY download_tarballs.sh /tmp/workdir +COPY build_source.sh /tmp/workdir +COPY install_ffmpeg.sh /tmp/workdir + + + +RUN \ + echo "Installing dependencies..." && \ + apt-get install -yq --no-install-recommends ${OPENCORE_PKGS} ${X264_PKGS} ${X265_PKGS} ${OGG_PKGS} ${OPUS_PKGS} ${VORBIS_PKGS} ${VPX_PKGS} ${WEBP_PKGS} ${MP3LAME_PKGS} ${XVIDCORE_PKGS} ${FDKAAC_PKGS} ${OPENJP_PKGS} ${FREETYPE_PKGS} ${VIDSTAB_PKGS} ${FRIBIDI_PKGS} ${FONTCONFIG_PKGS} ${LIBASS_PKGS} ${AOM_PKGS} ${SVTAV1_PKGS} ${DAV1D_PKGS} ${XORG_MACROS_PKGS} ${XPROTO_PKGS} ${XAU_PKGS} ${PTHREADS_STUBS_PKGS} ${XML2_PKGS} ${BLURAY_PKGS} ${ZMQ_PKGS} ${PNG_PKGS} ${ARIBB24_PKGS} ${ZIMG_PKGS} ${THEORA_PKGS} ${SRT_PKGS} ${LIBDRM_PKGS} + +RUN \ + git clone --branch ${AMD_AMF_VERSION} --depth 1 https://github.com/GPUOpen-LibrariesAndSDKs/AMF.git /tmp/amf && \ + mkdir -p /usr/local/include/AMF && \ + cp -a /tmp/amf/amf/public/include/. /usr/local/include/AMF/ && \ + rm -rf /tmp/amf + +# apt install libdrm-dev + +## libvmaf https://github.com/Netflix/vmaf +## https://github.com/Netflix/vmaf/issues/788#issuecomment-756098059 +RUN \ + echo "Adding g++ for VMAF build" && \ + apt-get install -yq g++ + +# Note: pass '--library-list lib1,lib2,lib3 for more control. +# Here we have 3 libs that we have to build from source +RUN /tmp/workdir/generate-source-of-truth-ffmpeg-versions.py --library-list kvazaar,libvmaf,whisper +RUN /tmp/workdir/download_tarballs.sh +RUN /tmp/workdir/build_source.sh + +RUN /tmp/workdir/generate-source-of-truth-ffmpeg-versions.py --library-list ffmpeg-8.1 +RUN /tmp/workdir/download_tarballs.sh +RUN /tmp/workdir/build_source.sh + +## when debugging you can pass in || true to the end of the command +## to keep the build going even if one of the steps fails +RUN /tmp/workdir/install_ffmpeg.sh + + + +# Stage 2: Final Image ( shrink the size back down ) +FROM ubuntu:24.04 AS runtime +# Copy fonts and fontconfig from builder +COPY --from=builder /usr/share/fonts /usr/share/fonts +COPY --from=builder /usr/share/fontconfig /usr/share/fontconfig +COPY --from=builder /usr/bin/fc-* /usr/bin/ + +# Copy rest of the content +COPY --from=builder /usr/local /usr/local/ + +LABEL org.opencontainers.image.authors="julien@rottenberg.info" \ + org.opencontainers.image.source=https://github.com/jrottenberg/ffmpeg + +ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64 + +CMD ["--help"] +ENTRYPOINT ["ffmpeg"] diff --git a/docker-images/8.1/amf2404/build_source.sh b/docker-images/8.1/amf2404/build_source.sh new file mode 100755 index 00000000..19d96ef5 --- /dev/null +++ b/docker-images/8.1/amf2404/build_source.sh @@ -0,0 +1,464 @@ +#!/usr/bin/env bash + +# Stop execution on any error +# Note: we can override this in the Dockerfile RUN command with an || true. +# which is useful for debugging +set -e + +manifestJsonFile="/tmp/workdir/generated_build_manifest.json" +manifestJsonVersionsFile="/tmp/workdir/generated_build_versions_manifest.json" + +OS_NAME=$(uname -s) +is_ubuntu=false +is_alpine=false +if [[ "$OS_NAME" == "Linux" ]]; then + if grep -q "Ubuntu" /etc/os-release; then + is_ubuntu=true + elif grep -q "Alpine Linux" /etc/alpine-release; then + is_alpine=true + fi +fi + +ARCH=$(uname -m) +is_x86=false +if [[ "$ARCH" == "x86_64" ]]; then + is_x86=true +fi +######################### Callback build functions ######################### +build_libopencore-amr() { + ./configure --prefix="${PREFIX}" --enable-shared + make + make install +} + +build_libx264() { + ./configure --prefix="${PREFIX}" --enable-shared --enable-pic --disable-cli + make + make install +} + +build_libx265() { + cd build/linux + sed -i "/-DEXTRA_LIB/ s/$/ -DCMAKE_INSTALL_PREFIX=\${PREFIX}/" multilib.sh + sed -i "/^cmake/ s/$/ -DENABLE_CLI=OFF/" multilib.sh + if [ "$is_x86" = false ]; then + sed -i "/^cmake/ s/$/ -DENABLE_ASSEMBLY=OFF/" multilib.sh + fi + ./multilib.sh + make -C 8bit install +} + +build_libogg() { + ./configure --prefix="${PREFIX}" --enable-shared + make + make install +} + +build_libopus() { + ./configure --prefix="${PREFIX}" --enable-shared + make + make install +} + +build_libvorbis() { + ./configure --prefix="${PREFIX}" --with-ogg="${PREFIX}" --enable-shared + make + make install + # https://gitlab.xiph.org/xiph/vorbis + # cmake -G YOUR-PROJECT-GENERATOR -DBUILD_SHARED_LIBS=1 -DCMAKE_INSTALL_PREFIX="${PREFIX}" . + # make + # make install +} + +build_libvpx() { + local data=$(jq -r '.[] | select(.library_name == "libvpx")' $manifestJsonFile) + local dir=$(echo "$data" | jq -r '.build_dir') + local vpx_version=$(jq -r '.["libvpx"]' $manifestJsonVersionsFile) + if [ -n "$vpx_version" ] && [[ "$vpx_version" != "null" ]]; then + echo "Building [libvpx-${vpx_version}] in [${dir}]" + else + echo "Error: libvpx version is empty or unset" + fi + version="v${vpx_version}" + git -C libvpx pull 2> /dev/null || git clone --branch ${version} --depth 1 https://chromium.googlesource.com/webm/libvpx.git + cd libvpx + pwd + local vpx_configure_flags="--prefix=${PREFIX} --disable-examples --disable-unit-tests --enable-vp9-highbitdepth --enable-pic --enable-shared" + if [ "$is_x86" = true ]; then + vpx_configure_flags="${vpx_configure_flags} --as=yasm" + fi + ./configure ${vpx_configure_flags} + make + make install +} + +build_libwebp() { + ./configure --prefix="${PREFIX}" --enable-shared && \ + make && \ + make install +} + +build_libmp3lame() { + local nasm_flag="--enable-nasm" + if [ "$is_x86" = false ]; then + nasm_flag="--disable-nasm" + fi + ./configure --prefix="${PREFIX}" --bindir="${PREFIX}/bin" --enable-shared ${nasm_flag} --disable-frontend && \ + make && \ + make install +} + + +build_libxvid() { + # read doc/INSTALL + cd build/generic + ./configure --help + echo "Now guess" + ./configure --prefix="${PREFIX}" --bindir="${PREFIX}/bin --enable-shared" + make + make install +} + +build_libfdk-aac() { + autoreconf -fiv && \ + ./configure --prefix="${PREFIX}" --enable-shared + make + make install +} + +build_openjpeg() { + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="${PREFIX}" . && \ + make && \ + make install +} + +build_freetype() { + ./configure --prefix="${PREFIX}" --disable-static --enable-shared && \ + make && \ + make install +} + +build_libvidstab() { + cmake -DCMAKE_INSTALL_PREFIX="${PREFIX}" . && \ + make && \ + make install +} + +build_fribidi() { + # Currently broken, need to fix + # sed -i 's/^SUBDIRS =.*/SUBDIRS=gen.tab charset lib bin/' Makefile.am + # ./bootstrap --no-config --auto + ./configure --prefix="${PREFIX}" --disable-static --enable-shared + make -j1 + make install +} + +build_fontconfig() { + meson setup build --prefix="${PREFIX}" --default-library=shared && \ + ninja -C build && \ + ninja -C build install +} + +build_libass() { + ./autogen.sh && \ + ./configure --prefix="${PREFIX}" --disable-static --enable-shared && \ + make && \ + make install +} + +build_kvazaar() { + # ./autogen.sh && \ + ./configure --prefix="${PREFIX}" --disable-static --enable-shared && \ + make && \ + make install +} + +# aom is a git clone ( to get source, so not in the loop using the callback function) +build_aom() { + local data=$(jq -r '.[] | select(.library_name == "aom")' $manifestJsonFile) + local dir=$(echo "$data" | jq -r '.build_dir') + local aom_version=$(jq -r '.["aom"]' $manifestJsonVersionsFile) # Access value with key "aom" + if [ -n "$aom_version" ] && [[ "$aom_version" != "null" ]]; then + echo "Building [aom-${aom_version}] in [${dir}]" + else + echo "Error: aom version is empty or unset" + fi + version="v${aom_version}" + git clone --branch ${version} --depth 1 https://aomedia.googlesource.com/aom ${dir} && \ + cd ${dir} && \ + mkdir -p ./aom_build && \ + cd ./aom_build && \ + local nasm_flag="-DENABLE_NASM=on" + if [ "$is_x86" = false ]; then + nasm_flag="-DENABLE_NASM=off" + fi + cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="${PREFIX}" -DBUILD_SHARED_LIBS=1 ${nasm_flag} .. && \ + make && \ + make install +} + +build_nvidia-codec-headers() { + local dir=${1} + # git clone https://github.com/FFmpeg/nv-codec-headers ${dir} + # git checkout n${NVIDIA_HEADERS_VERSION} + make PREFIX="${PREFIX}" + make install PREFIX="${PREFIX}" +} + +build_libsvtav1() { + cd Build && \ + cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="${PREFIX}" -DCMAKE_BUILD_TYPE=Release -DBUILD_DEC=OFF -DBUILD_SHARED_LIBS=OFF .. \ + make && \ + make install +} + +build_xorg-macros() { + dir=${1} + ./configure --srcdir=${dir} --prefix="${PREFIX}" && \ + make && \ + make install +} + +build_xorgproto() { + meson setup build --prefix="${PREFIX}" && \ + ninja -C build && \ + ninja -C build install +} + +build_libxau() { + dir=${1} + ./configure --srcdir=${dir} --prefix="${PREFIX}" && \ + make && \ + make install +} + +build_libpthread-stubs() { + ./configure --prefix="${PREFIX}" && \ + make && \ + make install +} + +build_libxml2() { + ./autogen.sh --prefix="${PREFIX}" --with-ftp=no --with-http=no --with-python=no && \ + make && \ + make install +} + +build_libbluray() { + ## libbluray - Requires libxml, freetype, and fontconfig + ./configure --prefix="${PREFIX}" --disable-examples --disable-bdjava-jar --disable-static --enable-shared && \ + make && \ + make install +} + +build_libzmq() { + ./autogen.sh && \ + ./configure --prefix="${PREFIX}" && \ + make && \ + make install +} + +# another special, code clone situation ( actually currently using the tarball build approach ) +build_libpng() { + local dir = "/tmp/png" + # local libpng_version=$(jq -r '.["libpng"]' $manifestJsonVersionsFile) # Access value with key "libpng" + # git clone https://git.code.sf.net/p/libpng/code ${dir} -b v${libpng_version} --depth 1 && \ + ./autogen.sh && \ + ./configure --prefix="${PREFIX}" && \ + make check && \ + make install +} + +build_libaribb24() { + autoreconf -fiv && \ + ./configure CFLAGS="-I${PREFIX}/include -fPIC" --prefix="${PREFIX}" && \ + make && \ + make install +} + +build_zimg() { + ./autogen.sh && \ + ./configure --prefix="${PREFIX}" --enable-shared && \ + make && \ + make install +} + +# Dependancy on libogg +build_libtheora() { + ./configure --prefix="${PREFIX}" --with-ogg="${PREFIX}" --enable-shared --disable-examples + make + make install +} + +build_libsrt() { + # requires libssl-dev + cmake -DCMAKE_INSTALL_PREFIX="${PREFIX}" . && \ + make && \ + make install +} + +build_libvmaf() { + # https://github.com/Netflix/vmaf/issues/788#issuecomment-756098059 + mkdir ./libvmaf/build + cd ./libvmaf/build + meson setup -Denable_tests=false -Denable_docs=false --buildtype=release --default-library=static --prefix "${PREFIX}" .. && \ + # meson setup -Denable_tests=false -Denable_docs=false --buildtype=release --default-library=shared --prefix "${PREFIX}" .. + ninja + ninja install +} + +build_whisper() { + cmake -B build -S . \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=${PREFIX} \ + -DGGML_STATIC=OFF + + cmake --build build -j$(nproc) + + mkdir -p ${PREFIX}/include ${PREFIX}/lib ${PREFIX}/lib/pkgconfig + cp -av include/whisper.h ggml/include/ggml*.h ${PREFIX}/include/ + find ./build -name "*.so*" -exec cp -av {} ${PREFIX}/lib/ \; + cp ./build/whisper.pc ${PREFIX}/lib/pkgconfig/ +} + + + + +build_ffmpeg() { + # Here is a list of things that we enable in the ffmpeg build: that are not in the + # track configuration guide: https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#FFmpeg + # --enable-fontconfig + # --enable-libaribb24 + # --enable-libbluray + # --enable-libkvazaar + # --enable-libopencore-amrnb + # --enable-libopencore-amrwb + # --enable-libopenjpeg + # --enable-libsrt + # --enable-libtheora + # --enable-libvmaf + # --enable-libwebp + # --enable-libxvid + # --enable-libzimg + # --enable-libzmq + # --enable-openssl + # --enable-postproc + # --enable-small + # --enable-version3 + + ./configure --disable-debug \ + --disable-doc \ + --disable-ffplay \ + --enable-amf \ + --enable-fontconfig \ + --enable-gpl \ + --enable-libaom \ + --enable-libaribb24 \ + --enable-libass \ + --enable-libbluray \ + --enable-libdav1d \ + --enable-libfdk-aac \ + --enable-libfontconfig \ + --enable-libfreetype \ + --enable-libfribidi \ + --enable-libharfbuzz \ + --enable-libkvazaar \ + --enable-libmp3lame \ + --enable-libopencore-amrnb \ + --enable-libopencore-amrwb \ + --enable-libopenjpeg \ + --enable-libopus \ + --enable-libsrt \ + --enable-libsvtav1 \ + --enable-libtheora \ + --enable-libvidstab \ + --enable-libvmaf \ + --enable-libvorbis \ + --enable-libvpx \ + --enable-libwebp \ + --enable-libx264 \ + --enable-libx265 \ + --enable-libxvid \ + --enable-libzimg \ + --enable-libzmq \ + --enable-nonfree \ + --enable-openssl \ + --enable-shared \ + --enable-small \ + --enable-version3 \ + --enable-whisper \ + --extra-cflags="-I${PREFIX}/include -I/usr/local/include -I/usr/include/x86_64-linux-gnu -I/usr/include/aarch64-linux-gnu" \ + --extra-ldflags="-L${PREFIX}/lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/aarch64-linux-gnu -L/usr/lib" \ + --extra-ldflags=-L/opt/ffmpeg/lib/aarch64-linux-gnu \ + --extra-ldflags=-L/opt/ffmpeg/lib/x86_64-linux-gnu \ + --extra-libs=-ldl \ + --extra-libs=-lm \ + --extra-libs=-lpthread \ + --ld=g++ \ + --prefix="${PREFIX}" && \ + make && \ + make install && \ + make tools/zmqsend && cp -av tools/zmqsend ${PREFIX}/bin/ && \ + make distclean && \ + hash -r && \ + cd tools && \ + make qt-faststart && cp qt-faststart ${PREFIX}/bin/ +} +######################### Helper functions ######################### +extract_tarball() { + local tarball_name=$1 + # grab the extension of the tarball + local extension="${tarball_name##*.}" + # tar extraction args: -z, -j, -J, --lzma Compress archive with gzip/bzip2/xz/lzma + if [ "$extension" == "gz" ]; then + tar -zx --strip-components=1 -f ${tarball_name} + elif [ "$extension" == "bz2" ]; then + tar -jx --strip-components=1 -f ${tarball_name} + elif [ "$extension" == "xz" ]; then + tar -Jx --strip-components=1 -f ${tarball_name} + else + echo "Error while extract_tarball, got an unknown extension: $extension" + fi +} + +build_support_libraries() { + local librariesRaw="$(jq -r '.[] | .library_name' $manifestJsonFile)" + local libs=( $librariesRaw ) + for i in "${!libs[@]}"; do + lib_name=${libs[$i]} + # handle the clone source case's ( there are only two ) + # if [ "$lib_name" == "libsvtav1" ]; then + # echo "-------------------- Running callback: build_aom --------------------" + # echo "Building 'aom' before we build $lib_name" + # build_aom + # fi + # ffmpeg is in the lib_name string then the callback name is build_ffmpeg + callback_lib_name=${lib_name} + if [[ "$lib_name" == *"ffmpeg"* ]]; then + # take out the version numbers + callback_lib_name="ffmpeg" + fi + + local data=$(jq -r '.[] | select(.library_name == "'${lib_name}'")' $manifestJsonFile) + build_dir=$(echo "$data" | jq -r '.build_dir') + tarball_name=$(echo "$data" | jq -r '.tarball_name') + sha256sum=$(echo "$data" | jq -r '.sha256sum') + + echo "Building $lib_name: from ${build_dir}/$tarball_name" + cd $build_dir + extract_tarball $tarball_name + if [ -n "$sha256sum" ] && [[ "$sha256sum" != "null" ]]; then + echo "Checking sha256sum for $tarball_name" + echo $sha256sum | sha256sum --check + fi + # make a callback function to build the library + # if anything fails, we will exit with a non-zero status + echo "-------------------- Running callback: build_${lib_name} --------------------" + build_${callback_lib_name} ${build_dir} + echo "Finished building $lib_name removing build directory [${build_dir}]" + cd /tmp/workdir + rm -rf $build_dir + done +} + +build_support_libraries diff --git a/docker-images/8.1/amf2404/download_tarballs.sh b/docker-images/8.1/amf2404/download_tarballs.sh new file mode 100755 index 00000000..2fcf49aa --- /dev/null +++ b/docker-images/8.1/amf2404/download_tarballs.sh @@ -0,0 +1,143 @@ +#!/usr/bin/env bash + +# The point of this script is to read in the list of tarballs to download from generated_build_manifest.json +# using jq and then download them into their build directories. +# +# The point, we need robust re-tries, as sometimes the download fails, and we need to be able to re-try. +# and verify that the download was successful. + +manifestJsonFile="/tmp/workdir/generated_build_manifest.json" + +report_on_failed_downloads() { + local librariesRaw="$(jq -r '.[] | .library_name' $manifestJsonFile)" + local libs=( $librariesRaw ) + local count=0 + + for i in "${!libs[@]}"; do + lib_name=${libs[$i]} + local data=$(jq -r '.[] | select(.library_name == "'${lib_name}'")' $manifestJsonFile) + build_dir=$(echo "$data" | jq -r '.build_dir') + tarball_name=$(echo "$data" | jq -r '.tarball_name') + # if tarball_name does not exist, then it could be a source repo build + # just check the directory + if [ -z "$tarball_name" ]; then + if [ ! -d "$build_dir" ]; then + echo "Error: $build_dir does not exist" + ((count++)) + fi + fi + if [ ! -f "$build_dir/$tarball_name" ]; then + echo "Error: $build_dir/$tarball_name does not exist" + ((count++)) + fi + done + echo "Failed to download $count tarballs" +} + +actual_number_of_downloads_completed() { + local librariesRaw="$(jq -r '.[] | .library_name' $manifestJsonFile)" + local libs=( $librariesRaw ) + local count=0 + + for i in "${!libs[@]}"; do + lib_name=${libs[$i]} + local data=$(jq -r '.[] | select(.library_name == "'${lib_name}'")' $manifestJsonFile) + build_dir=$(echo "$data" | jq -r '.build_dir') + tarball_name=$(echo "$data" | jq -r '.tarball_name') + # if tarball_name does not exist, then it could be a source repo build + # just check the directory + if [[ -z "$tarball_name" || "$tarball_name" == "null" ]]; then + if [ -d "$build_dir" ]; then + ((count++)) + fi + fi + if [ -f "$build_dir/$tarball_name" ]; then + ((count++)) + fi + done + echo $count # Return the count as output +} +number_of_tarballs_to_download() { + local librariesRaw="$(jq -r '.[] | .library_name' $manifestJsonFile)" + local libs=( $librariesRaw ) + echo "${#libs[@]}" # return count as output +} + +download_tarballs() { + # the default argument of quiet is false + quiet=${1:-false} + local librariesRaw="$(jq -r '.[] | .library_name' $manifestJsonFile)" + local libs=( $librariesRaw ) + echo "Downloading (${#libs[@]} libraries)..." + for i in "${!libs[@]}"; do + # echo "Downloading ${libs[$i]}..." + lib_name=${libs[$i]} + # use double quotes around '${lib_name}', so Bash will expand the value. + build_dir=$(jq -r '.[] | select(.library_name == "'${lib_name}'") | .build_dir' $manifestJsonFile) + download_url=$(jq -r '.[] | select(.library_name == "'${lib_name}'") | .download_url' $manifestJsonFile) + tarball_name=$(jq -r '.[] | select(.library_name == "'${lib_name}'") | .tarball_name' $manifestJsonFile) + if [ -z "$build_dir" ]; then + echo "Error: build_dir, is empty" + exit 1 + fi + + # does the directory exist? if not make it + if [ ! -d "$build_dir" ]; then + mkdir -p "$build_dir" + fi + # handle edge case for source repo builds (git clone ) + if [[ -z "$tarball_name" || -z "$download_url" || "$tarball_name" == "null" || "$download_url" == "null" ]]; then + echo "Warning: tarball_name, or download_url is empty or unset (ok in a source repo build)" + continue + fi + echo "Downloading: ${download_url} to: ${build_dir} ${tarball_name}" + if [ -z "$build_dir" ] || [ -z "$download_url" ] || [ -z "$tarball_name" ]; then + echo "Error: build_dir, download_url, or tarball_name is empty" + exit 1 + fi + # if the tarball_file does not exhist then download it + if [ ! -f "$build_dir/$tarball_name" ]; then + echo "$build_dir/$tarball_name does not exist, downloading now..." + cd "$build_dir" + local http_code + http_code=$(curl -sL --retry 2 -o "$tarball_name" -w "%{http_code}" "$download_url") + if [ "$http_code" = "418" ]; then + echo "Got HTTP 418 (anti-bot) for ${download_url}, waiting 60s before retry..." + rm -f "$tarball_name" + sleep 60 + curl -fsSL --retry 2 -o "$tarball_name" "$download_url" + elif [ "$http_code" -ge 400 ] 2>/dev/null; then + echo "curl: HTTP $http_code for ${download_url}" + rm -f "$tarball_name" + fi + else + # if not quietly, then echo that we are skipping the download + [ "$quiet" = false ] && + echo "$build_dir/$tarball_name already exists, skipping download" + fi + done +} + +num_to_download=1 # at least 1 +num_completed=0 +number_of_times_to_retry=6 +download_tarballs_called_number=0 +num_completed=$(actual_number_of_downloads_completed) +num_to_download=$(number_of_tarballs_to_download) +echo "Starting to download ${num_to_download} tarball images" +while [ $num_completed -lt $num_to_download ] && [ $number_of_times_to_retry -gt $download_tarballs_called_number ]; do + ((download_tarballs_called_number++)) + download_tarballs + sleep 5 + num_completed=$(actual_number_of_downloads_completed) + num_to_download=$(number_of_tarballs_to_download) + echo "Downloaded ${num_completed} of ${num_to_download} tarball images on pass ${download_tarballs_called_number}" +done + +if [ $num_completed -lt $num_to_download ]; then + echo "Failed to download all tarballs after $download_tarballs_called_number attempts" + report_on_failed_downloads + exit 1 +fi +echo "Successfully Downloaded the ${num_completed} tarball images after $download_tarballs_called_number attempts" +exit 0 diff --git a/docker-images/8.1/amf2404/generate-source-of-truth-ffmpeg-versions.py b/docker-images/8.1/amf2404/generate-source-of-truth-ffmpeg-versions.py new file mode 100755 index 00000000..4a4e6eda --- /dev/null +++ b/docker-images/8.1/amf2404/generate-source-of-truth-ffmpeg-versions.py @@ -0,0 +1,845 @@ +#!/usr/bin/env python3 + +import argparse +import json +import sys +from collections import OrderedDict + +""" +------- Purpose ------- +...This is the source of truth... +1. This script generates a table of the libraries used by FFMPEG that + will be included in the main README.md file of the repository. +2. This script generates a 'build_manifest.json' file that contains the + the download links, build directories, and build tarball names for + each library. ( Required to generate a robust re-try download of the package tarballs) + +------- Setup ------- +This script is run in the container to generate 'build_manifest.json' +However, it is also used to generate a generated_versions_table.md file. +The steps for doing that are below. +To run this script you need the ?? library. You can install it with pip: +in a venv as follows: + +$ python3 -mvenv .venv +$ source .venv/bin/activate +$ pip install ?? +$ python3 ./generate-source-of-truth-ffmpeg-versions.py +$ deactivate +$ rm -rf .venv + +The output of this script will be a table in markdown format, which you can +paste into the README.md file of the repository. +""" + +# Library versions Source of truth +AOM = {"version": "3.10.0", "release_date": "2024-08-01"} +FDKAAC = {"version": "2.0.3", "release_date": "2023-12-21"} +FFMPEG_80 = {"version": "8.0", "release_date": "2025-08-22"} +FFMPEG_81 = {"version": "8.1", "release_date": "2025-11-28"} +FONTCONFIG = {"version": "2.15.0", "release_date": "2023-12-22"} +FREETYPE = {"version": "2.13.3", "release_date": "2024-08-12"} +KVAAZAAR = {"version": "2.3.1", "release_date": "2024-04-10"} +LAME = {"version": "3.100", "release_date": "2017-10-13"} +LIBARIBB24 = {"version": "1.0.3", "release_date": "2014-08-18"} +LIBASS = {"version": "0.17.3", "release_date": "2024-07-02"} +LIBBLURAY = {"version": "1.3.4", "release_date": "2022-11-26"} +LIBFRIDIBI = {"version": "1.0.16", "release_date": "2024-10-1"} +LIBPNG = {"version": "1.6.44", "release_date": "2024-09-12"} +LIBSRT = {"version": "1.5.3", "release_date": "2023-09-07"} +LIBVIDSTAB = {"version": "1.1.1", "release_date": "2022-05-30"} +LIBVMAF = {"version": "3.0.0", "release_date": "2023-12-07"} +LIBXML2 = {"version": "2.13.4", "release_date": "2024-09-01"} +LIBZMQ = {"version": "4.3.5", "release_date": "2023-10-9"} +NV_CODEC = {"version": "12.2.72.0", "release_date": "2024-03-31"} +OGG = {"version": "1.3.5", "release_date": "2021-06-04"} +OPENCOREAMR = {"version": "0.1.6", "release_date": "2022-08-01"} +OPENJPEG = {"version": "2.5.2", "release_date": "2024-02-28"} +OPUS = {"version": "1.5.2", "release_date": "2024-04-12"} +PTHREAD_STUBS = {"version": "0.5", "release_date": "2023-07-18"} +SVTAV1 = {"version": "2.2.1", "release_date": "2024-08-01"} +THEORA = {"version": "1.2.0", "release_date": "2025-03-29"} +VORBIS = {"version": "1.3.7", "release_date": "2020-07-04"} +VPX = {"version": "1.14.1", "release_date": "2024-05-30"} +WEBP = {"version": "1.4.0", "release_date": "2024-04-13"} +WHISPER = {"version": "1.7.6", "release_date": "2025-06-25"} +X264 = {"version": "20191217-2245-stable", "release_date": "2019-12-17"} +X265 = {"version": "4.0", "release_date": "2024-09-13"} +XAU = {"version": "1.0.11", "release_date": "2022-12-08"} +XORG_MACROS = {"version": "1.20.1", "release_date": "2024-04-16"} +XORGPROTO = {"version": "2024.1", "release_date": "2024-04-12"} +XVID = {"version": "1.3.7", "release_date": "2019"} +ZIMG = {"version": "3.0.5", "release_date": "2023-6-30"} + +# Library details, Source of truth +# TODO: store this in a yaml configuration file ( would probably be better ) +# flake8: noqa E501 +LIBRARIES = OrderedDict( + [ + ( + "whisper", + { + "link": "https://github.com/ggml-org/whisper.cpp", + "version": WHISPER["version"], + "version_link": "https://github.com/ggml-org/whisper.cpp/releases", + "release_date": WHISPER["release_date"], + "license_name": "MIT License", + "license_link": "https://github.com/ggml-org/whisper.cpp/blob/master/LICENSE", + "build_info": { + "download_link": f"https://github.com/ggml-org/whisper.cpp/archive/refs/tags/v{WHISPER['version']}.tar.gz", + "build_dir": "/tmp/whisper", + "tarball_name": f"whisper-v{WHISPER['version']}.tar.gz", + }, + }, + ), + ( + "libopencore-amr", + { + "link": "https://sourceforge.net/projects/opencore-amr/", + "version": OPENCOREAMR["version"], + "version_link": "https://sourceforge.net/projects/opencore-amr/files/opencore-amr/", + "release_date": OPENCOREAMR["release_date"], + "license_name": "Apache License", + "license_link": "https://sourceforge.net/p/opencore-amr/code/ci/master/tree/LICENSE", + "build_info": { + # this one of the finikie download link's ( and the reason we wrote the download_tarball.sh script) + "download_link": f"https://sourceforge.net/projects/opencore-amr/files/opencore-amr/opencore-amr-{OPENCOREAMR['version']}.tar.gz", + "build_dir": "/tmp/libopencore-amr", + "tarball_name": f"opencore-amr-{OPENCOREAMR['version']}.tar.gz", + }, + }, + ), + ( + "libx264", + { + "link": "https://www.videolan.org/developers/x264.html", + "version": X264["version"], + "version_link": "https://download.videolan.org/pub/videolan/x264/snapshots/", + "release_date": X264["release_date"], + "license_name": "GNU General Public License (GPL) version 2", + "license_link": "https://www.gnu.org/licenses/old-licenses/gpl-2.0.html", + "build_info": { + "download_link": f"https://download.videolan.org/pub/videolan/x264/snapshots/x264-snapshot-{X264['version']}.tar.bz2", + "build_dir": "/tmp/x264", + "tarball_name": f"x264-snapshot-{X264['version']}.tar.bz2", + }, + }, + ), + ( + "libx265", + { + "link": "http://x265.org/", + "version": X265["version"], + # "https://www.x265.org/downloads/", + "version_link": "http://ftp.videolan.org/pub/videolan/x265/", + "release_date": X265["release_date"], + "license_name": "GNU General Public License (GPL) version 2", + "license_link": "https://bitbucket.org/multicoreware/x265/raw/f8ae7afc1f61ed0db3b2f23f5d581706fe6ed677/COPYING", + "build_info": { + "download_link": f"http://ftp.videolan.org/pub/videolan/x265/x265_{X265['version']}.tar.gz", + "build_dir": "/tmp/x265", + "tarball_name": f"x265_{X265['version']}.tar.gz", + }, + }, + ), + ( + "libogg", + { + "link": "https://www.xiph.org/ogg/", + "version": OGG["version"], + "version_link": "https://xiph.org/downloads/", + "release_date": OGG["release_date"], + "license_name": "BSD-style license", + # TODO: check this link + "license_link": "https://git.xiph.org/?p=mirrors/ogg.git;a=blob_plain;f=COPYING;hb=HEAD", + "build_info": { + "download_link": f"https://downloads.xiph.org/releases/ogg/libogg-{OGG['version']}.tar.gz", + "build_dir": "/tmp/libogg", + "tarball_name": f"libogg-{OGG['version']}.tar.gz", + }, + }, + ), + ( + "libopus", + { + "link": "https://www.opus-codec.org/", + # https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libopus + "version": OPUS["version"], + "version_link": "https://www.opus-codec.org/downloads/", + # https://ftp.osuosl.org/pub/xiph/releases/opus/ + "release_date": OPUS["release_date"], + "license_name": "BSD-style license", + "license_link": "https://www.xiph.org/licenses/bsd/", # https://opus-codec.org/license/ + "build_info": { + "download_link": f"https://github.com/xiph/opus/releases/download/v{OPUS['version']}/opus-{OPUS['version']}.tar.gz", + "build_dir": "/tmp/opus", + "tarball_name": f"opus-{OPUS['version']}.tar.gz", + "sha256sum": "65c1d2f78b9f2fb20082c38cbe47c951ad5839345876e46941612ee87f9a7ce1 opus-1.5.2.tar.gz", + }, + }, + ), + ( + "libvorbis", + { + "link": "https://xiph.org/vorbis/", + "version": VORBIS["version"], + "version_link": "https://xiph.org/downloads/", + "release_date": VORBIS["release_date"], + "license_name": "BSD-style license", + "license_link": "https://www.xiph.org/licenses/bsd/", + "build_info": { + "download_link": f"http://downloads.xiph.org/releases/vorbis/libvorbis-{VORBIS['version']}.tar.gz", + "build_dir": "/tmp/vorbis", + "tarball_name": f"libvorbis-{VORBIS['version']}.tar.gz", + "sha256sum": "0e982409a9c3fc82ee06e08205b1355e5c6aa4c36bca58146ef399621b0ce5ab libvorbis-1.3.7.tar.gz", + }, + }, + ), + ( + "libvpx", + { + "link": "https://www.webmproject.org/code/", + # https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libvpx + "version": VPX["version"], + "version_link": "https://chromium.googlesource.com/webm/libvpx.git/", + "release_date": VPX["release_date"], + "license_name": "BSD-style license", + "license_link": "https://github.com/webmproject/libvpx/blob/master/LICENSE", + "build_info": { + # "download_link": f"https://chromium.googlesource.com/webm/libvpx/+archive/v{VPX['version']}.tar.gz", + "build_dir": "/tmp/libvpx", + # "tarball_name": f"libvpx-v{VPX['version']}.tar.gz", + }, + }, + ), + ( + "libwebp", + { + "link": "https://developers.google.com/speed/webp/", + # https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libwebp + "version": WEBP["version"], + "version_link": "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/index.html", + "release_date": WEBP["release_date"], + "license_name": "BSD-style license", + "license_link": "https://github.com/webmproject/libvpx/blob/master/LICENSE", + "build_info": { + "download_link": f"https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-{WEBP['version']}.tar.gz", + "build_dir": "/tmp/webp", + "tarball_name": f"libwebp-{WEBP['version']}.tar.gz", + }, + }, + ), + ( + "libmp3lame", + { + "link": "http://lame.sourceforge.net/", + "version": LAME["version"], + "version_link": "http://lame.sourceforge.net/download.php", + "release_date": LAME["release_date"], + "license_name": "GNU Lesser General Public License (LGPL) version 2.1", + "license_link": "http://lame.cvs.sourceforge.net/viewvc/lame/lame/LICENSE?revision=1.9", + "build_info": { + # this one is also testie + "download_link": f"https://sourceforge.net/projects/lame/files/lame/{LAME['version']}/lame-{LAME['version']}.tar.gz", + "build_dir": "/tmp/lame", + "tarball_name": f"lame-{LAME['version']}.tar.gz", + }, + }, + ), + ( + "libxvid", + { + "link": "https://www.xvid.com/", + "version": XVID["version"], + "version_link": "https://labs.xvid.com/source/", + "release_date": XVID["release_date"], + "license_name": "GNU General Public Licence (GPL) version 2", + "license_link": "http://websvn.xvid.org/cvs/viewvc.cgi/trunk/xvidcore/LICENSE?revision=851", + "build_info": { + "download_link": f"https://downloads.xvid.com/downloads/xvidcore-{XVID['version']}.tar.gz", + "build_dir": "/tmp/xvid", + "tarball_name": f"xvidcore-{XVID['version']}.tar.gz", + }, + }, + ), + ( + "libfdk-aac", + { + "link": "https://github.com/mstorsjo/fdk-aac", + # https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libfdk-aac + "version": FDKAAC["version"], + "version_link": "https://github.com/mstorsjo/fdk-aac/tags", + "release_date": FDKAAC["release_date"], + "license_name": "Liberal but not a license of patented technologies", + "license_link": "https://github.com/mstorsjo/fdk-aac/blob/master/NOTICE", + "build_info": { + "download_link": f"https://github.com/mstorsjo/fdk-aac/archive/refs/tags/v{FDKAAC['version']}.tar.gz", + "build_dir": "/tmp/fdk-aac", + "tarball_name": f"fdk-aac-{FDKAAC['version']}.tar.gz", + }, + }, + ), + ( + "openjpeg", + { + "link": "https://github.com/uclouvain/openjpeg", + "version": OPENJPEG["version"], + "version_link": "https://github.com/uclouvain/openjpeg/releases", + "release_date": OPENJPEG["release_date"], + "license_name": "BSD-style license", + "license_link": "https://github.com/uclouvain/openjpeg/blob/master/LICENSE", + "build_info": { + "download_link": f"https://github.com/uclouvain/openjpeg/archive/refs/tags/v{OPENJPEG['version']}.tar.gz", + "build_dir": "/tmp/openjpeg", + "tarball_name": f"openjpeg-{OPENJPEG['version']}.tar.gz", + }, + }, + ), + ( + "freetype", + { + "link": "https://www.freetype.org/", + "version": FREETYPE["version"], + "version_link": "http://download.savannah.gnu.org/releases/freetype/", + "release_date": FREETYPE["release_date"], + "license_name": "GNU General Public License (GPL) version 2", + "license_link": "https://www.freetype.org/license.html", + "build_info": { + "download_link": f"http://download.savannah.gnu.org/releases/freetype/freetype-{FREETYPE['version']}.tar.gz", + "build_dir": "/tmp/freetype", + "tarball_name": f"freetype-{FREETYPE['version']}.tar.gz", + }, + }, + ), + ( + "libvidstab", + { + "link": "https://github.com/georgmartius/vid.stab", + "version": LIBVIDSTAB["version"], + "version_link": "https://github.com/georgmartius/vid.stab/tags", + "release_date": LIBVIDSTAB["release_date"], + "license_name": "GNU General Public License (GPL) version 2", + "license_link": "https://github.com/georgmartius/vid.stab/blob/master/LICENSE", + "build_info": { + "download_link": f"https://github.com/georgmartius/vid.stab/archive/v{LIBVIDSTAB['version']}.tar.gz", + "build_dir": "/tmp/vid.stab", + "tarball_name": f"vid.stab-{LIBVIDSTAB['version']}.tar.gz", + }, + }, + ), + ( + "fribidi", + { + "link": "https://www.fribidi.org/", + "version": LIBFRIDIBI["version"], + "version_link": "https://github.com/fribidi/fribidi/releases", + "release_date": LIBFRIDIBI["release_date"], + "license_name": "GNU General Public License (GPL) version 2", + "license_link": "https://cgit.freedesktop.org/fribidi/fribidi/plain/COPYING", + "build_info": { + "download_link": f"https://github.com/fribidi/fribidi/archive/refs/tags/v{LIBFRIDIBI['version']}.tar.gz", + "build_dir": "/tmp/fribidi", + "tarball_name": f"fribidi-{LIBFRIDIBI['version']}.tar.gz", + "using_source_build": False, + # "sha256sum": "3fc96fa9473bd31dcb5500bdf1aa78b337ba13eb8c301e7c28923fea982453a8 fribidi-{LIBFRIDIBI['version']}.tar.gz" + }, + }, + ), + ( + "fontconfig", + { + "link": "https://gitlab.freedesktop.org/fontconfig/fontconfig", + "version": FONTCONFIG["version"], + "version_link": "https://gitlab.freedesktop.org/fontconfig/fontconfig/-/tags", + "release_date": FONTCONFIG["release_date"], + "license_name": "", + "license_link": "", + "build_info": { + "download_link": f"https://gitlab.freedesktop.org/fontconfig/fontconfig/-/archive/{FONTCONFIG['version']}/fontconfig-{FONTCONFIG['version']}.tar.gz", + "build_dir": "/tmp/fontconfig", + "tarball_name": f"fontconfig-{FONTCONFIG['version']}.tar.gz", + }, + }, + ), + ( + "libass", + { + "link": "https://github.com/libass/libass", + "version": LIBASS["version"], + "version_link": "https://github.com/libass/libass/releases", + "release_date": LIBASS["release_date"], + "license_name": "ISC License", + "license_link": "https://github.com/libass/libass/blob/master/COPYING", + "build_info": { + "download_link": f"https://github.com/libass/libass/releases/download/{LIBASS['version']}/libass-{LIBASS['version']}.tar.gz", + "build_dir": "/tmp/libass", + "tarball_name": f"libass-{LIBASS['version']}.tar.gz", + "using_source_build": False, + }, + }, + ), + ( + "kvazaar", + { + "link": "https://github.com/ultravideo/kvazaar", + "version": KVAAZAAR["version"], + "version_link": "https://github.com/ultravideo/kvazaar/releases", + "release_date": KVAAZAAR["release_date"], + "license_name": "BSD 3-Clause", + "license_link": "https://github.com/ultravideo/kvazaar/blob/master/LICENSE`", + "build_info": { + "download_link": f"https://github.com/ultravideo/kvazaar/releases/download/v{KVAAZAAR['version']}/kvazaar-{KVAAZAAR['version']}.tar.gz", + "build_dir": "/tmp/kvazaar", + "tarball_name": f"kvazaar-{KVAAZAAR['version']}.tar.gz", + }, + }, + ), + ( + "aom", + { + "link": "https://aomedia.googlesource.com/aom", + "version": AOM["version"], + "version_link": "https://aomedia.googlesource.com/aom/+refs", + "release_date": AOM["release_date"], + "license_name": "Alliance for Open Media", + "license_link": "https://aomedia.org/license/software-license/", + "build_info": { + "build_dir": "/tmp/aom", + }, + }, + ), + ( + "nvidia-codec-headers", + { + "link": "https://github.com/FFmpeg/nv-codec-headers", + "version": NV_CODEC["version"], + "version_link": "", + "release_date": NV_CODEC["release_date"], + "license_name": "", + "license_link": "", + "build_info": { + "download_link": f"https://github.com/FFmpeg/nv-codec-headers/releases/download/n{NV_CODEC['version']}/nv-codec-headers-{NV_CODEC['version']}.tar.gz", + # "download_link": f"https://github.com/FFmpeg/nv-codec-headers/archive/refs/tags/n{NV_CODEC['version']}.tar.gz", + "build_dir": "/tmp/nv-codec-headers", + "tarball_name": f"nv-codec-headers-{NV_CODEC['version']}.tar.gz", + }, + }, + ), + ( + "libsvtav1", + { + "link": "https://gitlab.com/AOMediaCodec/SVT-AV1", + "version": SVTAV1["version"], + "version_link": "https://gitlab.com/AOMediaCodec/SVT-AV1/-/tags", + "release_date": SVTAV1["release_date"], + "license_name": "BSD 3-Clause Clear License", + "license_link": "https://gitlab.com/AOMediaCodec/SVT-AV1/-/blob/master/LICENSE.md?ref_type=heads", + "build_info": { + "download_link": f"https://gitlab.com/AOMediaCodec/SVT-AV1/-/archive/v{SVTAV1['version']}/SVT-AV1-v{SVTAV1['version']}.tar.gz", + "build_dir": "/tmp/libsvtav1", + "tarball_name": f"SVT-AV1-v{SVTAV1['version']}.tar.gz", + }, + }, + ), + ( + "xorg-macros", + { + "link": "https://xcb.freedesktop.org/", + "version": XORG_MACROS["version"], + "version_link": "https://www.x.org/releases/individual/util/", + "release_date": XORG_MACROS["release_date"], + "license_name": "The MIT License", + "license_link": "https://opensource.org/licenses/MIT", + "build_info": { + "download_link": f"https://www.x.org/releases/individual/util/util-macros-{XORG_MACROS['version']}.tar.xz", + "build_dir": "/tmp/xorg-macros", + "tarball_name": f"util-macros-{XORG_MACROS['version']}.tar.xz", + "using_source_build": False, + }, + }, + ), + ( + "xorgproto", + { + "link": "https://www.x.org/releases/individual/proto/", + "version": XORGPROTO["version"], + "version_link": "https://www.x.org/releases/individual/proto/", + "release_date": XORGPROTO["release_date"], + "license_name": "The MIT License", + "license_link": "https://opensource.org/licenses/MIT", + "build_info": { + "download_link": f"https://www.x.org/releases/individual/proto/xorgproto-{XORGPROTO['version']}.tar.xz", + "build_dir": "/tmp/xorgproto", + "tarball_name": f"xorgproto-{XORGPROTO['version']}.tar.xz", + }, + }, + ), + ( + "libxau", + { + "link": "https://www.x.org/releases/individual/lib/", + "version": XAU["version"], + "version_link": "https://www.x.org/releases/individual/lib/", + "release_date": XAU["release_date"], + "license_name": "The MIT License", + "license_link": "https://opensource.org/licenses/MIT", + "build_info": { + "download_link": f"https://www.x.org/releases/individual/lib/libXau-{XAU['version']}.tar.xz", + "build_dir": "/tmp/libXau", + "tarball_name": f"libXau-{XAU['version']}.tar.xz", + "using_source_build": False, + }, + }, + ), + ( + "libpthread-stubs", + { + "link": "https://xcb.freedesktop.org/dist/", + "version": PTHREAD_STUBS["version"], + "version_link": "https://xcb.freedesktop.org/dist/", + "release_date": PTHREAD_STUBS["release_date"], + "license_name": "The MIT License", + "license_link": "https://opensource.org/licenses/MIT", + "build_info": { + "download_link": f"https://xcb.freedesktop.org/dist/libpthread-stubs-{PTHREAD_STUBS['version']}.tar.xz", + "build_dir": "/tmp/libpthread-stubs", + "tarball_name": f"libpthread-stubs-{PTHREAD_STUBS['version']}.tar.xz", + # "using_source_build": False, + }, + }, + ), + ( + "libxml2", + { + "link": "http://www.xmlsoft.org/", + "version": LIBXML2["version"], + "version_link": "http://www.xmlsoft.org/downloads.html", + "release_date": LIBXML2["release_date"], + "license_name": "MIT License", + "license_link": "http://www.xmlsoft.org/license.html", + "build_info": { + "download_link": f"https://gitlab.gnome.org/GNOME/libxml2/-/archive/v{LIBXML2['version']}/libxml2-v{LIBXML2['version']}.tar.gz", + "build_dir": "/tmp/libxml2", + "tarball_name": f"libxml2-{LIBXML2['version']}.tar.gz", + "using_source_build": False, + }, + }, + ), + ( + "libbluray", + { + "link": "https://www.videolan.org/developers/libbluray.html", + "version": LIBBLURAY["version"], + "version_link": "https://download.videolan.org/pub/videolan/libbluray/", + "release_date": LIBBLURAY["release_date"], + "license_name": "GNU General Public License (GPL) version 2", + "license_link": "https://www.gnu.org/licenses/old-licenses/gpl-2.0.html", + "build_info": { + "download_link": f"https://download.videolan.org/pub/videolan/libbluray/{LIBBLURAY['version']}/libbluray-{LIBBLURAY['version']}.tar.bz2", + "build_dir": "/tmp/libbluray", + "tarball_name": f"libbluray-{LIBBLURAY['version']}.tar.bz2", + }, + }, + ), + ( + "libzmq", + { + "link": "https://github.com/zeromq/libzmq/", + "version": LIBZMQ["version"], + "version_link": "https://github.com/zeromq/libzmq/releases/", + "release_date": LIBZMQ["release_date"], + "license_name": "Mozilla Public License (MPL) version 2.0", + "license_link": f"https://github.com/zeromq/libzmq/blob/v{LIBZMQ['version']}/LICENSE", + "build_info": { + "download_link": f"https://github.com/zeromq/libzmq/releases/download/v{LIBZMQ['version']}/zeromq-{LIBZMQ['version']}.tar.gz", + "build_dir": "/tmp/libzmq", + "tarball_name": f"zeromq-{LIBZMQ['version']}.tar.gz", + }, + }, + ), + ( + "libpng", + { + "link": "http://www.libpng.org/pub/png/libpng.html", + "version": LIBPNG["version"], + "version_link": "https://sourceforge.net/projects/libpng/files/libpng16/", + "release_date": LIBPNG["release_date"], + "license_name": "PNG Reference Library License version 2", + "license_link": "http://www.libpng.org/pub/png/src/libpng-LICENSE.txt", + "build_info": { + # sourceforge is a bit finikie + # https://sourceforge.net/projects/libpng/files/libpng16/1.6.44/libpng-1.6.44.tar.gz/download + # https://download.sourceforge.net/libpng/libpng-1.6.44.tar.xz + "download_link": f"https://download.sourceforge.net/libpng/libpng-{LIBPNG['version']}.tar.xz", + "build_dir": "/tmp/libpng", + "tarball_name": f"libpng-{LIBPNG['version']}.tar.xz", + "using_source_build": False, + }, + }, + ), + ( + "libaribb24", + { + "link": "https://github.com/nkoriyama/aribb24/", + "version": LIBARIBB24["version"], + "version_link": "https://github.com/nkoriyama/aribb24/releases", + "release_date": LIBARIBB24["release_date"], + "license_name": "GNU Lesser General Public License (LGPL) version 2.1 or newer", + "license_link": "https://github.com/nkoriyama/aribb24/issues/9", + "build_info": { + "download_link": f"https://github.com/nkoriyama/aribb24/archive/refs/tags/v{LIBARIBB24['version']}.tar.gz", + "build_dir": "/tmp/b24", + "tarball_name": f"aribb24-v{LIBARIBB24['version']}.tar.gz", + }, + }, + ), + ( + "zimg", + { + "link": "https://github.com/sekrit-twc/zimg", + "version": ZIMG["version"], + "version_link": "https://github.com/sekrit-twc/zimg/releases", + "release_date": ZIMG["release_date"], + "license_name": "WTFPL", + "license_link": "https://github.com/sekrit-twc/zimg?tab=WTFPL-1-ov-file", + "build_info": { + "download_link": f"https://github.com/sekrit-twc/zimg/archive/refs/tags/release-{ZIMG['version']}.tar.gz", + "build_dir": "/tmp/zimg", + "tarball_name": f"zimg-{ZIMG['version']}.tar.gz", + }, + }, + ), + ( + "libtheora", + { + "link": "https://xiph.org/downloads/", + "version": THEORA["version"], + "version_link": "https://xiph.org/downloads/", + "release_date": THEORA["release_date"], + "license_name": "BSD-style license", + "license_link": "https://git.xiph.org/?p=mirrors/theora.git;a=blob_plain;f=COPYING;hb=HEAD", + "build_info": { + "download_link": f"https://downloads.xiph.org/releases/theora/libtheora-{THEORA['version']}.tar.gz", + "build_dir": "/tmp/theora", + "tarball_name": f"libtheora-{THEORA['version']}.tar.gz", + }, + }, + ), + ( + "libsrt", + { + "link": "https://github.com/Haivision/srt", + "version": LIBSRT["version"], + "version_link": "https://github.com/Haivision/srt/releases/", + "release_date": LIBSRT["release_date"], + "license_name": "Mozilla Public License (MPL) version 2.0", + "license_link": "https://github.com/Haivision/srt/blob/master/LICENSE", + "build_info": { + "download_link": f"https://github.com/Haivision/srt/archive/refs/tags/v{LIBSRT['version']}.tar.gz", + "build_dir": "/tmp/srt", + "tarball_name": f"srt-v{LIBSRT['version']}.tar.gz", + }, + }, + ), + ( + "libvmaf", + { + "link": "https://github.com/Netflix/vmaf", + # https://github.com/Netflix/vmaf/issues/788 + "version": LIBVMAF["version"], + "version_link": "https://github.com/Netflix/vmaf/releases", + "release_date": LIBVMAF["release_date"], + "license_name": "BSD-2-Clause", + "license_link": "https://github.com/Netflix/vmaf/blob/master/LICENSE", + "build_info": { + "download_link": f"https://github.com/Netflix/vmaf/archive/refs/tags/v{LIBVMAF['version']}.tar.gz", + "build_dir": "/tmp/vmaf", + "tarball_name": f"vmaf-v{LIBVMAF['version']}.tar.gz", + }, + }, + ), + ( + "ffmpeg-8.1", + { + "link": "http://ffmpeg.org/", + "version": FFMPEG_81["version"], + "version_link": "http://ffmpeg.org/releases/", + "release_date": FFMPEG_81["release_date"], + "license_name": "GNU Lesser General Public License (LGPL) version 2.1", + "license_link": "https://ffmpeg.org/legal.html", + "build_info": { + "download_link": f"https://ffmpeg.org/releases/ffmpeg-{FFMPEG_81['version']}.tar.bz2", + "build_dir": "/tmp/ffmpeg", + "tarball_name": f"ffmpeg-{FFMPEG_81['version']}.tar.bz2", + }, + }, + ), + ( + "ffmpeg-8.0", + { + "link": "http://ffmpeg.org/", + "version": FFMPEG_80["version"], + "version_link": "http://ffmpeg.org/releases/", + "release_date": FFMPEG_80["release_date"], + "license_name": "GNU Lesser General Public License (LGPL) version 2.1", + "license_link": "https://ffmpeg.org/legal.html", + "build_info": { + "download_link": f"https://ffmpeg.org/releases/ffmpeg-{FFMPEG_80['version']}.tar.bz2", + "build_dir": "/tmp/ffmpeg", + "tarball_name": f"ffmpeg-{FFMPEG_80['version']}.tar.bz2", + }, + }, + ), + ] +) +# come back to this problem, I think yaml configuration might be better. +# with open('libraries.json', 'r') as f: +# data = json.load(f) # todo this should be yaml config +# order_list = data['build_order'] +# LIBRARIES = OrderedDict((key, data['libraries'][key]) for key in order_list) + + +def generate_library_table(filename): + """ + Generates a formatted table of FFmpeg libraries. + cut-n-paste this into the main projects README.md file. + """ + # open the filename for writing, overwrite if it exists + with open(filename, "w") as f: + f.write("## FFMPEG Supported Libraries\n") + f.write( + "The following libraries are used by FFMPEG. The version number and release date are provided along with the license information.\n" + ) + f.write( + "These version numbers are for the lib source builds, which are 'ubuntu2404-edge' and 'scratch320'.\n" + ) + f.write( + "These libs are included in the package images as well, but the version numbers might vary slightly.\n\n" + ) + + f.write( + "| Libraries | Version | Release Date | Download Source | Checksum | License |\n" + ) + f.write( + "|-----------|---------|--------------|------------ | --- | ---------|\n" + ) + for k, v in LIBRARIES.items(): + libname = f"[{k}]({v['link']})" # link to the library + libversion = f"[{v['version']}]({v['version_link']})" # link to the version + license = ( + f"[{v['license_name']}]({v['license_link']})" # link to the license + ) + # if build_info and build_info.tarball_name and build_info.download_link is avaliabl then set the download_source + download_source = "" + if ( + v.get("build_info") + and v["build_info"].get("tarball_name") + and v["build_info"].get("download_link") + ): + download_source = f"[{v['build_info']['tarball_name']}]({v['build_info']['download_link']})" + checksum = v["build_info"].get("sha256sum", "") + has_checksum = "Yes" if checksum else "No" + + using_source_build = v["build_info"].get("using_source_build", True) + # if we are not using the source build then do not display it in the table. + if using_source_build: + f.write( + f"| {libname} | {libversion} | {v.get('release_date', '')} | {download_source} | {has_checksum} | {license} |\n" + ) + print(f"Library table generated: {filename}") + sys.stdout.flush() + + +def generate_versions_manifest(output_file, ffmpeg_libraries=[]): + """ + Generates a 'generated_build_versions_manifest.json' file containing library version information. + + Args: + ffmpeg_libraries (dict): A dictionary containing FFmpeg library information. + output_file (str, optional): The filename for the build manifest. Defaults to "generated_build_versions_manifest.json". + """ + + manifest_data = {} + if not ffmpeg_libraries: + ffmpeg_libraries = LIBRARIES.keys() + for library_name in ffmpeg_libraries: + library_info = LIBRARIES.get(library_name, {}) + manifest_data[library_name] = library_info.get("version", "") + + with open(output_file, "w") as f: + json.dump(manifest_data, f, indent=4) + print(f"Versions manifest generated: {output_file}") + sys.stdout.flush() + + +def generate_build_manifest(output_file, ffmpeg_libraries=[]): + """ + Generates a 'generated_build_manifest.json' file containing library download information. + + Args: + ffmpeg_libraries (dict): A dictionary containing FFmpeg library information. + output_file (str, optional): The filename for the build manifest. Defaults to "generated_build_manifest.json". + """ + + manifest_data = [] + if not ffmpeg_libraries: + ffmpeg_libraries = LIBRARIES.keys() + for library_name in ffmpeg_libraries: + library_info = LIBRARIES.get(library_name, {}) + build_info = library_info.get("build_info", {}) + download_url = build_info.get("download_link", "") + build_dir = build_info.get("build_dir", "") + tarball_name = build_info.get("tarball_name", "") + sha256sum = build_info.get("sha256sum", "") + + if not all([build_dir]): + print( + f"Warning: Missing 'build_dir' information for {library_name} in build manifest generation." + ) + continue + + data = { + "library_name": library_name, + "build_dir": build_dir, + } + if download_url and tarball_name: + data["download_url"] = download_url + data["tarball_name"] = tarball_name + + if sha256sum: + data["sha256sum"] = sha256sum + manifest_data.append(data) + + with open(output_file, "w") as f: + json.dump(manifest_data, f, indent=4) + print(f"Build manifest generated: {output_file}") + sys.stdout.flush() + + +def list_of_strings(arg): + return arg.split(",") + + +def main(): + """ + Handles three modes: + 1. Generate both generated files (default) + 2. Generate library table + 3. Generate build manifest + """ + + parser = argparse.ArgumentParser(description="FFmpeg Library Information Script") + parser.add_argument("--library-list", type=list_of_strings, default=[]) + args = parser.parse_args() + + default_versions_table = "generated_versions_table.md" + default_generated_json_file = "generated_build_manifest.json" + default_generated_versions_json = "generated_build_versions_manifest.json" + + generate_library_table(default_versions_table) + generate_build_manifest(default_generated_json_file, args.library_list) + generate_versions_manifest(default_generated_versions_json, args.library_list) + + +if __name__ == "__main__": + main() diff --git a/docker-images/8.1/amf2404/install_ffmpeg.sh b/docker-images/8.1/amf2404/install_ffmpeg.sh new file mode 100755 index 00000000..7b4fb8b4 --- /dev/null +++ b/docker-images/8.1/amf2404/install_ffmpeg.sh @@ -0,0 +1,128 @@ +#!/bin/bash + +# Stop execution on any error +# Note: we can override this in the Dockerfile RUN command with an || true. +# which is useful for debugging +set -e +strip_libs=false + +# Parse command-line arguments +while [[ $# -gt 0 ]]; do + case "$1" in + --strip) + strip_libs=true + shift 1 + ;; + *) + echo "Unknown option: $1" + exit 1 + ;; + esac +done + +OS_NAME=$(uname -s) +is_ubuntu=false +is_alpine=false +if [[ "$OS_NAME" == "Linux" ]]; then + if grep -q "Ubuntu" /etc/os-release; then + is_ubuntu=true + elif [[ -f /etc/alpine-release ]]; then + is_alpine=true + fi +fi + +install_ffmpeg() { + echo "Installing ffmpeg" + ## cleanup + # This is used for both the source and packages version ( be robust about looking for libs to copy ) + if [ ! -f ${PREFIX}/bin/ffmpeg ]; then + echo "ERROR: ffmpeg not found in ${PREFIX}/bin" + exit 1 + fi + + ARCH=$(uname -m) + if [ "$ARCH" = "x86_64" ]; then + GNU_ARCH="x86_64-linux-gnu" + CUDA_ARCH="x86_64-linux" + elif [ "$ARCH" = "aarch64" ]; then + GNU_ARCH="aarch64-linux-gnu" + CUDA_ARCH="sbsa-linux" + else + GNU_ARCH="${ARCH}-linux-gnu" + CUDA_ARCH="${ARCH}-linux" + fi + + if ldd ${PREFIX}/bin/ffmpeg | grep ${GNU_ARCH} | cut -d ' ' -f 3 | grep -q . ; then + ldd ${PREFIX}/bin/ffmpeg | grep ${GNU_ARCH} | cut -d ' ' -f 3 | xargs -i cp -p {} /usr/local/lib/ + fi + if [[ -d /usr/local/cuda/targets/${CUDA_ARCH}/lib/ ]]; then + cp -p /usr/local/cuda/targets/${CUDA_ARCH}/lib/libnpp* /usr/local/lib + fi + + # Check if ffmpeg library is linked to opt/ffmpeg and copy it to /usr/local/lib + if ldd ${PREFIX}/bin/ffmpeg | grep opt/ffmpeg | cut -d ' ' -f 3 | grep -q . ; then + ldd ${PREFIX}/bin/ffmpeg | grep opt/ffmpeg | cut -d ' ' -f 3 | xargs -i cp -p {} /usr/local/lib/ + fi + + # Create symbolic links for shared libraries in /usr/local/lib + for lib in /usr/local/lib/*.so.*; do + ln -sf "${lib##*/}" "${lib%%.so.*}".so + done + + # Copy ffmpeg binaries and share directory to /usr/local + cp -r ${PREFIX}/bin/* /usr/local/bin/ + cp -r ${PREFIX}/share/ffmpeg /usr/local/share/ + + if [ ! -d /usr/local/include ]; then + mkdir -p /usr/local/include + fi + + # Build configuration and copy include directories + LD_LIBRARY_PATH=/usr/local/lib ffmpeg -buildconf + for lib in ${PREFIX}/include/libav* ${PREFIX}/include/libpostproc ${PREFIX}/include/libsw*; do + if [[ -d "$lib" ]]; then + cp -rp "$lib" /usr/local/include/ + else + echo "Warning: Directory '$lib' not found." + fi + done + + # Create pkgconfig directory and copy and modify pkgconfig files + mkdir -p /usr/local/lib/pkgconfig + for pc in ${PREFIX}/lib/pkgconfig/libav*.pc ${PREFIX}/lib/pkgconfig/libpostproc.pc ${PREFIX}/lib/pkgconfig/kvazaar.pc ${PREFIX}/lib/pkgconfig/libsw*.pc ${PREFIX}/lib/${GNU_ARCH}/pkgconfig/libvmaf*; do + if [[ -f "$pc" ]]; then + sed "s:${PREFIX}:/usr/local:g; s:/lib64:/lib:g" <"$pc" >/usr/local/lib/pkgconfig/"${pc##*/}"; \ + else + echo "Warning: File '$pc' not found." + fi + done +} + +fakeroot_install_with_striped_libs() { + echo "Installing ffmpeg with fakeroot and striped libs" + mkdir -p /tmp/fakeroot/lib + ldd ${PREFIX}/bin/ffmpeg | cut -d ' ' -f 3 | strings | xargs -I R cp R /tmp/fakeroot/lib/ + for lib in /tmp/fakeroot/lib/*; do strip --strip-all $lib; done + cp -r ${PREFIX}/bin /tmp/fakeroot/bin/ + cp -r ${PREFIX}/share/ffmpeg /tmp/fakeroot/share/ + LD_LIBRARY_PATH=/tmp/fakeroot/lib /tmp/fakeroot/bin/ffmpeg -buildconf +} + +fakeroot_install() { + echo "Using fakeroot to install ffmpeg" + mkdir -p /tmp/fakeroot/lib + ldd ${PREFIX}/bin/ffmpeg | cut -d ' ' -f 3 | strings | xargs -I R cp R /tmp/fakeroot/lib/ + cp -r ${PREFIX}/bin /tmp/fakeroot/bin/ + cp -r ${PREFIX}/share/ffmpeg /tmp/fakeroot/share/ + LD_LIBRARY_PATH=/tmp/fakeroot/lib /tmp/fakeroot/bin/ffmpeg -buildconf +} + +# if strip_libs is true then call the install_with_striped_libs function +# else if is_alpine is true then call the fakeroot_install function +if $strip_libs; then + fakeroot_install_with_striped_libs +elif $is_alpine; then + fakeroot_install +else + install_ffmpeg +fi diff --git a/docker-images/github-actions-matrix.json b/docker-images/github-actions-matrix.json index d0fac0fa..079b783d 100644 --- a/docker-images/github-actions-matrix.json +++ b/docker-images/github-actions-matrix.json @@ -117,6 +117,19 @@ "arch": "amd64", "runner": "ubuntu-latest" }, + { + "major_version": "8", + "version": "8.1", + "long_version": "8.1.1", + "variant": "amf2404", + "parent": "amf", + "is_parent": "True", + "is_latest": "False", + "platforms": "linux/amd64", + "platform": "linux/amd64", + "arch": "amd64", + "runner": "ubuntu-latest" + }, { "major_version": "8", "version": "8.1", @@ -247,6 +260,19 @@ "arch": "amd64", "runner": "ubuntu-latest" }, + { + "major_version": "8", + "version": "8.0", + "long_version": "8.0.2", + "variant": "amf2404", + "parent": "amf", + "is_parent": "True", + "is_latest": "False", + "platforms": "linux/amd64", + "platform": "linux/amd64", + "arch": "amd64", + "runner": "ubuntu-latest" + }, { "major_version": "8", "version": "8.0", @@ -312,6 +338,16 @@ "is_latest": "False", "platforms": "linux/amd64" }, + { + "major_version": "8", + "version": "8.1", + "long_version": "8.1.1", + "variant": "amf2404", + "parent": "amf", + "is_parent": "True", + "is_latest": "False", + "platforms": "linux/amd64" + }, { "major_version": "8", "version": "8.1", @@ -372,6 +408,16 @@ "is_latest": "False", "platforms": "linux/amd64" }, + { + "major_version": "8", + "version": "8.0", + "long_version": "8.0.2", + "variant": "amf2404", + "parent": "amf", + "is_parent": "True", + "is_latest": "False", + "platforms": "linux/amd64" + }, { "major_version": "8", "version": "8.0", diff --git a/docker-images/gitlab-ci.yml b/docker-images/gitlab-ci.yml index e3c2cde4..a575e065 100644 --- a/docker-images/gitlab-ci.yml +++ b/docker-images/gitlab-ci.yml @@ -1,6 +1,7 @@ stages: - lint - alpine + - amf - nvidia - scratch - ubuntu @@ -72,6 +73,19 @@ stages: ISLATEST: "False" PLATFORMS: "linux/amd64" +8.1.1-amf2404: + extends: .docker + stage: amf + variables: + MAJOR_VERSION: 8 + VERSION: "8.1" + LONG_VERSION: "8.1.1" + VARIANT: amf2404 + PARENT: "amf" + ISPARENT: "True" + ISLATEST: "False" + PLATFORMS: "linux/amd64" + 8.1.1-nvidia2404: extends: .docker stage: nvidia @@ -150,6 +164,19 @@ stages: ISLATEST: "False" PLATFORMS: "linux/amd64" +8.0.2-amf2404: + extends: .docker + stage: amf + variables: + MAJOR_VERSION: 8 + VERSION: "8.0" + LONG_VERSION: "8.0.2" + VARIANT: amf2404 + PARENT: "amf" + ISPARENT: "True" + ISLATEST: "False" + PLATFORMS: "linux/amd64" + 8.0.2-nvidia2404: extends: .docker stage: nvidia diff --git a/templates/Dockerfile-env-amf b/templates/Dockerfile-env-amf new file mode 100644 index 00000000..34c0f66b --- /dev/null +++ b/templates/Dockerfile-env-amf @@ -0,0 +1,96 @@ +ENV FFMPEG_VERSION=%%FFMPEG_VERSION%% + +ENV AMD_AMF_VERSION=v1.5.2 + +## opencore-amr - https://sourceforge.net/projects/opencore-amr/ +## x264 - http://www.videolan.org/developers/x264.html +## x265 - http://x265.org/ ( videolan ) +## libogg - https://www.xiph.org/ogg/ ( xiph ) +## libopus - https://www.opus-codec.org/ ( xiph ) +## - https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libopus +## libvorbis - https://xiph.org/vorbis/ ( xiph ) +## libvpx - https://www.webmproject.org/code/ +## - https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libvpx +## libwebp - https://developers.google.com/speed/webp/ +## libmp3lame - http://lame.sourceforge.net/ +## xvid - https://www.xvid.com/ (xvidcore) +## fdk-aac - https://github.com/mstorsjo/fdk-aac +## - https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libfdk-aac +## openjpeg - https://github.com/uclouvain/openjpeg +## freetype - https://www.freetype.org/ +## consider passing --no-install-recommends for this one its globbie (if you do, pass in libfreetype6) +## libvidstab - https://github.com/georgmartius/vid.stab +## fridibi - https://www.fribidi.org/ +## fontconfig - https://www.freedesktop.org/wiki/Software/fontconfig/ +## libass - https://github.com/libass/libass +## lib aom - https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libaom +## libsvtav1 - https://gitlab.com/AOMediaCodec/SVT-AV1.git +## - https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libsvtav1 +## libdav1d - https://code.videolan.org/videolan/dav1d +## - https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#libdav1d +## util-macros - (x.org) (and supporting libraries) for screen capture https://xcb.freedesktop.org/ +## xorgproto - (x.org) +## libXau - +## libpthread - libpthread-stubs +## libxml2 - for libbluray +## libbluray - Requires libxml, freetype, and fontconfig +## libzmq - https://github.com/zeromq/libzmq/ +## this one pulls in a bunch of dependencies +## libpng - this one also pulls in a bunch of stuff +## libaribb24 - +## zimg - https://github.com/sekrit-twc/zimg +## libtheora - http://www.theora.org/ ( xiph ) +## - https://stackoverflow.com/questions/4810996/how-to-resolve-configure-guessing-build-type-failure +## libsrt - https://github.com/Haivision/srt +## Secure Reliable Transport UDP streaming library +## multiple flavors (OpenSSL flavour) and ( GnuTLS flavour) +ARG OPENCORE_PKGS="libopencore-amrnb-dev libopencore-amrnb0 libopencore-amrwb-dev libopencore-amrwb0" +ARG X264_PKGS="libx264-164 libx264-dev" +ARG X265_PKGS="libnuma1 libx265-199 libx265-dev" +# libnuma-dev +ARG OGG_PKGS="libogg-dev libogg0" +ARG OPUS_PKGS="libopus-dev libopus0" +ARG VORBIS_PKGS="libvorbis-dev libvorbis0a libvorbisenc2 libvorbisfile3" +ARG VPX_PKGS="libvpx-dev libvpx9" +ARG WEBP_PKGS="libsharpyuv-dev libsharpyuv0 libwebp-dev libwebp7 libwebpdecoder3 libwebpdemux2 libwebpmux3" +ARG MP3LAME_PKGS="libmp3lame-dev libmp3lame0" +ARG XVIDCORE_PKGS="libxvidcore-dev libxvidcore4" +ARG FDKAAC_PKGS="libfdk-aac-dev libfdk-aac2" +ARG OPENJP_PKGS="libopenjp2-7 libopenjp2-7-dev" +# bzip2-doc fontconfig-config fonts-dejavu-core fonts-dejavu-mono libaom3 libbrotli-dev +# libbrotli1 libbsd0 libbz2-dev libc-dev-bin libc-devtools libc6-dev libcrypt-dev libde265-0 +# libdeflate0 libfontconfig1 libfreetype6 libgd3 libheif-plugin-aomdec +# libheif-plugin-aomenc libheif-plugin-libde265 libheif1 libjbig0 libjpeg-turbo8 +# libjpeg8 liblerc4 libpng-dev libpng-tools libpng16-16t64 libsharpyuv0 libtiff6 +# libwebp7 libx11-6 libx11-data libxau6 libxcb1 libxdmcp6 libxpm4 linux-libc-dev +# manpages manpages-dev rpcsvc-proto zlib1g-dev +ARG FREETYPE_PKGS="libfreetype6-dev" +ARG FONTCONFIG_PKGS="fontconfig libfontconfig-dev libfontconfig1 fontconfig-config fonts-dejavu-core fonts-dejavu-mono" +ARG VIDSTAB_PKGS="libvidstab-dev libvidstab1.1" +ARG FRIBIDI_PKGS="libfribidi-dev libfribidi0" +# libass-dev wanted to install a boat-load of packages +ARG LIBASS_PKGS="libass-dev libass9" +ARG AOM_PKGS="libaom-dev libaom3" +ARG SVTAV1_PKGS="libsvtav1-dev libsvtav1enc-dev libsvtav1enc1d1 libsvtav1dec-dev libsvtav1dec0" +ARG DAV1D_PKGS="libdav1d-dev libdav1d7" +# LIBDRM_PKGS picks ups some of the XORG_MACROS_PKGS as well +ARG XORG_MACROS_PKGS="libxcb-shm0-dev libxcb-shm0 libxcb-xfixes0 libxcb-xfixes0-dev" +ARG XPROTO_PKGS="x11proto-core-dev x11proto-dev" +ARG XAU_PKGS="libxau-dev libxau6" +ARG PTHREADS_STUBS_PKGS="libpthread-stubs0-dev" +ARG XML2_PKGS="libxml2-dev libxml2" +ARG BLURAY_PKGS="libbluray-dev libbluray2" +ARG ZMQ_PKGS="libzmq3-dev libzmq5" +# libpng-tools +ARG PNG_PKGS="libpng-dev libpng16-16t64" +ARG ARIBB24_PKGS="libaribb24-dev" +ARG ZIMG_PKGS="libzimg-dev libzimg2" +ARG THEORA_PKGS="libtheora-dev libtheora0" +ARG SRT_PKGS="libssl-dev libsrt-openssl-dev libsrt1.5-openssl" +ARG LIBDRM_PKGS="libbsd0 libdrm-dev libdrm2 libxcb1-dev libxcb1" + +ENV MAKEFLAGS="-j4" +ENV PKG_CONFIG_PATH="/opt/ffmpeg/share/pkgconfig:/opt/ffmpeg/lib/pkgconfig:/opt/ffmpeg/lib64/pkgconfig:/opt/ffmpeg/lib/x86_64-linux-gnu/pkgconfig:/opt/ffmpeg/lib/aarch64-linux-gnu/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig" + +ENV PREFIX="/opt/ffmpeg" +ENV LD_LIBRARY_PATH="/opt/ffmpeg/lib:/opt/ffmpeg/lib64:/opt/ffmpeg/lib/aarch64-linux-gnu" diff --git a/templates/Dockerfile-run-amf b/templates/Dockerfile-run-amf new file mode 100644 index 00000000..c4a89e2d --- /dev/null +++ b/templates/Dockerfile-run-amf @@ -0,0 +1,31 @@ +RUN \ + echo "Installing dependencies..." && \ + apt-get install -yq --no-install-recommends ${OPENCORE_PKGS} ${X264_PKGS} ${X265_PKGS} ${OGG_PKGS} ${OPUS_PKGS} ${VORBIS_PKGS} ${VPX_PKGS} ${WEBP_PKGS} ${MP3LAME_PKGS} ${XVIDCORE_PKGS} ${FDKAAC_PKGS} ${OPENJP_PKGS} ${FREETYPE_PKGS} ${VIDSTAB_PKGS} ${FRIBIDI_PKGS} ${FONTCONFIG_PKGS} ${LIBASS_PKGS} ${AOM_PKGS} ${SVTAV1_PKGS} ${DAV1D_PKGS} ${XORG_MACROS_PKGS} ${XPROTO_PKGS} ${XAU_PKGS} ${PTHREADS_STUBS_PKGS} ${XML2_PKGS} ${BLURAY_PKGS} ${ZMQ_PKGS} ${PNG_PKGS} ${ARIBB24_PKGS} ${ZIMG_PKGS} ${THEORA_PKGS} ${SRT_PKGS} ${LIBDRM_PKGS} + +RUN \ + git clone --branch ${AMD_AMF_VERSION} --depth 1 https://github.com/GPUOpen-LibrariesAndSDKs/AMF.git /tmp/amf && \ + mkdir -p /usr/local/include/AMF && \ + cp -a /tmp/amf/amf/public/include/. /usr/local/include/AMF/ && \ + rm -rf /tmp/amf + +# apt install libdrm-dev + +## libvmaf https://github.com/Netflix/vmaf +## https://github.com/Netflix/vmaf/issues/788#issuecomment-756098059 +RUN \ + echo "Adding g++ for VMAF build" && \ + apt-get install -yq g++ + +# Note: pass '--library-list lib1,lib2,lib3 for more control. +# Here we have 3 libs that we have to build from source +RUN /tmp/workdir/generate-source-of-truth-ffmpeg-versions.py --library-list kvazaar,libvmaf,whisper +RUN /tmp/workdir/download_tarballs.sh +RUN /tmp/workdir/build_source.sh + +RUN /tmp/workdir/generate-source-of-truth-ffmpeg-versions.py --library-list ffmpeg-%%FFMPEG_VERSION%% +RUN /tmp/workdir/download_tarballs.sh +RUN /tmp/workdir/build_source.sh + +## when debugging you can pass in || true to the end of the command +## to keep the build going even if one of the steps fails +RUN /tmp/workdir/install_ffmpeg.sh diff --git a/templates/Dockerfile-template.amf2404 b/templates/Dockerfile-template.amf2404 new file mode 100644 index 00000000..bbc3513c --- /dev/null +++ b/templates/Dockerfile-template.amf2404 @@ -0,0 +1,85 @@ +# ffmpeg - http://ffmpeg.org/download.html +# +# From https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu +# +# https://hub.docker.com/r/jrottenberg/ffmpeg/ +# +# +# Stage 1: Build +FROM ubuntu:24.04 AS builder + + +%%ENV%% + +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get -yqq update && \ + apt-get install -yq --no-install-recommends curl jq python3 python3-requests less tree file vim + +RUN buildDeps="autoconf \ + automake \ + cmake \ + build-essential \ + texinfo \ + curl \ + wget \ + tar \ + bzip2 \ + libexpat1-dev \ + gcc \ + git \ + git-core \ + gperf \ + libtool \ + make \ + meson \ + ninja-build \ + nasm \ + perl \ + pkg-config \ + python3 \ + yasm \ + zlib1g-dev \ + libfreetype6-dev \ + libgnutls28-dev \ + libsdl2-dev \ + libva-dev \ + libvdpau-dev \ + libnuma-dev \ + libdav1d-dev \ + openssl \ + libssl-dev \ + expat \ + libgomp1" && \ + apt-get -yqq update && \ + apt-get install -yq --no-install-recommends ${buildDeps} + +WORKDIR /tmp/workdir + +COPY generate-source-of-truth-ffmpeg-versions.py /tmp/workdir +COPY download_tarballs.sh /tmp/workdir +COPY build_source.sh /tmp/workdir +COPY install_ffmpeg.sh /tmp/workdir + + + +%%RUN%% + + +# Stage 2: Final Image ( shrink the size back down ) +FROM ubuntu:24.04 AS runtime +# Copy fonts and fontconfig from builder +COPY --from=builder /usr/share/fonts /usr/share/fonts +COPY --from=builder /usr/share/fontconfig /usr/share/fontconfig +COPY --from=builder /usr/bin/fc-* /usr/bin/ + +# Copy rest of the content +COPY --from=builder /usr/local /usr/local/ + +LABEL org.opencontainers.image.authors="julien@rottenberg.info" \ + org.opencontainers.image.source=https://github.com/jrottenberg/ffmpeg + +ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64 + +CMD ["--help"] +ENTRYPOINT ["ffmpeg"] diff --git a/update.py b/update.py index 372b02dd..f8f9db96 100755 --- a/update.py +++ b/update.py @@ -72,6 +72,9 @@ def get_eol_versions(): # Video Acceleration API (VAAPI) https://trac.ffmpeg.org/wiki/HWAccelIntro#VAAPI # i965-va-driver is x86_64 only {"name": "vaapi2404", "parent": "vaapi", "platforms": X86_ONLY_PLATFORMS}, + # AMD Advanced Media Framework (AMF) + # https://github.com/GPUOpen-LibrariesAndSDKs/AMF/wiki/Build-FFmpeg-with-AMF-Support + {"name": "amf2404", "parent": "amf", "platforms": X86_ONLY_PLATFORMS}, # NVIDIA CUDA builds are x86_64 only {"name": "nvidia2404", "parent": "nvidia", "platforms": X86_ONLY_PLATFORMS}, ] @@ -137,6 +140,8 @@ def read_ffmpeg_template(variant_name, env_or_run="env"): distro_name = "nvidia" elif variant_name == "vaapi": distro_name = "vaapi" + elif variant_name == "amf": + distro_name = "amf" else: distro_name = "ubuntu" @@ -289,6 +294,10 @@ def read_ffmpeg_template(variant_name, env_or_run="env"): ] == "vaapi": FFMPEG_CONFIG_FLAGS.append("--enable-vaapi") + if variant["parent"] == "amf": + CFLAGS.append("-I/usr/local/include") + FFMPEG_CONFIG_FLAGS.append("--enable-amf") + # libavresample removed on v5, deprecated since v4.0 # https://github.com/FFmpeg/FFmpeg/commit/c29038f3041a4080342b2e333c1967d136749c0f if float(version[0]) < 5: From a95135d5e694946617c14dd4c2e8f113fe07baad Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 18 Jun 2026 08:48:40 +0000 Subject: [PATCH 2/2] Add AMF and Vulkan libraries --- docker-images/8.0/amf2404/Dockerfile | 25 ++++++++++++++++++++++--- docker-images/8.1/amf2404/Dockerfile | 25 ++++++++++++++++++++++--- templates/Dockerfile-env-amf | 4 +++- templates/Dockerfile-run-amf | 11 ++++++++++- templates/Dockerfile-template.amf2404 | 10 +++++++++- 5 files changed, 66 insertions(+), 9 deletions(-) diff --git a/docker-images/8.0/amf2404/Dockerfile b/docker-images/8.0/amf2404/Dockerfile index 834321f5..5391849b 100644 --- a/docker-images/8.0/amf2404/Dockerfile +++ b/docker-images/8.0/amf2404/Dockerfile @@ -12,6 +12,8 @@ FROM ubuntu:24.04 AS builder ENV FFMPEG_VERSION=8.0.2 ENV AMD_AMF_VERSION=v1.5.2 +ENV AMD_AMF_REPO_URL=https://repo.radeon.com/amf/26.10.1 +ENV TZ=Etc/UTC ## opencore-amr - https://sourceforge.net/projects/opencore-amr/ ## x264 - http://www.videolan.org/developers/x264.html @@ -104,7 +106,7 @@ ENV MAKEFLAGS="-j4" ENV PKG_CONFIG_PATH="/opt/ffmpeg/share/pkgconfig:/opt/ffmpeg/lib/pkgconfig:/opt/ffmpeg/lib64/pkgconfig:/opt/ffmpeg/lib/x86_64-linux-gnu/pkgconfig:/opt/ffmpeg/lib/aarch64-linux-gnu/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig" ENV PREFIX="/opt/ffmpeg" -ENV LD_LIBRARY_PATH="/opt/ffmpeg/lib:/opt/ffmpeg/lib64:/opt/ffmpeg/lib/aarch64-linux-gnu" +ENV LD_LIBRARY_PATH="/opt/ffmpeg/lib:/opt/ffmpeg/lib64:/opt/ffmpeg/lib/aarch64-linux-gnu:/opt/amf/lib/x86_64-linux-gnu" ARG DEBIAN_FRONTEND=noninteractive @@ -161,7 +163,16 @@ COPY install_ffmpeg.sh /tmp/workdir RUN \ echo "Installing dependencies..." && \ - apt-get install -yq --no-install-recommends ${OPENCORE_PKGS} ${X264_PKGS} ${X265_PKGS} ${OGG_PKGS} ${OPUS_PKGS} ${VORBIS_PKGS} ${VPX_PKGS} ${WEBP_PKGS} ${MP3LAME_PKGS} ${XVIDCORE_PKGS} ${FDKAAC_PKGS} ${OPENJP_PKGS} ${FREETYPE_PKGS} ${VIDSTAB_PKGS} ${FRIBIDI_PKGS} ${FONTCONFIG_PKGS} ${LIBASS_PKGS} ${AOM_PKGS} ${SVTAV1_PKGS} ${DAV1D_PKGS} ${XORG_MACROS_PKGS} ${XPROTO_PKGS} ${XAU_PKGS} ${PTHREADS_STUBS_PKGS} ${XML2_PKGS} ${BLURAY_PKGS} ${ZMQ_PKGS} ${PNG_PKGS} ${ARIBB24_PKGS} ${ZIMG_PKGS} ${THEORA_PKGS} ${SRT_PKGS} ${LIBDRM_PKGS} + apt-get install -yq --no-install-recommends ${OPENCORE_PKGS} ${X264_PKGS} ${X265_PKGS} ${OGG_PKGS} ${OPUS_PKGS} ${VORBIS_PKGS} ${VPX_PKGS} ${WEBP_PKGS} ${MP3LAME_PKGS} ${XVIDCORE_PKGS} ${FDKAAC_PKGS} ${OPENJP_PKGS} ${FREETYPE_PKGS} ${VIDSTAB_PKGS} ${FRIBIDI_PKGS} ${FONTCONFIG_PKGS} ${LIBASS_PKGS} ${AOM_PKGS} ${SVTAV1_PKGS} ${DAV1D_PKGS} ${XORG_MACROS_PKGS} ${XPROTO_PKGS} ${XAU_PKGS} ${PTHREADS_STUBS_PKGS} ${XML2_PKGS} ${BLURAY_PKGS} ${ZMQ_PKGS} ${PNG_PKGS} ${ARIBB24_PKGS} ${ZIMG_PKGS} ${THEORA_PKGS} ${SRT_PKGS} ${LIBDRM_PKGS} tzdata + +RUN \ + . /etc/os-release && \ + codename="${UBUNTU_CODENAME:-${VERSION_CODENAME}}" && \ + mkdir -p /etc/apt/keyrings && \ + curl -fsSL ${AMD_AMF_REPO_URL}/amf-pub.gpg -o /etc/apt/keyrings/amf-pub.asc && \ + echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/amf-pub.asc] ${AMD_AMF_REPO_URL}/ubuntu ${codename} main" > /etc/apt/sources.list.d/amf.list && \ + apt-get -yqq update && \ + apt-get install -yq --no-install-recommends amf-amdgpu-pro libamdenc-amdgpu-pro RUN \ git clone --branch ${AMD_AMF_VERSION} --depth 1 https://github.com/GPUOpen-LibrariesAndSDKs/AMF.git /tmp/amf && \ @@ -195,6 +206,13 @@ RUN /tmp/workdir/install_ffmpeg.sh # Stage 2: Final Image ( shrink the size back down ) FROM ubuntu:24.04 AS runtime + +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get -yqq update && \ + apt-get install -yq --no-install-recommends libvulkan1 mesa-vulkan-drivers && \ + rm -rf /var/lib/apt/lists/* + # Copy fonts and fontconfig from builder COPY --from=builder /usr/share/fonts /usr/share/fonts COPY --from=builder /usr/share/fontconfig /usr/share/fontconfig @@ -202,11 +220,12 @@ COPY --from=builder /usr/bin/fc-* /usr/bin/ # Copy rest of the content COPY --from=builder /usr/local /usr/local/ +COPY --from=builder /opt/amf /opt/amf/ LABEL org.opencontainers.image.authors="julien@rottenberg.info" \ org.opencontainers.image.source=https://github.com/jrottenberg/ffmpeg -ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64 +ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64:/opt/amf/lib/x86_64-linux-gnu CMD ["--help"] ENTRYPOINT ["ffmpeg"] diff --git a/docker-images/8.1/amf2404/Dockerfile b/docker-images/8.1/amf2404/Dockerfile index 08ed0d42..fc036e15 100644 --- a/docker-images/8.1/amf2404/Dockerfile +++ b/docker-images/8.1/amf2404/Dockerfile @@ -12,6 +12,8 @@ FROM ubuntu:24.04 AS builder ENV FFMPEG_VERSION=8.1.1 ENV AMD_AMF_VERSION=v1.5.2 +ENV AMD_AMF_REPO_URL=https://repo.radeon.com/amf/26.10.1 +ENV TZ=Etc/UTC ## opencore-amr - https://sourceforge.net/projects/opencore-amr/ ## x264 - http://www.videolan.org/developers/x264.html @@ -104,7 +106,7 @@ ENV MAKEFLAGS="-j4" ENV PKG_CONFIG_PATH="/opt/ffmpeg/share/pkgconfig:/opt/ffmpeg/lib/pkgconfig:/opt/ffmpeg/lib64/pkgconfig:/opt/ffmpeg/lib/x86_64-linux-gnu/pkgconfig:/opt/ffmpeg/lib/aarch64-linux-gnu/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig" ENV PREFIX="/opt/ffmpeg" -ENV LD_LIBRARY_PATH="/opt/ffmpeg/lib:/opt/ffmpeg/lib64:/opt/ffmpeg/lib/aarch64-linux-gnu" +ENV LD_LIBRARY_PATH="/opt/ffmpeg/lib:/opt/ffmpeg/lib64:/opt/ffmpeg/lib/aarch64-linux-gnu:/opt/amf/lib/x86_64-linux-gnu" ARG DEBIAN_FRONTEND=noninteractive @@ -161,7 +163,16 @@ COPY install_ffmpeg.sh /tmp/workdir RUN \ echo "Installing dependencies..." && \ - apt-get install -yq --no-install-recommends ${OPENCORE_PKGS} ${X264_PKGS} ${X265_PKGS} ${OGG_PKGS} ${OPUS_PKGS} ${VORBIS_PKGS} ${VPX_PKGS} ${WEBP_PKGS} ${MP3LAME_PKGS} ${XVIDCORE_PKGS} ${FDKAAC_PKGS} ${OPENJP_PKGS} ${FREETYPE_PKGS} ${VIDSTAB_PKGS} ${FRIBIDI_PKGS} ${FONTCONFIG_PKGS} ${LIBASS_PKGS} ${AOM_PKGS} ${SVTAV1_PKGS} ${DAV1D_PKGS} ${XORG_MACROS_PKGS} ${XPROTO_PKGS} ${XAU_PKGS} ${PTHREADS_STUBS_PKGS} ${XML2_PKGS} ${BLURAY_PKGS} ${ZMQ_PKGS} ${PNG_PKGS} ${ARIBB24_PKGS} ${ZIMG_PKGS} ${THEORA_PKGS} ${SRT_PKGS} ${LIBDRM_PKGS} + apt-get install -yq --no-install-recommends ${OPENCORE_PKGS} ${X264_PKGS} ${X265_PKGS} ${OGG_PKGS} ${OPUS_PKGS} ${VORBIS_PKGS} ${VPX_PKGS} ${WEBP_PKGS} ${MP3LAME_PKGS} ${XVIDCORE_PKGS} ${FDKAAC_PKGS} ${OPENJP_PKGS} ${FREETYPE_PKGS} ${VIDSTAB_PKGS} ${FRIBIDI_PKGS} ${FONTCONFIG_PKGS} ${LIBASS_PKGS} ${AOM_PKGS} ${SVTAV1_PKGS} ${DAV1D_PKGS} ${XORG_MACROS_PKGS} ${XPROTO_PKGS} ${XAU_PKGS} ${PTHREADS_STUBS_PKGS} ${XML2_PKGS} ${BLURAY_PKGS} ${ZMQ_PKGS} ${PNG_PKGS} ${ARIBB24_PKGS} ${ZIMG_PKGS} ${THEORA_PKGS} ${SRT_PKGS} ${LIBDRM_PKGS} tzdata + +RUN \ + . /etc/os-release && \ + codename="${UBUNTU_CODENAME:-${VERSION_CODENAME}}" && \ + mkdir -p /etc/apt/keyrings && \ + curl -fsSL ${AMD_AMF_REPO_URL}/amf-pub.gpg -o /etc/apt/keyrings/amf-pub.asc && \ + echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/amf-pub.asc] ${AMD_AMF_REPO_URL}/ubuntu ${codename} main" > /etc/apt/sources.list.d/amf.list && \ + apt-get -yqq update && \ + apt-get install -yq --no-install-recommends amf-amdgpu-pro libamdenc-amdgpu-pro RUN \ git clone --branch ${AMD_AMF_VERSION} --depth 1 https://github.com/GPUOpen-LibrariesAndSDKs/AMF.git /tmp/amf && \ @@ -195,6 +206,13 @@ RUN /tmp/workdir/install_ffmpeg.sh # Stage 2: Final Image ( shrink the size back down ) FROM ubuntu:24.04 AS runtime + +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get -yqq update && \ + apt-get install -yq --no-install-recommends libvulkan1 mesa-vulkan-drivers && \ + rm -rf /var/lib/apt/lists/* + # Copy fonts and fontconfig from builder COPY --from=builder /usr/share/fonts /usr/share/fonts COPY --from=builder /usr/share/fontconfig /usr/share/fontconfig @@ -202,11 +220,12 @@ COPY --from=builder /usr/bin/fc-* /usr/bin/ # Copy rest of the content COPY --from=builder /usr/local /usr/local/ +COPY --from=builder /opt/amf /opt/amf/ LABEL org.opencontainers.image.authors="julien@rottenberg.info" \ org.opencontainers.image.source=https://github.com/jrottenberg/ffmpeg -ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64 +ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64:/opt/amf/lib/x86_64-linux-gnu CMD ["--help"] ENTRYPOINT ["ffmpeg"] diff --git a/templates/Dockerfile-env-amf b/templates/Dockerfile-env-amf index 34c0f66b..023927b3 100644 --- a/templates/Dockerfile-env-amf +++ b/templates/Dockerfile-env-amf @@ -1,6 +1,8 @@ ENV FFMPEG_VERSION=%%FFMPEG_VERSION%% ENV AMD_AMF_VERSION=v1.5.2 +ENV AMD_AMF_REPO_URL=https://repo.radeon.com/amf/26.10.1 +ENV TZ=Etc/UTC ## opencore-amr - https://sourceforge.net/projects/opencore-amr/ ## x264 - http://www.videolan.org/developers/x264.html @@ -93,4 +95,4 @@ ENV MAKEFLAGS="-j4" ENV PKG_CONFIG_PATH="/opt/ffmpeg/share/pkgconfig:/opt/ffmpeg/lib/pkgconfig:/opt/ffmpeg/lib64/pkgconfig:/opt/ffmpeg/lib/x86_64-linux-gnu/pkgconfig:/opt/ffmpeg/lib/aarch64-linux-gnu/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig" ENV PREFIX="/opt/ffmpeg" -ENV LD_LIBRARY_PATH="/opt/ffmpeg/lib:/opt/ffmpeg/lib64:/opt/ffmpeg/lib/aarch64-linux-gnu" +ENV LD_LIBRARY_PATH="/opt/ffmpeg/lib:/opt/ffmpeg/lib64:/opt/ffmpeg/lib/aarch64-linux-gnu:/opt/amf/lib/x86_64-linux-gnu" diff --git a/templates/Dockerfile-run-amf b/templates/Dockerfile-run-amf index c4a89e2d..ce5dc837 100644 --- a/templates/Dockerfile-run-amf +++ b/templates/Dockerfile-run-amf @@ -1,6 +1,15 @@ RUN \ echo "Installing dependencies..." && \ - apt-get install -yq --no-install-recommends ${OPENCORE_PKGS} ${X264_PKGS} ${X265_PKGS} ${OGG_PKGS} ${OPUS_PKGS} ${VORBIS_PKGS} ${VPX_PKGS} ${WEBP_PKGS} ${MP3LAME_PKGS} ${XVIDCORE_PKGS} ${FDKAAC_PKGS} ${OPENJP_PKGS} ${FREETYPE_PKGS} ${VIDSTAB_PKGS} ${FRIBIDI_PKGS} ${FONTCONFIG_PKGS} ${LIBASS_PKGS} ${AOM_PKGS} ${SVTAV1_PKGS} ${DAV1D_PKGS} ${XORG_MACROS_PKGS} ${XPROTO_PKGS} ${XAU_PKGS} ${PTHREADS_STUBS_PKGS} ${XML2_PKGS} ${BLURAY_PKGS} ${ZMQ_PKGS} ${PNG_PKGS} ${ARIBB24_PKGS} ${ZIMG_PKGS} ${THEORA_PKGS} ${SRT_PKGS} ${LIBDRM_PKGS} + apt-get install -yq --no-install-recommends ${OPENCORE_PKGS} ${X264_PKGS} ${X265_PKGS} ${OGG_PKGS} ${OPUS_PKGS} ${VORBIS_PKGS} ${VPX_PKGS} ${WEBP_PKGS} ${MP3LAME_PKGS} ${XVIDCORE_PKGS} ${FDKAAC_PKGS} ${OPENJP_PKGS} ${FREETYPE_PKGS} ${VIDSTAB_PKGS} ${FRIBIDI_PKGS} ${FONTCONFIG_PKGS} ${LIBASS_PKGS} ${AOM_PKGS} ${SVTAV1_PKGS} ${DAV1D_PKGS} ${XORG_MACROS_PKGS} ${XPROTO_PKGS} ${XAU_PKGS} ${PTHREADS_STUBS_PKGS} ${XML2_PKGS} ${BLURAY_PKGS} ${ZMQ_PKGS} ${PNG_PKGS} ${ARIBB24_PKGS} ${ZIMG_PKGS} ${THEORA_PKGS} ${SRT_PKGS} ${LIBDRM_PKGS} tzdata + +RUN \ + . /etc/os-release && \ + codename="${UBUNTU_CODENAME:-${VERSION_CODENAME}}" && \ + mkdir -p /etc/apt/keyrings && \ + curl -fsSL ${AMD_AMF_REPO_URL}/amf-pub.gpg -o /etc/apt/keyrings/amf-pub.asc && \ + echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/amf-pub.asc] ${AMD_AMF_REPO_URL}/ubuntu ${codename} main" > /etc/apt/sources.list.d/amf.list && \ + apt-get -yqq update && \ + apt-get install -yq --no-install-recommends amf-amdgpu-pro libamdenc-amdgpu-pro RUN \ git clone --branch ${AMD_AMF_VERSION} --depth 1 https://github.com/GPUOpen-LibrariesAndSDKs/AMF.git /tmp/amf && \ diff --git a/templates/Dockerfile-template.amf2404 b/templates/Dockerfile-template.amf2404 index bbc3513c..777b32db 100644 --- a/templates/Dockerfile-template.amf2404 +++ b/templates/Dockerfile-template.amf2404 @@ -68,6 +68,13 @@ COPY install_ffmpeg.sh /tmp/workdir # Stage 2: Final Image ( shrink the size back down ) FROM ubuntu:24.04 AS runtime + +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get -yqq update && \ + apt-get install -yq --no-install-recommends libvulkan1 mesa-vulkan-drivers && \ + rm -rf /var/lib/apt/lists/* + # Copy fonts and fontconfig from builder COPY --from=builder /usr/share/fonts /usr/share/fonts COPY --from=builder /usr/share/fontconfig /usr/share/fontconfig @@ -75,11 +82,12 @@ COPY --from=builder /usr/bin/fc-* /usr/bin/ # Copy rest of the content COPY --from=builder /usr/local /usr/local/ +COPY --from=builder /opt/amf /opt/amf/ LABEL org.opencontainers.image.authors="julien@rottenberg.info" \ org.opencontainers.image.source=https://github.com/jrottenberg/ffmpeg -ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64 +ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64:/opt/amf/lib/x86_64-linux-gnu CMD ["--help"] ENTRYPOINT ["ffmpeg"]