diff --git a/.gitattributes b/.gitattributes index cfb3cbf..ecf83dd 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,9 +1,2 @@ -# Enforce LF line endings for all text files (Linux build system) * text=auto eol=lf - -# Shell scripts must be LF -*.sh text eol=lf - -# Explicitly binary -*.tar.gz binary -*.mp4 binary +*.patch -text diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml deleted file mode 100644 index acc3fa9..0000000 --- a/.github/codeql/codeql-config.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: "CodeQL config (flexplay-ffmpeg builder)" - -# This repo is a BUILDER of stock upstream FFmpeg + libraries — it does not vendor, -# modify, or compile in any upstream source of its own. Upstream code is cloned into -# the (git-ignored, ephemeral) .build/ tree only at workflow run time and is never -# committed. We scan our OWN code only; upstream CVEs are upstream's to triage. -# -# C/C++ analysis runs in build-mode: none (see codeql.yml), which scans the C source -# committed to the repo — currently scripts/test/smoke.c and any future test -# programs — WITHOUT building. Nothing is compiled, so upstream is never cloned or -# analyzed. paths-ignore is a belt-and-suspenders guard: if a build ever runs under -# CodeQL, the ephemeral upstream build tree is excluded from results. -paths-ignore: - - '.build/**' diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 3d6a7c6..8976576 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,21 +1,18 @@ -# Dependabot handles GitHub Actions version updates (SHAs/tags in .github/workflows/). -# The build DEPENDENCIES (codec/util libraries) are handled separately by Renovate, -# which is scoped to deps.json only — see renovate.json + .github/workflows/renovate.yml. -# Keeping this config in-repo (rather than the repo-settings UI) makes the policy visible -# and reviewable. +# The actions the workflows use (ffmpeg.lock is kept current by update-lock.yml, not Dependabot): one grouped PR a week, +# each release a week old first, merged by ci.yml once it passes. version: 2 updates: - - package-ecosystem: "github-actions" - directory: "/" # scans all workflows under .github/workflows/ + - package-ecosystem: github-actions + directory: / schedule: - interval: "weekly" - day: "monday" - labels: - - "dependencies" - - "github-actions" + interval: weekly + day: monday + labels: [dependencies] commit-message: - prefix: "chore(actions)" + prefix: ci + cooldown: + default-days: 7 + exclude: ['devenvy/*'] # the engine's workflows arrive without delay groups: - github-actions: # one grouped PR for all action bumps, not one per action - patterns: - - "*" + actions: + patterns: ['*'] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index f3bc18d..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,373 +0,0 @@ -name: Build FFmpeg - -permissions: - contents: read - -on: - workflow_call: - inputs: - ffmpeg_version: - required: true - type: string - ref: - required: false - type: string - default: "" - fail_fast: - required: false - type: boolean - default: false - -jobs: - build: - strategy: - fail-fast: ${{ inputs.fail_fast }} - matrix: - rid: [linux-x64, linux-arm64, linux-armhf, linux-musl-x64, linux-musl-arm64, win-x64, win-arm64, osx-x64, osx-arm64, android-arm64, android-x64, ios-arm64, ios-sim-arm64, maccatalyst-arm64, maccatalyst-x64] - license: [lgpl, gpl] - # License version series. 3 = (L)GPLv3 (OpenSSL 3.x TLS + Vulkan on Linux/Android, both - # Apache-2.0). 2 = LGPLv2.1 / GPLv2 (App-Store-safe): Vulkan dropped everywhere; on - # Linux/Android/Catalyst, gplv2 gets GnuTLS but lgplv2 ships with NO TLS backend at all - # (GnuTLS's deps can't stay LGPLv2.1). Windows, macOS and iOS are unaffected by any of - # this — they keep their native SChannel/SecureTransport TLS in every cell, v3 or v2. - # Mac Catalyst is NOT: SecureTransport is unavailable on macabi, so it follows the - # Linux/Android ladder (see scripts/platform/apple.sh's Catalyst arm). - license_version: [3, 2] - include: - - rid: linux-x64 - runner: ubuntu-latest - - rid: linux-arm64 - runner: ubuntu-24.04-arm - - rid: linux-armhf - runner: ubuntu-latest - # Build inside Debian Bookworm (glibc 2.36), not on the bare runner. The runner image - # ships glibc 2.38, and cross-compiling against ITS headers raised the armhf floor to - # 2.38 -- visible as __isoc23_* imports in the published libraries. Raspberry Pi OS - # Bookworm and Debian 12 ship 2.36, so armhf could not run on the hardware armhf - # mostly exists for, and it contradicted the 2.28 floor documented in - # docs/install/linux.md. Bookworm is the oldest base that still satisfies the Node 20 - # runtime the JS actions need (glibc 2.28+). - container: debian:bookworm@sha256:f37a335e82bca302e955fa39f9dfe28f1be618f016f8a2b56318e5a5111afc26 - - rid: linux-musl-x64 - runner: ubuntu-latest - container: alpine:3.24.2@sha256:294b683cb724975bec92580e1e685676bd4b50bda910ddb8c51d4cabeaec77e6 - # No container: here (unlike linux-musl-x64) — GitHub only supports - # JavaScript actions in Alpine containers on x64 runners, so this RID - # instead docker-runs the pinned Alpine image itself in the build step below, - # keeping actions/checkout etc. on the host's glibc Node runtime. - - rid: linux-musl-arm64 - runner: ubuntu-24.04-arm - - rid: win-x64 - runner: ubuntu-latest - - rid: win-arm64 - runner: ubuntu-latest - - rid: osx-x64 - runner: macos-15-intel - - rid: osx-arm64 - runner: macos-latest - - rid: android-arm64 - runner: ubuntu-latest - - rid: android-x64 - runner: ubuntu-latest - - rid: ios-arm64 - runner: macos-latest - - rid: ios-sim-arm64 - runner: macos-latest - # Catalyst cross-compiles from the macOS SDK, so either runner arch can build either - # slice; both use the default. The TEST jobs are the ones that need matching arches, - # because Catalyst binaries actually execute (see test-mobile.yml). - - rid: maccatalyst-arm64 - runner: macos-latest - - rid: maccatalyst-x64 - runner: macos-latest - - runs-on: ${{ matrix.runner }} - container: ${{ matrix.container || '' }} - name: ${{ inputs.ffmpeg_version }} ${{ matrix.rid }} (${{ matrix.license }}v${{ matrix.license_version }}) - - env: - BUILD_RID: ${{ matrix.rid }} - BUILD_LICENSE: ${{ matrix.license }} - BUILD_LICENSE_VERSION: ${{ matrix.license_version }} - # Artifact names must be unique across every version/license/series in one run. - # License token = {license}v{series}: lgplv3 | gplv3 | lgplv2 | gplv2 (lgplv2 = LGPLv2.1). - VARIANT: ${{ inputs.ffmpeg_version }}-${{ matrix.rid }}-${{ matrix.license }}v${{ matrix.license_version }} - # Embedded into legal/SOURCE_OFFER.txt so the corresponding-source notice - # points at this exact repo + commit. - SOURCE_REPO_URL: ${{ github.server_url }}/${{ github.repository }} - SOURCE_REPO_REF: ${{ inputs.ref || github.sha }} - - steps: - - name: Bootstrap container (Alpine or Debian) - if: matrix.container - # Package installs only: a stalled mirror must fail here, not consume the 6 h job limit. - timeout-minutes: 25 - # Was gated on `matrix.container` merely being SET and hardcoded apk, which broke the - # moment a second container image appeared: linux-armhf now builds in debian:bookworm - # (for its glibc floor) and died with "apk: not found". Pick the package manager from - # the image instead of assuming Alpine. - shell: sh -e {0} - run: | - if command -v apk >/dev/null 2>&1; then - apk add --no-cache bash git file jq # 'file' for the test script, 'jq' for the dep loader - elif command -v apt-get >/dev/null 2>&1; then - # Bounded waits: a stalled mirror must fail fast, not hold the job (see apt_get in - # scripts/lib.sh, which the build itself uses). - APT="-o Acquire::Retries=5 -o Acquire::http::Timeout=30 -o Acquire::https::Timeout=30" - apt-get $APT update -qq - # python3-pip: Debian ships none, and 03_install_packages.sh needs pip to pull a meson - # newer than the distro's (bookworm has 1.0.1; fontconfig 2.18+ wants >= 1.11). Without - # it the job died on "No module named pip" after an otherwise clean apt run. - apt-get $APT install -y -q --no-install-recommends bash git file jq ca-certificates curl sudo python3-pip - else - echo "unsupported container image: no apk or apt-get" >&2; exit 1 - fi - - # actions/checkout has no retry input; its internal helper makes 3 attempts with a RANDOM - # 10-20s sleep between them, so roughly 20-40s of cover. A DNS or TLS blip longer than that - # kills the job before any of our code runs: - # fatal: unable to access 'https://github.com/...': Could not resolve host: github.com - # The action cannot be wrapped: a local composite action needs the repo ALREADY checked out, - # and retry actions only wrap `run:` steps, not `uses:` steps. So wait for the host to be - # reachable BEFORE checkout, with the same exponential-with-jitter backoff the build scripts - # use (4, 8, 16, 32, 64s + jitter), and do NOT sleep after the final attempt -- nothing probes - # again afterwards. Worst case is ~2 minutes of sleep plus the probe timeouts. - # This never fails the job. If the host is still unreachable it warns and lets checkout run, so - # the real error is reported by the action rather than masked here. - - name: Wait for github.com to be reachable - shell: bash - run: | - command -v curl >/dev/null 2>&1 || { echo "curl unavailable - skipping reachability wait"; exit 0; } - delay=4 - for i in 1 2 3 4 5 6; do - if curl -sSf -o /dev/null --max-time 10 "${GITHUB_SERVER_URL:-https://github.com}"; then - if [ "$i" -gt 1 ]; then echo "github.com reachable after attempt ${i}"; fi - exit 0 - fi - if [ "$i" -eq 6 ]; then break; fi - s=$(( delay + (RANDOM % 5) )) - echo "github.com not reachable (attempt ${i}/6) - retrying in ${s}s" >&2 - sleep "$s" - delay=$(( delay * 2 )) - done - echo "::warning::github.com still unreachable after 6 attempts; letting checkout try anyway" - - uses: actions/checkout@v7 - with: - # github.sha, NOT github.ref: for a push run github.ref is refs/heads/main, so each - # matrix cell would check out whatever main's tip is when that cell STARTS. Across a - # multi-hour matrix that lets different cells build different commits, and none of - # them need be the commit the release tags. github.sha is the immutable event SHA and - # is shared with the calling workflow, so every cell builds exactly one tree. - ref: ${{ inputs.ref || github.sha }} - - # The HOST glslc. FFmpeg's configure executes it on the runner to compile shaders, and it - # has to be new enough for --target-env=vulkan1.4 -- the distro glslc on Ubuntu, Debian and - # manylinux is not, so 03_install_packages.sh builds the pinned shaderc from source. That is - # 4-5 minutes on every Vulkan (v3) cell of every Linux/Windows/Android RID: 28 cells, about - # two hours of compute, per two-line release, all producing the same binary. It is a single - # executable that changes only when the shaderc pin does, so cache it. - # - # Key = RID + the host the binary is built ON + the shaderc ref the ledger resolves for this - # RID and FFmpeg line. - # - The ref comes from the real loader (dep_version), so a shaderc override for one line - # or platform gets its own key instead of silently reusing the default's. NOT - # hashFiles(deps.json): that would miss on every weekly ledger bump. - # - The host fingerprint is the distro release the build runs in (ubuntu-24.04, - # debian-12), or the manylinux image name for the RIDs that build inside it (its glibc - # is 2.28 by definition, whatever the image date). Cache entries are IMMUTABLE: without - # this, a runner-image move that made the cached binary unloadable would not be a - # one-off rebuild but a rebuild on EVERY run, because the fixed key could never be - # re-saved. A new release string is a new key. (Image-date tags are deliberately NOT in - # the key: they change weekly and would make the cache miss more than it hits.) - # A stale or foreign binary cannot be USED by accident either way: 03 runs the SAME - # capability probe on the restored copy and builds from source when it fails. Apple RIDs take - # glslc from Homebrew and the musl RIDs from apk, so neither builds it; the v2 cells drop - # Vulkan and never need it. Both are excluded so they do not create empty caches. - - name: Resolve the shaderc pin (glslc cache key) - id: shaderc - if: matrix.license_version == 3 && !startsWith(matrix.rid, 'osx-') && !startsWith(matrix.rid, 'ios-') && !startsWith(matrix.rid, 'maccatalyst-') && !startsWith(matrix.rid, 'linux-musl-') - shell: bash - env: - FFMPEG_VERSION: ${{ inputs.ffmpeg_version }} - run: | - set -euo pipefail - export ROOT_DIR="${PWD}" # the loader resolves the ledger relative to it - # shellcheck source=scripts/deps/lib.sh - . scripts/deps/lib.sh - tag="$(dep_version shaderc)" - case "${BUILD_RID}" in - # Built inside the manylinux container (see the Build step), not on this host. - linux-x64|linux-arm64) host="manylinux_2_28" ;; - # This step runs where the build runs: on the bare runner for win-*/android-*, inside - # the job container for linux-armhf. /etc/os-release names that environment. - *) host="$(. /etc/os-release && printf '%s-%s' "${ID}" "${VERSION_ID}")" ;; - esac - echo "glslc cache key: rid=${BUILD_RID} host=${host} shaderc=${tag} (FFmpeg ${FFMPEG_VERSION})" - { echo "tag=${tag}"; echo "host=${host}"; } >> "$GITHUB_OUTPUT" - - name: Cache the host glslc - if: steps.shaderc.outputs.tag != '' - uses: actions/cache@v6 - with: - path: .tools/glslc - key: glslc-v1-${{ matrix.rid }}-${{ steps.shaderc.outputs.host }}-${{ steps.shaderc.outputs.tag }} - - - name: Build FFmpeg - shell: bash - run: | - set -euo pipefail - if [[ "${BUILD_RID}" == android-* ]]; then - export ANDROID_NDK_HOME="${ANDROID_NDK_HOME:-$ANDROID_NDK_LATEST_HOME}" - echo "Using Android NDK: ${ANDROID_NDK_HOME}" - fi - mkdir -p "artifacts/${BUILD_RID}/logs" - { - if command -v gcc &>/dev/null; then - echo "gcc: $(gcc --version | head -1)" - fi - if command -v clang &>/dev/null; then - echo "clang: $(clang --version | head -1)" - fi - echo "nasm: $(nasm --version 2>/dev/null || echo 'not installed')" - echo "pkg-config: $(pkg-config --version 2>/dev/null || echo 'not installed')" - } > "artifacts/${BUILD_RID}/logs/toolchain.txt" - chmod +x scripts/build.sh - export FFMPEG_VERSION="${{ inputs.ffmpeg_version }}" - if [[ "${BUILD_RID}" == "linux-x64" || "${BUILD_RID}" == "linux-arm64" ]]; then - # Build in the STOCK upstream manylinux_2_28 image (glibc 2.28) for a low - # runtime floor. The image is pulled unmodified from quay.io/pypa — there is - # no custom image to maintain; 03_install_packages.sh provisions the - # toolchain inside it (triggered by BUILD_CONTAINER=manylinux). Artifacts - # land in the mounted workspace; the test/upload steps below run on the HOST - # against them — which also proves the low-floor binary runs on the runner's - # newer glibc. - # Pinned tag@digest (issue #26): the image IS the toolchain (gcc-toolset, glibc floor), - # so a floating ref changed binaries with no diff on our side. One literal ref per arch, - # not an interpolated name, so Renovate's image manager can match and bump each. - case "${BUILD_RID}" in - linux-x64) _img="quay.io/pypa/manylinux_2_28_x86_64:2026.09.30-1@sha256:c2261579b9c2e5d45aa93312f73e2a302182e3e977b558581a1838d6fed3d8e6" ;; - linux-arm64) _img="quay.io/pypa/manylinux_2_28_aarch64:2026.09.30-1@sha256:acc4e63610fef1da3d687322793665205415c2b22c0d2e403f1a44eb834d63fc" ;; - esac - # `docker run` pulls the image implicitly, and that pull is a NETWORK operation with no - # retry of any kind -- a registry blip takes the whole build down for a reason that is not - # our code, which is the failure class the curl/git wrappers exist to remove. Observed on - # this branch: "docker: Error response from daemon: received unexpected HTTP status: - # 502 Bad Gateway" pulling quay.io/pypa/manylinux_2_28_x86_64. - # - # Pull explicitly first, with the same exponential+jitter backoff scripts/lib.sh uses, so - # `docker run` below finds the image locally. Retrying the PULL rather than the `docker run` - # matters: re-running the run would repeat the entire build. - _delay=4 - for _try in 1 2 3 4 5 6; do - docker pull "${_img}" && break - if [ "${_try}" -eq 6 ]; then - echo "ERROR: docker pull ${_img} failed after 6 attempts" >&2; exit 1 - fi - _wait=$(( _delay + (RANDOM % 5) )) - echo " docker pull failed (attempt ${_try}/6) - retrying in ${_wait}s..." >&2 - sleep "${_wait}" - _delay=$(( _delay * 2 )) - done - docker run --rm -v "${PWD}:/work" -w /work \ - -e BUILD_RID -e BUILD_LICENSE -e BUILD_LICENSE_VERSION -e FFMPEG_VERSION -e BUILD_CONTAINER=manylinux \ - -e SOURCE_REPO_URL -e SOURCE_REPO_REF \ - "${_img}" \ - bash -c 'chmod +x scripts/build.sh && ./scripts/build.sh' \ - 2>&1 | tee "artifacts/${BUILD_RID}/logs/build.log" - # Container ran as root — hand the outputs back to the runner user so the - # host-side test/upload steps can read/clean them (.tools holds the cached glslc, - # which the actions/cache post-step reads back on the host). - sudo chown -R "$(id -u):$(id -g)" artifacts .build .tools 2>/dev/null || true - elif [[ "${BUILD_RID}" == "linux-musl-arm64" ]]; then - # Same reasoning as linux-x64/linux-arm64 above, but for musl: GitHub - # only supports JavaScript actions in Alpine containers on x64 runners, - # so this arm64 runner docker-runs the pinned Alpine image for the build itself - # rather than using `container:` on the job (which breaks actions/checkout - # here — see linux-musl-x64, which stays on `container:` because its - # x64 runner *is* supported). BUILD_CONTAINER is intentionally NOT set - # to manylinux — 03_install_packages.sh must still take its - # linux-musl-* apk branch inside this container. - # `docker run` pulls the image implicitly, and that pull is a NETWORK operation with no - # retry of any kind -- a registry blip takes the whole build down for a reason that is not - # our code, which is the failure class the curl/git wrappers exist to remove. Observed on - # this branch: "docker: Error response from daemon: received unexpected HTTP status: - # 502 Bad Gateway" pulling quay.io/pypa/manylinux_2_28_x86_64. - # - # Pull explicitly first, with the same exponential+jitter backoff scripts/lib.sh uses, so - # `docker run` below finds the image locally. Retrying the PULL rather than the `docker run` - # matters: re-running the run would repeat the entire build. - _img="alpine:3.24.2@sha256:294b683cb724975bec92580e1e685676bd4b50bda910ddb8c51d4cabeaec77e6" - _delay=4 - for _try in 1 2 3 4 5 6; do - docker pull "${_img}" && break - if [ "${_try}" -eq 6 ]; then - echo "ERROR: docker pull ${_img} failed after 6 attempts" >&2; exit 1 - fi - _wait=$(( _delay + (RANDOM % 5) )) - echo " docker pull failed (attempt ${_try}/6) - retrying in ${_wait}s..." >&2 - sleep "${_wait}" - _delay=$(( _delay * 2 )) - done - docker run --rm -v "${PWD}:/work" -w /work \ - -e BUILD_RID -e BUILD_LICENSE -e BUILD_LICENSE_VERSION -e FFMPEG_VERSION \ - -e SOURCE_REPO_URL -e SOURCE_REPO_REF \ - "${_img}" \ - sh -c 'apk add --no-cache bash git file jq && chmod +x scripts/build.sh && ./scripts/build.sh' \ - 2>&1 | tee "artifacts/${BUILD_RID}/logs/build.log" - # Container ran as root — hand the outputs back to the runner user so the - # host-side test/upload steps can read/clean them. - sudo chown -R "$(id -u):$(id -g)" artifacts .build .tools 2>/dev/null || true - else - ./scripts/build.sh 2>&1 | tee "artifacts/${BUILD_RID}/logs/build.log" - fi - - # Tests run in the separate test.yml workflow (chained after this one), which - # downloads the artifact uploaded below and runs the per-platform checks — - # keeping build and test decoupled so tests can grow / re-run independently. - - uses: actions/upload-artifact@v7 - with: - name: ${{ env.VARIANT }} - path: artifacts/${{ matrix.rid }}/native - if-no-files-found: error - # 5, not 1: the release workflow reuses these build artifacts in its publish jobs, and a - # full release run (80 build cells + tests, queuing on scarce macOS runners) can take - # ~24h end-to-end. At retention-days:1 the earliest-finishing artifacts (e.g. the lean - # ios-sim slice) expired before publish could download them → "Artifact not found". Five - # days gives comfortable margin over the longest observed run; they're throwaway either way. - retention-days: 5 - - # Issue #20: unstripped win-x64 binaries (ffmpeg_g.exe, ffprobe_g.exe, versioned DLLs) staged - # by 08_stage_artifacts.sh, for symbolizing a crash dump's module+offset frames. A separate - # artifact, never part of the shipped one; release.yml downloads build artifacts by exact name, - # so it cannot pick this up. Kept as long as GitHub allows, since it pairs with a release. - - uses: actions/upload-artifact@v7 - if: matrix.rid == 'win-x64' - with: - name: symbols-${{ env.VARIANT }} - path: artifacts/${{ matrix.rid }}/symbols - if-no-files-found: error - retention-days: 90 - - - uses: actions/upload-artifact@v7 - if: failure() - with: - name: ${{ env.VARIANT }}-diagnostics - path: | - artifacts/${{ matrix.rid }}/build-info.txt - artifacts/${{ matrix.rid }}/logs/ - .build/${{ matrix.rid }}/src/ffbuild/config.log - .build/${{ matrix.rid }}/src/ffbuild/config.mak - .build/${{ matrix.rid }}/libvpx/config.log - if-no-files-found: warn - retention-days: 1 - - # Gate job — single required status check for branch protection - all-builds: - if: always() - needs: build - runs-on: ubuntu-latest - steps: - - run: | - if [[ "${{ needs.build.result }}" != "success" ]]; then - echo "One or more build jobs failed" - exit 1 - fi diff --git a/.github/workflows/check-updates.yml b/.github/workflows/check-updates.yml deleted file mode 100644 index 18b7206..0000000 --- a/.github/workflows/check-updates.yml +++ /dev/null @@ -1,154 +0,0 @@ -name: Check for a new FFmpeg major line - -on: - schedule: - - cron: "0 6 * * 1" # Weekly, Monday 6am UTC (a new FFmpeg major is a rare event) - workflow_dispatch: - -permissions: - contents: write - pull-requests: write - -concurrency: - group: check-updates - cancel-in-progress: true - -jobs: - check: - runs-on: ubuntu-latest - env: - GH_TOKEN: ${{ secrets.UPDATE_PR_TOKEN }} - UPSTREAM: https://git.ffmpeg.org/ffmpeg.git - steps: - # actions/checkout has no retry input; its internal helper makes 3 attempts with a RANDOM - # 10-20s sleep between them, so roughly 20-40s of cover. A DNS or TLS blip longer than that - # kills the job before any of our code runs: - # fatal: unable to access 'https://github.com/...': Could not resolve host: github.com - # The action cannot be wrapped: a local composite action needs the repo ALREADY checked out, - # and retry actions only wrap `run:` steps, not `uses:` steps. So wait for the host to be - # reachable BEFORE checkout, with the same exponential-with-jitter backoff the build scripts - # use (4, 8, 16, 32, 64s + jitter), and do NOT sleep after the final attempt -- nothing probes - # again afterwards. Worst case is ~2 minutes of sleep plus the probe timeouts. - # This never fails the job. If the host is still unreachable it warns and lets checkout run, so - # the real error is reported by the action rather than masked here. - - name: Wait for github.com to be reachable - shell: bash - run: | - command -v curl >/dev/null 2>&1 || { echo "curl unavailable - skipping reachability wait"; exit 0; } - delay=4 - for i in 1 2 3 4 5 6; do - if curl -sSf -o /dev/null --max-time 10 "${GITHUB_SERVER_URL:-https://github.com}"; then - if [ "$i" -gt 1 ]; then echo "github.com reachable after attempt ${i}"; fi - exit 0 - fi - if [ "$i" -eq 6 ]; then break; fi - s=$(( delay + (RANDOM % 5) )) - echo "github.com not reachable (attempt ${i}/6) - retrying in ${s}s" >&2 - sleep "$s" - delay=$(( delay * 2 )) - done - echo "::warning::github.com still unreachable after 6 attempts; letting checkout try anyway" - - uses: actions/checkout@v7 - with: - persist-credentials: false - - # Point releases (a newer release within the major) are handled by Renovate now (grouped with the library - # bumps into one PR). This workflow does only what Renovate can't: when a newer FFmpeg - # MAJOR appears upstream than anything tracked, open a PR that ADDS it as a new parallel - # line in deps.json's .ffmpeg list. A new major is a flag you enhance (new sonames / configure flags / - # libraries worth enabling) before merge — its CI build is the check. Kept separate from - # the mechanical point/lib bumps that Renovate merges. - - name: Add a new FFmpeg major line if one appeared - run: | - # Retry the network git operations. These run in workflow `run:` steps, so the - # retrying git() wrapper in scripts/lib.sh does not apply -- and a push that fails on a - # transient blip is not cosmetic here: a release would be tagged locally but never - # published, or an update PR branch would be committed and never pushed. - git_net() { - local n=1 delay=4 wait - while :; do - git "$@" && return 0 - if [ "$n" -ge 5 ]; then - echo "::error::git $1 failed after $n attempts"; return 1 - fi - wait=$(( delay + (RANDOM % 5) )) - echo "git $1 failed (attempt $n/5) - retrying in ${wait}s" >&2 - sleep "$wait" - delay=$(( delay * 2 )); n=$(( n + 1 )) - done - } - set -euo pipefail - git config user.name "ffmpeg-update-bot" - git config user.email "ffmpeg-update-bot@users.noreply.github.com" - git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" - - # The maintained FFmpeg lines live in the ledger now (deps.json .ffmpeg). - mapfile -t TRACKED < <(jq -r '.ffmpeg[]' deps.json) - - # All upstream release tags (n), point releases only (no -rcN). - mapfile -t ALLTAGS < <(git_net ls-remote --tags "${UPSTREAM}" 'refs/tags/n*' \ - | grep -v '\^{}' | sed 's|.*refs/tags/n||' | grep -vi '-' | sort -V) - - # Append the library-coverage gap for a version to a PR body, so a bump - # surfaces any NEW external libraries FFmpeg gained (e.g. a codec added - # in the new release we might want to enable). Best-effort: never fails - # the bump if the coverage probe can't run. - coverage_note() { # $1 = version -> echoes a markdown section - local v="$1" out - if out="$(bash scripts/gen-coverage.sh "$v" 2>/dev/null)"; then - printf '\n\n---\n### Library coverage vs FFmpeg %s\n
Libraries FFmpeg %s supports that this build does not enable\n\n```\n%s\n```\n
\n\nThe coverage matrix in this PR was regenerated for this version — see the updated `docs/matrix/` files.' "$v" "$v" "$out" - fi - } - - open_pr() { # $1 = branch, $2 = commit/PR title, $3 = PR body - local branch="$1" title="$2" body="$3" - if git_net ls-remote --exit-code --heads origin "$branch" >/dev/null 2>&1; then - echo " branch $branch already exists — skipping" - return - fi - git checkout -B "$branch" origin/${GITHUB_REF_NAME:-main} - git add deps.json renovate.json - # Regenerate the coverage matrix so the PR is self-contained: a bump - # refreshes its major's matrix, and a new major adds a dedicated - # docs/matrix/ffmpeg-.md + updates the index. Needs network to - # fetch each version's configure; python3 + curl are on the runner. - if bash scripts/gen-matrix.sh; then - git add docs/matrix - else - echo " WARN: matrix regeneration failed — PR will not include it" >&2 - fi - git commit -m "$title" - git_net push -u origin "$branch" - gh pr create --title "$title" --body "$body" --base "${GITHUB_REF_NAME:-main}" --head "$branch" - git checkout -f "${GITHUB_REF_NAME:-main}" - } - - # Newer releases within a tracked major are handled by Renovate now (its deps.json .ffmpeg - # manager), grouped with the library bumps into one PR. This workflow only does what - # Renovate can't — compute the highest tracked major, then (below) add a NEW major as a - # parallel line when one appears upstream. - MAX_MAJOR=0 - for v in "${TRACKED[@]}"; do major="${v%%.*}"; (( major > MAX_MAJOR )) && MAX_MAJOR="$major"; done - - # New major line: the newest upstream release whose MAJOR is above everything tracked. - # A newer minor/patch of a major we already track (9.0.1 -> 9.0.2 or 9.1.0) is just a - # stability point in that series — Renovate bumps the existing line to it, so it is NOT a - # new line and never reaches here. - NEWEST="${ALLTAGS[-1]}" - NEW_MAJOR="${NEWEST%%.*}" - if (( NEW_MAJOR > MAX_MAJOR )); then - echo "New major available: ${NEWEST} (tracked max major ${MAX_MAJOR})" - git checkout -f "${GITHUB_REF_NAME:-main}" 2>/dev/null || true - # Add the new line to the ledger (.ffmpeg) AND its per-major Renovate rule, so once this - # PR merges Renovate keeps the new line current (any newer release within the major). - jq --arg v "${NEWEST}" '.ffmpeg += [$v]' deps.json > deps.tmp && mv deps.tmp deps.json - SERIES_RE="/^${NEW_MAJOR}\\./" - jq --arg re "${SERIES_RE}" \ - '.packageRules += [{"matchPackageNames":["https://github.com/FFmpeg/FFmpeg.git"],"matchCurrentVersion":$re,"allowedVersions":$re}]' \ - renovate.json > rn.tmp && mv rn.tmp renovate.json - open_pr "auto/ffmpeg-${NEWEST}" "Add FFmpeg ${NEWEST} (new major line)" \ - "Automated: FFmpeg ${NEWEST} is a new major series upstream. This PR adds it to the ledger (\`deps.json\` \`.ffmpeg\`) plus a per-major Renovate rule so newer releases within it are tracked from here on. Major bumps can change library sonames and configure flags, and a new major often supports new libraries worth enabling — treat this as a starting point: the CI build on this PR is the check, and you may extend it with new \`deps/\` + configure flags before merging. Existing lines keep releasing independently.$(coverage_note "${NEWEST}")" - git checkout -f deps.json renovate.json - fi - - echo "Done." diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d6e4700..f47b5e9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,229 +1,61 @@ +# The pull-request check: is ffmpeg-build.yml valid, does ffmpeg.lock cover it, can every target be planned? It builds +# nothing (the daily release builds and tests every target before it publishes, and keeps a release that fails a +# draft), so it takes a minute. It merges the lock updates (update-lock.yml) and Dependabot's PRs once it passes. +# `result` is the check the main ruleset requires. name: CI - -permissions: - contents: read - on: pull_request: - branches: - - main + workflow_dispatch: # update-lock.yml starts it on its PR's branch (GITHUB_TOKEN's pushes start nothing) +# a newer push to the same branch replaces the run under way concurrency: group: ci-${{ github.ref }} cancel-in-progress: true -jobs: - # Build/test only the versions this PR actually affects, so a PR doesn't rebuild - # every tracked FFmpeg version. Same diff logic as release.yml's prepare, so CI and - # release agree on what a change touches: - # - a build-recipe change (scripts/, except tests) → ALL tracked versions - # - only deps.json's .ffmpeg list → just the added/changed lines (an add-9 PR → only 9) - # - anything else (docs, etc.) → nothing - resolve: - runs-on: ubuntu-latest - outputs: - versions: ${{ steps.v.outputs.versions }} - any: ${{ steps.v.outputs.any }} - steps: - # actions/checkout has no retry input; its internal helper makes 3 attempts with a RANDOM - # 10-20s sleep between them, so roughly 20-40s of cover. A DNS or TLS blip longer than that - # kills the job before any of our code runs: - # fatal: unable to access 'https://github.com/...': Could not resolve host: github.com - # The action cannot be wrapped: a local composite action needs the repo ALREADY checked out, - # and retry actions only wrap `run:` steps, not `uses:` steps. So wait for the host to be - # reachable BEFORE checkout, with the same exponential-with-jitter backoff the build scripts - # use (4, 8, 16, 32, 64s + jitter), and do NOT sleep after the final attempt -- nothing probes - # again afterwards. Worst case is ~2 minutes of sleep plus the probe timeouts. - # This never fails the job. If the host is still unreachable it warns and lets checkout run, so - # the real error is reported by the action rather than masked here. - - name: Wait for github.com to be reachable - shell: bash - run: | - command -v curl >/dev/null 2>&1 || { echo "curl unavailable - skipping reachability wait"; exit 0; } - delay=4 - for i in 1 2 3 4 5 6; do - if curl -sSf -o /dev/null --max-time 10 "${GITHUB_SERVER_URL:-https://github.com}"; then - if [ "$i" -gt 1 ]; then echo "github.com reachable after attempt ${i}"; fi - exit 0 - fi - if [ "$i" -eq 6 ]; then break; fi - s=$(( delay + (RANDOM % 5) )) - echo "github.com not reachable (attempt ${i}/6) - retrying in ${s}s" >&2 - sleep "$s" - delay=$(( delay * 2 )) - done - echo "::warning::github.com still unreachable after 6 attempts; letting checkout try anyway" - - uses: actions/checkout@v7 - with: - fetch-depth: 0 # need the base commit to diff the PR against - - id: v - env: - BASE_SHA: ${{ github.event.pull_request.base.sha }} - run: | - set -euo pipefail - mapfile -t TRACKED < <(jq -r '.ffmpeg[]' deps.json) - echo "Changed vs base:"; git diff --name-only "${BASE_SHA}" HEAD || true - # Which lines this PR affects (shared with release.yml via select-versions.sh): - # build-recipe change (scripts/**, non-test) -> all lines - # deps.json bump -> only lines whose RESOLVED deps changed (a line that whole-line- - # pins the bumped dep is skipped — it wasn't affected) - # deps.json's .ffmpeg list -> the added/changed version lines - mapfile -t SEL < <(bash scripts/ci/select-versions.sh "${BASE_SHA}" "${TRACKED[@]}") - echo "Selected versions: ${SEL[*]:-none}" - - VERSIONS='[]' - for v in "${SEL[@]:-}"; do - [[ -z "$v" ]] && continue - VERSIONS=$(jq -c --arg v "$v" '. + [$v]' <<< "$VERSIONS") - done - ANY=$([[ "$(jq 'length' <<< "$VERSIONS")" -gt 0 ]] && echo true || echo false) - { - echo "versions=${VERSIONS}" - echo "any=${ANY}" - } >> "$GITHUB_OUTPUT" - echo "Building: ${VERSIONS}" - - # Keep the committed build-coverage matrices (docs/matrix/) in lockstep with what we - # actually build. They are generated from FFmpeg's configure + the build scripts + the - # dependency ledger (deps.json), so a DEP BUMP, a deps.json's .ffmpeg list change, or a build-script - # edit must regenerate them — not just an FFmpeg change. This job regenerates and fails if - # the committed files drifted; the fix is `bash scripts/gen-matrix.sh` + commit. Cheap - # (~1 min), so it runs on every PR. SELECT THIS as a required check alongside build/test. - docs-matrix: - runs-on: ubuntu-latest # ANDROID_NDK_LATEST_HOME is preinstalled here (the android sim needs it) - steps: - # actions/checkout has no retry input; its internal helper makes 3 attempts with a RANDOM - # 10-20s sleep between them, so roughly 20-40s of cover. A DNS or TLS blip longer than that - # kills the job before any of our code runs: - # fatal: unable to access 'https://github.com/...': Could not resolve host: github.com - # The action cannot be wrapped: a local composite action needs the repo ALREADY checked out, - # and retry actions only wrap `run:` steps, not `uses:` steps. So wait for the host to be - # reachable BEFORE checkout, with the same exponential-with-jitter backoff the build scripts - # use (4, 8, 16, 32, 64s + jitter), and do NOT sleep after the final attempt -- nothing probes - # again afterwards. Worst case is ~2 minutes of sleep plus the probe timeouts. - # This never fails the job. If the host is still unreachable it warns and lets checkout run, so - # the real error is reported by the action rather than masked here. - - name: Wait for github.com to be reachable - shell: bash - run: | - command -v curl >/dev/null 2>&1 || { echo "curl unavailable - skipping reachability wait"; exit 0; } - delay=4 - for i in 1 2 3 4 5 6; do - if curl -sSf -o /dev/null --max-time 10 "${GITHUB_SERVER_URL:-https://github.com}"; then - if [ "$i" -gt 1 ]; then echo "github.com reachable after attempt ${i}"; fi - exit 0 - fi - if [ "$i" -eq 6 ]; then break; fi - s=$(( delay + (RANDOM % 5) )) - echo "github.com not reachable (attempt ${i}/6) - retrying in ${s}s" >&2 - sleep "$s" - delay=$(( delay * 2 )) - done - echo "::warning::github.com still unreachable after 6 attempts; letting checkout try anyway" - - uses: actions/checkout@v7 - - name: Regenerate coverage matrices and fail on drift - run: | - set -euo pipefail - bash scripts/gen-matrix.sh - if ! git diff --quiet -- docs/matrix; then - echo "::error::docs/matrix is stale — run 'bash scripts/gen-matrix.sh' and commit the result (a dependency bump in deps.json changes these files too)." - git diff --stat -- docs/matrix - git --no-pager diff -- docs/matrix | head -300 - exit 1 - fi - echo "Coverage matrices are up to date." - - # The matrix-caller jobs (one reusable-workflow call, fanned out per version × RID × - # license). Their individual matrix checks surface as "build-matrix / …", "test-matrix / …" - # — you do NOT select those in branch protection; select the aggregate `build`/`test` gates - # below, which reflect the whole matrix in one check each. - build-matrix: - # docs-matrix is ~1 minute and build-matrix is hours; gating on it means a stale - # coverage matrix fails fast instead of after the whole fan-out has run. - needs: [resolve, docs-matrix] - if: needs.resolve.outputs.any == 'true' - strategy: - fail-fast: false - matrix: - version: ${{ fromJson(needs.resolve.outputs.versions) }} - uses: ./.github/workflows/build.yml - with: - ffmpeg_version: ${{ matrix.version }} - fail_fast: false - - # Tests run separately, after the build, against its uploaded artifacts. Desktop and - # mobile are split so mobile's slow emulator/simulator setup doesn't gate or - # destabilise the fast desktop execution checks. - test-matrix: - needs: [resolve, build-matrix] - if: needs.resolve.outputs.any == 'true' - strategy: - fail-fast: false - matrix: - version: ${{ fromJson(needs.resolve.outputs.versions) }} - uses: ./.github/workflows/test.yml - with: - ffmpeg_version: ${{ matrix.version }} - fail_fast: false - - test-mobile-matrix: - needs: [resolve, build-matrix] - if: needs.resolve.outputs.any == 'true' - strategy: - fail-fast: false - matrix: - version: ${{ fromJson(needs.resolve.outputs.versions) }} - uses: ./.github/workflows/test-mobile.yml - with: - ffmpeg_version: ${{ matrix.version }} - fail_fast: false +permissions: {} - # ── Aggregate required status checks ────────────────────────────────────── - # SELECT THESE TWO ("build" and "test") as the required checks in the branch ruleset — - # NOT the ~100 individual matrix jobs. Each reflects its whole matrix: green when every - # matrix job passed OR was skipped (a docs-only PR builds/tests nothing), red on any real - # failure/cancellation. `test` covers both desktop AND mobile. Select BOTH: `test` is - # green-when-skipped, so if a build fails, `build` (also required) is what blocks the merge. - build: +jobs: + check: + uses: devenvy/ffmpeg-build/.github/workflows/check.yml@52201a1204772caf79156ced0954c25407f6b433 # v0.0.5 + permissions: + contents: read + # one check for the main ruleset to require, whatever ran + result: + needs: check if: always() - needs: [resolve, build-matrix] - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 + timeout-minutes: 5 + permissions: {} steps: - - run: | - r="${{ needs.build-matrix.result }}" - if [[ "$r" == "failure" || "$r" == "cancelled" ]]; then - echo "build failed (matrix result: $r)"; exit 1 - fi - # A skip has two very different causes and only one of them deserves a green: - # resolve said any=false -> nothing to build, correctly passes - # a NEEDED job failed (docs-matrix) -> GitHub skips this matrix whatever its `if:` says - # Without this branch the second case printed "build passed (matrix result: skipped)" - # over a fan-out that never ran -- observed on PR #31, which reported build green with - # zero artifacts built. Safe today only because docs-matrix is itself a required check; - # this makes the roll-up true on its own terms rather than by depending on that. - if [[ "$r" == "skipped" && "${{ needs.resolve.outputs.any }}" == "true" ]]; then - echo "build-matrix was SKIPPED even though resolve selected versions" \ - "${{ needs.resolve.outputs.versions }} - an upstream job it needs must have failed." \ - "Nothing was built, so this cannot pass."; exit 1 - fi - echo "build passed (matrix result: $r)" - - test: - if: always() - needs: [resolve, test-matrix, test-mobile-matrix] - runs-on: ubuntu-latest + - name: the check passed + env: + CHECK: ${{ needs.check.result }} + run: test "${CHECK}" = success + merge: + needs: result + uses: devenvy/ffmpeg-build/.github/workflows/automerge.yml@52201a1204772caf79156ced0954c25407f6b433 # v0.0.5 + permissions: + contents: write + pull-requests: write + + # Dependabot's PRs merge themselves once the required check passes, as devenvy-bot (org variable + # DEVENVY_BOT_CLIENT_ID, org secret DEVENVY_BOT_PRIVATE_KEY, both also Dependabot secrets). + dependabot-auto-merge: + if: github.event_name == 'pull_request' && github.event.pull_request.user.login == 'dependabot[bot]' + runs-on: ubuntu-24.04 + timeout-minutes: 5 + permissions: {} steps: - - run: | - for r in "${{ needs.test-matrix.result }}" "${{ needs.test-mobile-matrix.result }}"; do - if [[ "$r" == "failure" || "$r" == "cancelled" ]]; then - echo "test failed (a desktop/mobile test matrix did not pass: $r)"; exit 1 - fi - # Same reasoning as the build roll-up: skipped-because-nothing-to-do passes, - # skipped-because-an-upstream-job-failed must not. - if [[ "$r" == "skipped" && "${{ needs.resolve.outputs.any }}" == "true" ]]; then - echo "a test matrix was SKIPPED even though resolve selected versions" \ - "${{ needs.resolve.outputs.versions }} - an upstream job it needs must have" \ - "failed. Nothing was tested, so this cannot pass."; exit 1 - fi - done - echo "test passed (desktop + mobile)" + - id: app-token + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 + with: + client-id: ${{ secrets.DEVENVY_BOT_CLIENT_ID }} + private-key: ${{ secrets.DEVENVY_BOT_PRIVATE_KEY }} + # enabling auto-merge + permission-contents: write + permission-pull-requests: write + - name: Enable auto-merge + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + PR_URL: ${{ github.event.pull_request.html_url }} + run: gh pr merge "$PR_URL" --auto --squash diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 95eca96..51df4f5 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,26 +1,16 @@ +# CodeQL on what this repository holds: its workflows (FFmpeg and the libraries are built by ffmpeg-build from +# upstream sources, which aren't kept here). The security-and-quality queries, on every pull request, on main and +# weekly for newly published queries. Results go to the Security tab; the main ruleset requires them. name: CodeQL - -# Security/quality analysis of the code WE own. This repo is a builder of stock -# upstream FFmpeg + libraries — it vendors no upstream source, so there is nothing -# upstream for CodeQL to (mis)attribute to us: -# - c-cpp runs in build-mode: none → it scans the C committed to the repo -# (scripts/test/smoke.c and any future test programs) WITHOUT building, so -# upstream is never cloned or analyzed and no build minutes are spent. -# - actions scans our workflow YAML (e.g. script-injection in inline `run:` steps). -# NOTE: CodeQL has no shell/bash analyzer — the bash scripts are covered separately -# by the ShellCheck workflow. - on: push: branches: [main] pull_request: branches: [main] schedule: - - cron: '23 4 * * 1' # weekly (Mon 04:23 UTC), catches newly-published queries + - cron: '23 4 * * 1' -permissions: - contents: read - security-events: write # required to upload results to the Security tab +permissions: {} concurrency: group: codeql-${{ github.ref }} @@ -29,50 +19,24 @@ concurrency: jobs: analyze: name: Analyze (${{ matrix.language }}) - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 + timeout-minutes: 15 + permissions: + contents: read + security-events: write # uploads the results strategy: fail-fast: false matrix: - include: - - language: c-cpp - build-mode: none - - language: actions - build-mode: none + language: [actions] steps: - # actions/checkout has no retry input; its internal helper makes 3 attempts with a RANDOM - # 10-20s sleep between them, so roughly 20-40s of cover. A DNS or TLS blip longer than that - # kills the job before any of our code runs: - # fatal: unable to access 'https://github.com/...': Could not resolve host: github.com - # The action cannot be wrapped: a local composite action needs the repo ALREADY checked out, - # and retry actions only wrap `run:` steps, not `uses:` steps. So wait for the host to be - # reachable BEFORE checkout, with the same exponential-with-jitter backoff the build scripts - # use (4, 8, 16, 32, 64s + jitter), and do NOT sleep after the final attempt -- nothing probes - # again afterwards. Worst case is ~2 minutes of sleep plus the probe timeouts. - # This never fails the job. If the host is still unreachable it warns and lets checkout run, so - # the real error is reported by the action rather than masked here. - - name: Wait for github.com to be reachable - shell: bash - run: | - command -v curl >/dev/null 2>&1 || { echo "curl unavailable - skipping reachability wait"; exit 0; } - delay=4 - for i in 1 2 3 4 5 6; do - if curl -sSf -o /dev/null --max-time 10 "${GITHUB_SERVER_URL:-https://github.com}"; then - if [ "$i" -gt 1 ]; then echo "github.com reachable after attempt ${i}"; fi - exit 0 - fi - if [ "$i" -eq 6 ]; then break; fi - s=$(( delay + (RANDOM % 5) )) - echo "github.com not reachable (attempt ${i}/6) - retrying in ${s}s" >&2 - sleep "$s" - delay=$(( delay * 2 )) - done - echo "::warning::github.com still unreachable after 6 attempts; letting checkout try anyway" - - uses: actions/checkout@v7 - - uses: github/codeql-action/init@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: github/codeql-action/init@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3 with: languages: ${{ matrix.language }} - build-mode: ${{ matrix.build-mode }} - config-file: ./.github/codeql/codeql-config.yml - - uses: github/codeql-action/analyze@v4 + build-mode: none + queries: security-and-quality + - uses: github/codeql-action/analyze@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3 with: - category: "/language:${{ matrix.language }}" + category: /language:${{ matrix.language }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 816825e..f992bf2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,673 +1,19 @@ +# The daily release: publishes every release whose builds changed since it was last published (a merged lock update, +# a new FFmpeg release, a new engine). Back-to-back merges cost one release; a failed day is retried the next. +# +# Permissions: contents: write (below), to create the GitHub releases. name: Release - -permissions: - contents: write - on: - push: - branches: - - main - paths: - - deps.json # the ledger — FFmpeg version bumps (.ffmpeg) AND library bumps (incl. merged Renovate PRs) - - 'scripts/**' # a build-recipe/logic change (incl. a dep build-SCRIPT fix) → all lines - - '!scripts/test/**' # ...except test-only changes, which don't affect artifacts - # ...and except the CI validators, for the same reason. Narrow on purpose: scripts/ci also - # holds gen-manifest.sh, select-versions.sh and impacted-versions.sh, which the release DOES - # run, so only the *-test.sh validators are excluded. Without this, editing a test that - # merely reads a config rebuilds 15 RIDs x 4 cells x 2 FFmpeg lines for no artifact change. - - '!scripts/ci/*-test.sh' - # The pinned build/test container images ARE the toolchain (issue #26), so a merged - # Renovate image bump must reach select-versions.sh. It selects every line only when a - # changed line carries an `@sha256:` image ref; any other edit to these files selects none. - - '.github/workflows/build.yml' - - '.github/workflows/test.yml' + schedule: + - cron: '17 7 * * *' workflow_dispatch: - inputs: - versions: - description: "Space-separated versions to (re)build, or 'all'. Default: all tracked." - required: false - default: "all" -concurrency: - group: release - cancel-in-progress: false # never cancel a release mid-flight +permissions: {} jobs: - # Decide which version lines to (re)build this run, and compute each one's - # next {version}.{build} tag. A push that only edits deps.json's .ffmpeg list builds just - # the added/changed lines; a scripts/build.sh change (or a manual run) rebuilds - # every tracked line. - prepare: - runs-on: ubuntu-latest - outputs: - builds: ${{ steps.plan.outputs.builds }} # JSON: [{version, tag}] - versions: ${{ steps.plan.outputs.versions }} # JSON: [version] - any: ${{ steps.plan.outputs.any }} - steps: - # actions/checkout has no retry input; its internal helper makes 3 attempts with a RANDOM - # 10-20s sleep between them, so roughly 20-40s of cover. A DNS or TLS blip longer than that - # kills the job before any of our code runs: - # fatal: unable to access 'https://github.com/...': Could not resolve host: github.com - # The action cannot be wrapped: a local composite action needs the repo ALREADY checked out, - # and retry actions only wrap `run:` steps, not `uses:` steps. So wait for the host to be - # reachable BEFORE checkout, with the same exponential-with-jitter backoff the build scripts - # use (4, 8, 16, 32, 64s + jitter), and do NOT sleep after the final attempt -- nothing probes - # again afterwards. Worst case is ~2 minutes of sleep plus the probe timeouts. - # This never fails the job. If the host is still unreachable it warns and lets checkout run, so - # the real error is reported by the action rather than masked here. - - name: Wait for github.com to be reachable - shell: bash - run: | - command -v curl >/dev/null 2>&1 || { echo "curl unavailable - skipping reachability wait"; exit 0; } - delay=4 - for i in 1 2 3 4 5 6; do - if curl -sSf -o /dev/null --max-time 10 "${GITHUB_SERVER_URL:-https://github.com}"; then - if [ "$i" -gt 1 ]; then echo "github.com reachable after attempt ${i}"; fi - exit 0 - fi - if [ "$i" -eq 6 ]; then break; fi - s=$(( delay + (RANDOM % 5) )) - echo "github.com not reachable (attempt ${i}/6) - retrying in ${s}s" >&2 - sleep "$s" - delay=$(( delay * 2 )) - done - echo "::warning::github.com still unreachable after 6 attempts; letting checkout try anyway" - - uses: actions/checkout@v7 - with: - fetch-depth: 0 # full history for tag lookup - - - id: plan - env: - EVENT: ${{ github.event_name }} - DISPATCH_VERSIONS: ${{ inputs.versions }} - BEFORE: ${{ github.event.before }} - run: | - set -euo pipefail - mapfile -t TRACKED < <(jq -r '.ffmpeg[]' deps.json) - - BUILD_ALL=false - SEL=() - if [[ "${EVENT}" == "workflow_dispatch" ]]; then - if [[ -z "${DISPATCH_VERSIONS}" || "${DISPATCH_VERSIONS}" == "all" ]]; then - BUILD_ALL=true - else - read -ra SEL <<< "${DISPATCH_VERSIONS}" - fi - else - # A push to main: build + release only the lines this change actually affects (shared - # with ci.yml via scripts/ci/select-versions.sh) — a build-recipe change (scripts/**, - # non-test) -> all lines; a deps.json bump -> only lines whose RESOLVED deps changed - # (a line that whole-line-pins the bumped dep is NOT re-released); a deps.json's .ffmpeg list change - # -> the added/changed lines. First push / unknown base -> all (the script can't diff). - mapfile -t SEL < <(bash scripts/ci/select-versions.sh "${BEFORE}" "${TRACKED[@]}") - fi - $BUILD_ALL && SEL=("${TRACKED[@]}") - - BUILDS='[]'; VERSIONS='[]' - for v in "${SEL[@]:-}"; do - [[ -z "$v" ]] && continue - IFS='.' read -ra P <<< "$v" - while [[ ${#P[@]} -lt 3 ]]; do P+=("0"); done - BASE="${P[0]}.${P[1]}.${P[2]}" - LAST=$(git tag --list "${BASE}.*" --sort=-v:refname | head -1) - if [[ -n "$LAST" ]]; then NEXT=$(( ${LAST##*.} + 1 )); else NEXT=0; fi - TAG="${BASE}.${NEXT}" - BUILDS=$(jq -c --arg v "$v" --arg t "$TAG" '. + [{version:$v, tag:$t}]' <<< "$BUILDS") - VERSIONS=$(jq -c --arg v "$v" '. + [$v]' <<< "$VERSIONS") - echo "Will build ${v} -> ${TAG}" - done - ANY=$([[ $(jq 'length' <<< "$VERSIONS") -gt 0 ]] && echo true || echo false) - { - echo "builds=${BUILDS}" - echo "versions=${VERSIONS}" - echo "any=${ANY}" - } >> "$GITHUB_OUTPUT" - - build: - needs: prepare - if: needs.prepare.outputs.any == 'true' - strategy: - fail-fast: false - matrix: - version: ${{ fromJson(needs.prepare.outputs.versions) }} - uses: ./.github/workflows/build.yml - with: - ffmpeg_version: ${{ matrix.version }} - - # Tests gate the release: a failing test blocks the tag/publish below. Desktop and - # mobile are separate workflows (mobile's emulator/simulator setup is isolated). - test: - needs: [prepare, build] - if: needs.prepare.outputs.any == 'true' - strategy: - fail-fast: false - matrix: - version: ${{ fromJson(needs.prepare.outputs.versions) }} - uses: ./.github/workflows/test.yml - with: - ffmpeg_version: ${{ matrix.version }} - - test-mobile: - needs: [prepare, build] - if: needs.prepare.outputs.any == 'true' - strategy: - fail-fast: false - matrix: - version: ${{ fromJson(needs.prepare.outputs.versions) }} - uses: ./.github/workflows/test-mobile.yml - with: - ffmpeg_version: ${{ matrix.version }} - - # One tag + GitHub Release per version line. release: - needs: [prepare, build, test, test-mobile] - runs-on: ubuntu-latest - strategy: - fail-fast: false # create every line's release even if a sibling fails - matrix: - build: ${{ fromJson(needs.prepare.outputs.builds) }} - steps: - # actions/checkout has no retry input; its internal helper makes 3 attempts with a RANDOM - # 10-20s sleep between them, so roughly 20-40s of cover. A DNS or TLS blip longer than that - # kills the job before any of our code runs: - # fatal: unable to access 'https://github.com/...': Could not resolve host: github.com - # The action cannot be wrapped: a local composite action needs the repo ALREADY checked out, - # and retry actions only wrap `run:` steps, not `uses:` steps. So wait for the host to be - # reachable BEFORE checkout, with the same exponential-with-jitter backoff the build scripts - # use (4, 8, 16, 32, 64s + jitter), and do NOT sleep after the final attempt -- nothing probes - # again afterwards. Worst case is ~2 minutes of sleep plus the probe timeouts. - # This never fails the job. If the host is still unreachable it warns and lets checkout run, so - # the real error is reported by the action rather than masked here. - - name: Wait for github.com to be reachable - shell: bash - run: | - command -v curl >/dev/null 2>&1 || { echo "curl unavailable - skipping reachability wait"; exit 0; } - delay=4 - for i in 1 2 3 4 5 6; do - if curl -sSf -o /dev/null --max-time 10 "${GITHUB_SERVER_URL:-https://github.com}"; then - if [ "$i" -gt 1 ]; then echo "github.com reachable after attempt ${i}"; fi - exit 0 - fi - if [ "$i" -eq 6 ]; then break; fi - s=$(( delay + (RANDOM % 5) )) - echo "github.com not reachable (attempt ${i}/6) - retrying in ${s}s" >&2 - sleep "$s" - delay=$(( delay * 2 )) - done - echo "::warning::github.com still unreachable after 6 attempts; letting checkout try anyway" - - uses: actions/checkout@v7 - with: - fetch-depth: 0 - - name: Create tag and release - env: - GH_TOKEN: ${{ github.token }} - run: | - VERSION="${{ matrix.build.version }}" - TAG="${{ matrix.build.tag }}" - # Only the HIGHEST tracked version line gets GitHub's "Latest" badge. A - # maintenance release on an older line (e.g. 8.1.3 published after 9.0 already - # exists) must NOT become "Latest" — otherwise it steals the badge from the - # newest major. GitHub's default (--latest omitted) would mis-assign this by - # recency, so we set it explicitly per release. - HIGHEST="$(jq -r '.ffmpeg[]' deps.json | sort -V | tail -1)" - if [[ "${VERSION}" == "${HIGHEST}" ]]; then MARK_LATEST=true; else MARK_LATEST=false; fi - echo "Highest tracked line: ${HIGHEST} — mark ${VERSION} as latest: ${MARK_LATEST}" - # Retry the network git operations. These run in workflow `run:` steps, so the - # retrying git() wrapper in scripts/lib.sh does not apply -- and a push that fails on a - # transient blip is not cosmetic here: a release would be tagged locally but never - # published, or an update PR branch would be committed and never pushed. - git_net() { - local n=1 delay=4 wait - while :; do - git "$@" && return 0 - if [ "$n" -ge 5 ]; then - echo "::error::git $1 failed after $n attempts"; return 1 - fi - wait=$(( delay + (RANDOM % 5) )) - echo "git $1 failed (attempt $n/5) - retrying in ${wait}s" >&2 - sleep "$wait" - delay=$(( delay * 2 )); n=$(( n + 1 )) - done - } - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git tag "${TAG}" - git_net push origin "${TAG}" - # Created as a DRAFT and published by the `finalize` job once every asset AND the SHA256SUMS - # manifest are in place. Previously it went public immediately with the assets uploading - # afterwards, so any upload failure left a PUBLIC release -- possibly flagged `latest` -- - # missing artifacts or its checksums, which consumers would then fetch. A draft is invisible - # until complete, and if a later job fails it simply stays a draft for a human to inspect. - # --latest moves to finalize as well: it is meaningless on a draft. - gh release create "${TAG}" \ - --title "FFmpeg ${VERSION} (build ${TAG##*.})" \ - --generate-notes \ - --draft - echo "${MARK_LATEST}" > mark-latest.txt - - publish: - needs: [prepare, build, test, test-mobile, release] - runs-on: ubuntu-latest - permissions: - contents: write - strategy: - fail-fast: false # one cell's failure must NOT cancel the rest — a partial release beats - # an empty one, and a real bug then shows in every affected cell, not just - # the first to hit it (which is what masked the relink_so bug as 2 failures). - matrix: - build: ${{ fromJson(needs.prepare.outputs.builds) }} - rid: [linux-x64, linux-arm64, linux-armhf, linux-musl-x64, linux-musl-arm64, win-x64, win-arm64, osx-x64, osx-arm64, android-arm64, android-x64] - license: [lgpl, gpl] - license_version: [3, 2] # → license token {license}v{series}: lgplv3/gplv3/lgplv2/gplv2 - steps: - - uses: actions/download-artifact@v8 - with: - name: ${{ matrix.build.version }}-${{ matrix.rid }}-${{ matrix.license }}v${{ matrix.license_version }} - path: artifacts/${{ matrix.rid }}-${{ matrix.license }}v${{ matrix.license_version }} - - - name: Create release tarballs (runtime + optional dev) - run: | - VERSION="${{ matrix.build.version }}" - VARIANT="${{ matrix.rid }}-${{ matrix.license }}v${{ matrix.license_version }}" - SRC="artifacts/${VARIANT}" - RUN="/tmp/run"; DEV="/tmp/dev" - rm -rf "${RUN}" "${DEV}" && mkdir -p "${RUN}" - # actions/upload-artifact dereferences symlinks, so the downloaded lib set has the - # SONAME/linker aliases as full COPIES (3x per .so, 2x per .dylib) — a ~3x-bloated - # tarball. Collapse each group back to one real file (the fullest-versioned) + relative - # symlinks, restoring the standard layout the loader expects (ffmpeg's NEEDED is the - # SONAME). Run inside the target dir. - relink_so() { # ELF: libfoo.so, libfoo.so.MAJOR, libfoo.so.MAJOR.MINOR.MICRO - local link stem f full - for link in *.so; do - [ -e "$link" ] || continue - stem="${link%.so}"; full="" - for f in "${stem}".so.*; do [ -e "$f" ] || continue; { [ -z "$full" ] || [ "${#f}" -gt "${#full}" ]; } && full="$f"; done - [ -n "$full" ] || continue - for f in "$link" "${stem}".so.*; do [ -e "$f" ] && [ "$f" != "$full" ] && ln -sf "$full" "$f"; done - done - return 0 # the final loop's last test ([ "$f" != "$full" ]) is falsy → without this - # the function returns 1 and `set -e` (bash -e) kills the step silently. - } - relink_dylib() { # Mach-O: libfoo.dylib, libfoo.MAJOR.dylib, libfoo.MAJOR.MINOR.MICRO.dylib - # Mirror relink_so: collapse the WHOLE group to one real file plus symlinks. The previous - # version linked only the bare libfoo.dylib, so libfoo.MAJOR.dylib stayed a second full - # copy — upload-artifact dereferences symlinks, so it survived as real bytes. That is why - # macOS shipped 16 real files where Linux shipped 9, carrying tens of MB of duplicate - # payload per tarball. - local f base full link bases="" - for f in *.dylib; do - [ -e "$f" ] || continue - base="${f%%.*}" # libavcodec.63.1.101.dylib -> libavcodec - case " $bases " in *" $base "*) ;; *) bases="$bases $base" ;; esac - done - for base in $bases; do - full="" - for f in "$base".*.dylib; do # versioned candidates only - [ -e "$f" ] || continue - [ -L "$f" ] && continue # a real file, not an alias - if [ -z "$full" ] || [ "${#f}" -gt "${#full}" ]; then full="$f"; fi - done - [ -n "$full" ] || continue - for link in "$base.dylib" "$base".*.dylib; do - [ -e "$link" ] || continue - [ "$link" = "$full" ] && continue - ln -sf "$full" "$link" - done - done - return 0 # trailing tests can be falsy; the same set -e trap relink_so documents. - } - # Runtime tarball = binaries + shared libraries + legal ONLY. Dev files - # (headers, and Windows import libs) go in a separate -dev tarball so the - # runtime download stays lean. Android/iOS are link-only artifacts and - # keep their headers in the main tarball (handled below / in publish-ios). - case "${VARIANT}" in - win-*) - cp "${SRC}"/*.dll "${SRC}"/*.exe "${RUN}/" - mkdir -p "${DEV}/include" "${DEV}/lib" - cp -r "${SRC}/include/." "${DEV}/include/" - cp -r "${SRC}/lib/." "${DEV}/lib/" # MSVC .lib import libraries - ;; - osx-*) - cp "${SRC}"/*.dylib "${SRC}/ffmpeg" "${SRC}/ffprobe" "${RUN}/" - # MoltenVK_icd.json is staged by 08_stage_artifacts.sh and docs/install/macos.md tells - # users to point VK_ICD_FILENAMES at it, but it was never copied into the runtime - # tarball -- the documented Vulkan setup was impossible with what actually shipped. - if [ -f "${SRC}/MoltenVK_icd.json" ]; then cp "${SRC}/MoltenVK_icd.json" "${RUN}/"; fi - ( cd "${RUN}" && relink_dylib ) - mkdir -p "${DEV}/include"; cp -r "${SRC}/include/." "${DEV}/include/" - # pkg-config files are the standard integration path and belong with the headers. - if [ -d "${SRC}/lib/pkgconfig" ]; then mkdir -p "${DEV}/lib"; cp -r "${SRC}/lib/pkgconfig" "${DEV}/lib/"; fi - ;; - android-*) - # Link-only: headers + libs belong together, no runtime/dev split. - mkdir -p "${RUN}/include" "${RUN}/lib" - cp -r "${SRC}/include/." "${RUN}/include/" - cp -r "${SRC}/lib/." "${RUN}/lib/" - ;; - *) # linux-* - cp "${SRC}"/*.so* "${SRC}/ffmpeg" "${SRC}/ffprobe" "${RUN}/" - ( cd "${RUN}" && relink_so ) - mkdir -p "${DEV}/include"; cp -r "${SRC}/include/." "${DEV}/include/" - # pkg-config files are the standard integration path and belong with the headers. - if [ -d "${SRC}/lib/pkgconfig" ]; then mkdir -p "${DEV}/lib"; cp -r "${SRC}/lib/pkgconfig" "${DEV}/lib/"; fi - ;; - esac - if [ -d "${SRC}/legal" ]; then - cp -r "${SRC}/legal" "${RUN}/legal" - [ -d "${DEV}" ] && [ -n "$(ls -A "${DEV}" 2>/dev/null)" ] && cp -r "${SRC}/legal" "${DEV}/legal" - fi - # actions/upload-artifact does NOT preserve the executable bit, so the downloaded tree - # has ffmpeg/ffprobe at 0644. test.yml re-chmods before testing, which hid this; the - # release step did not, so every published Linux/macOS tarball shipped a CLI the user - # could not run ("Permission denied", exit 126). Restore it before packaging. - case "${VARIANT}" in - win-*|android-*|ios-*) ;; - *) for _b in ffmpeg ffprobe; do if [ -f "${RUN}/${_b}" ]; then chmod 0755 "${RUN}/${_b}"; fi; done ;; - esac - tar -czf "ffmpeg-${VERSION}-${VARIANT}.tar.gz" -C "${RUN}" . - - # Verify the ARCHIVE, not the staging tree. Every other check in CI inspects the - # pre-release native/ directory, so a defect introduced by packaging itself -- a lost - # permission bit, a file that never got copied -- reaches users unseen. - case "${VARIANT}" in - win-*|android-*|ios-*) ;; - *) - _v="$(mktemp -d)"; tar -xzf "ffmpeg-${VERSION}-${VARIANT}.tar.gz" -C "${_v}" - for _b in ffmpeg ffprobe; do - [ -x "${_v}/${_b}" ] || { echo "ERROR: ${_b} not executable inside ffmpeg-${VERSION}-${VARIANT}.tar.gz" >&2; exit 1; } - done - if [ "${VARIANT#osx-}" != "${VARIANT}" ] && [ -f "${SRC}/MoltenVK_icd.json" ] && [ ! -f "${_v}/MoltenVK_icd.json" ]; then - echo "ERROR: MoltenVK_icd.json was staged but is missing from the tarball" >&2; exit 1 - fi - # RUN it. Every other check inspects the artifact; this one uses it the way a user will, - # and is the single test that would have caught the three defects that actually shipped: - # a non-executable CLI, macOS binaries loading siblings by absolute build path, and an - # Intel-runner Homebrew dylib leaking into the link. Runs only where the archive is - # native to the runner -- a cross-built RID cannot execute here, and is covered by the - # test-matrix under qemu/wine instead. - _host="$(uname -s)-$(uname -m)" - _native="" - case "${VARIANT}:${_host}" in - linux-x64-*:Linux-x86_64) _native=1 ;; - linux-arm64-*:Linux-aarch64) _native=1 ;; - osx-x64-*:Darwin-x86_64) _native=1 ;; - osx-arm64-*:Darwin-arm64) _native=1 ;; - esac - if [ -n "${_native}" ]; then - _r="$(mktemp -d)"; tar -xzf "ffmpeg-${VERSION}-${VARIANT}.tar.gz" -C "${_r}" - if ! ( cd "${_r}" && ./ffmpeg -hide_banner -version >/dev/null 2>"${_r}/err" ); then - echo "ERROR: ffmpeg from ffmpeg-${VERSION}-${VARIANT}.tar.gz does not run:" >&2 - head -5 "${_r}/err" >&2 - exit 1 - fi - echo "archive self-test: ffmpeg runs from a clean extraction (${VARIANT})" - rm -rf "${_r}" - fi - rm -rf "${_v}" - ;; - esac - if [ -n "$(ls -A "${DEV}" 2>/dev/null)" ]; then - tar -czf "ffmpeg-${VERSION}-${VARIANT}-dev.tar.gz" -C "${DEV}" . - fi - - - name: Upload release assets - env: - GH_TOKEN: ${{ github.token }} - run: | - VERSION="${{ matrix.build.version }}" - VARIANT="${{ matrix.rid }}-${{ matrix.license }}v${{ matrix.license_version }}" - # Asset upload is a mutable network operation against the API and had no retry, while every - # other network call in this repo now has one -- and this is the worst place to lack one: the - # release is already PUBLIC by the time these run, so a blip leaves a published release missing - # an artifact. --clobber makes the retry idempotent: a partially-uploaded asset is replaced, - # not duplicated. - upload_retry() { # - local f="$1" try delay=4 wait - for try in 1 2 3 4 5 6; do - gh release upload "${{ matrix.build.tag }}" "${f}" --clobber \ - --repo "${{ github.repository }}" && return 0 - if [ "${try}" -eq 6 ]; then - echo "ERROR: gh release upload ${f} failed after 6 attempts" >&2; return 1 - fi - wait=$(( delay + (RANDOM % 5) )) - echo " upload of ${f} failed (attempt ${try}/6) - retrying in ${wait}s..." >&2 - sleep "${wait}"; delay=$(( delay * 2 )) - done - } - upload_retry "ffmpeg-${VERSION}-${VARIANT}.tar.gz" - if [ -f "ffmpeg-${VERSION}-${VARIANT}-dev.tar.gz" ]; then - upload_retry "ffmpeg-${VERSION}-${VARIANT}-dev.tar.gz" - fi - - publish-ios: - needs: [prepare, build, test, test-mobile, release] - runs-on: macos-latest - permissions: - contents: write - strategy: - fail-fast: false # don't let one iOS cell's failure cancel the others - matrix: - build: ${{ fromJson(needs.prepare.outputs.builds) }} - license: [lgpl, gpl] - license_version: [3, 2] # ios v2 = LGPLv2.1/GPLv2 (App-Store-safe): no version3 - steps: - - uses: actions/download-artifact@v8 - with: - name: ${{ matrix.build.version }}-ios-arm64-${{ matrix.license }}v${{ matrix.license_version }} - path: artifacts/ios-arm64 - - uses: actions/download-artifact@v8 - with: - name: ${{ matrix.build.version }}-ios-sim-arm64-${{ matrix.license }}v${{ matrix.license_version }} - path: artifacts/ios-sim-arm64 - - uses: actions/download-artifact@v8 - with: - name: ${{ matrix.build.version }}-maccatalyst-arm64-${{ matrix.license }}v${{ matrix.license_version }} - path: artifacts/maccatalyst-arm64 - - uses: actions/download-artifact@v8 - with: - name: ${{ matrix.build.version }}-maccatalyst-x64-${{ matrix.license }}v${{ matrix.license_version }} - path: artifacts/maccatalyst-x64 - - - name: Fuse the Catalyst frameworks into one universal slice - run: | - # An .xcframework holds at most one framework per platform+variant, so the two Catalyst - # RIDs must be lipo(1)-fused into a single fat binary rather than passed as two separate - # -framework arguments (xcodebuild rejects duplicate library identifiers). Everything - # else in the bundle -- Headers, Info.plist -- is arch-independent, so take the arm64 - # copy wholesale and replace only the executable. - rm -rf artifacts/maccatalyst - cp -R artifacts/maccatalyst-arm64 artifacts/maccatalyst - for fwpath in artifacts/maccatalyst/frameworks/*.framework; do - name=$(basename "${fwpath}" .framework) - lipo -create \ - "artifacts/maccatalyst-arm64/frameworks/${name}.framework/${name}" \ - "artifacts/maccatalyst-x64/frameworks/${name}.framework/${name}" \ - -output "${fwpath}/${name}" - # lipo rewrites the binary, so the ad-hoc signature from the build is now stale. - codesign --remove-signature "${fwpath}/${name}" 2>/dev/null || true - codesign --force --sign - --timestamp=none "${fwpath}/${name}" - archs=$(lipo -archs "${fwpath}/${name}") - case "${archs}" in - *arm64*x86_64*|*x86_64*arm64*) ;; - *) echo "ERROR: ${name} Catalyst slice is not universal (got: ${archs})" >&2; exit 1 ;; - esac - done - - - name: Assemble xcframeworks - run: | - VERSION="${{ matrix.build.version }}" - rm -rf bundle && mkdir -p bundle - # One .xcframework per libav* library, bundling the iOS device, iOS simulator - # and Mac Catalyst (universal arm64 + x86_64) .frameworks. - # These are dynamic frameworks (iOS is --enable-shared); Xcode embeds + signs them in - # the consuming app. Dynamic linking is what makes the lgplv2 build LGPLv2.1-compliant - # (the end user can relink). Headers travel inside each .framework/Headers. - for fwpath in artifacts/ios-arm64/frameworks/*.framework; do - name="$(basename "${fwpath}" .framework)" - xcodebuild -create-xcframework \ - -framework "artifacts/ios-arm64/frameworks/${name}.framework" \ - -framework "artifacts/ios-sim-arm64/frameworks/${name}.framework" \ - -framework "artifacts/maccatalyst/frameworks/${name}.framework" \ - -output "bundle/${name}.xcframework" - # Three slices must land: ios-arm64, ios-*-simulator and ios-*-maccatalyst. If Xcode - # ever folds two of them together the consumer silently loses a platform, so assert. - slices=$(/usr/libexec/PlistBuddy -c "Print :AvailableLibraries" \ - "bundle/${name}.xcframework/Info.plist" | grep -c LibraryIdentifier || true) - if [ "${slices}" -ne 3 ]; then - echo "ERROR: ${name}.xcframework has ${slices} slice(s), expected 3" >&2 - /usr/libexec/PlistBuddy -c "Print :AvailableLibraries" \ - "bundle/${name}.xcframework/Info.plist" >&2 - exit 1 - fi - done - # Attribution has to cover every binary in the bundle. The iOS device notices stay at the - # established path so existing consumers keep working; the simulator slice is the same - # license cell built from the same dependency set, so it is covered by them. Mac Catalyst - # is a distinct platform arm in scripts/platform/apple.sh with its own dependency set (no - # SecureTransport, different Vulkan/Metal choices), so its notices ship alongside rather - # than being assumed identical. - cp -r artifacts/ios-arm64/legal bundle/legal - cp -r artifacts/maccatalyst/legal bundle/legal/maccatalyst - # Nothing the Catalyst build attributed may be missing from what we ship. - for lic in artifacts/maccatalyst/legal/licenses/*; do - dep=$(basename "${lic}") - if [ ! -d "bundle/legal/maccatalyst/licenses/${dep}" ]; then - echo "ERROR: Catalyst license text for ${dep} did not reach the bundle" >&2 - exit 1 - fi - done - tar -czf "ffmpeg-${VERSION}-ios-${{ matrix.license }}v${{ matrix.license_version }}.tar.gz" -C bundle . - - - name: Upload release asset - env: - GH_TOKEN: ${{ github.token }} - run: | - gh release upload "${{ matrix.build.tag }}" \ - "ffmpeg-${{ matrix.build.version }}-ios-${{ matrix.license }}v${{ matrix.license_version }}.tar.gz" \ - --clobber \ - --repo "${{ github.repository }}" - - # Aggregate checksum manifest — one file covering every asset, so a downstream packager or - # mirror verifies once instead of making an API call per asset. - # - # This is an INTEGRITY check, not an authenticity one, and is deliberately NOT described as - # "signed": the manifest sits beside the artifacts and is fetched from the same place under - # the same trust, so whoever could replace a tarball could replace this too. It catches - # truncated/corrupted downloads and lets a consumer pin what they built against and notice - # if an asset later changes. It does NOT establish that we published it — that needs a - # signature anchored elsewhere (e.g. actions/attest-build-provenance). - # - # Digests come from the release API per-asset `digest`, i.e. what GitHub computed from the - # bytes it stored, rather than being hashed here. That verifies the upload round-trip - # cheaply, but nothing in this repo independently hashes the artifact. - # Gated on BOTH publish jobs so every asset exists before the release is enumerated. - manifest: - needs: [prepare, publish, publish-ios] - runs-on: ubuntu-latest + uses: devenvy/ffmpeg-build/.github/workflows/build.yml@52201a1204772caf79156ced0954c25407f6b433 # v0.0.5 permissions: - contents: write - # If the API ever stops populating `digest`, the job silently falls back to downloading all - # ~64 assets (several GB) under the default 360-minute budget; a short timeout turns that - # into a fast, loud failure. - timeout-minutes: 20 - strategy: - matrix: - build: ${{ fromJson(needs.prepare.outputs.builds) }} - steps: - # actions/checkout has no retry input; its internal helper makes 3 attempts with a RANDOM - # 10-20s sleep between them, so roughly 20-40s of cover. A DNS or TLS blip longer than that - # kills the job before any of our code runs: - # fatal: unable to access 'https://github.com/...': Could not resolve host: github.com - # The action cannot be wrapped: a local composite action needs the repo ALREADY checked out, - # and retry actions only wrap `run:` steps, not `uses:` steps. So wait for the host to be - # reachable BEFORE checkout, with the same exponential-with-jitter backoff the build scripts - # use (4, 8, 16, 32, 64s + jitter), and do NOT sleep after the final attempt -- nothing probes - # again afterwards. Worst case is ~2 minutes of sleep plus the probe timeouts. - # This never fails the job. If the host is still unreachable it warns and lets checkout run, so - # the real error is reported by the action rather than masked here. - - name: Wait for github.com to be reachable - shell: bash - run: | - command -v curl >/dev/null 2>&1 || { echo "curl unavailable - skipping reachability wait"; exit 0; } - delay=4 - for i in 1 2 3 4 5 6; do - if curl -sSf -o /dev/null --max-time 10 "${GITHUB_SERVER_URL:-https://github.com}"; then - if [ "$i" -gt 1 ]; then echo "github.com reachable after attempt ${i}"; fi - exit 0 - fi - if [ "$i" -eq 6 ]; then break; fi - s=$(( delay + (RANDOM % 5) )) - echo "github.com not reachable (attempt ${i}/6) - retrying in ${s}s" >&2 - sleep "$s" - delay=$(( delay * 2 )) - done - echo "::warning::github.com still unreachable after 6 attempts; letting checkout try anyway" - - uses: actions/checkout@v7 - - - name: Generate and upload SHA256SUMS - env: - GH_TOKEN: ${{ github.token }} - TAG: ${{ matrix.build.tag }} - REPO: ${{ github.repository }} - run: | - set -euo pipefail - bash scripts/ci/gen-manifest.sh "$TAG" "$REPO" > SHA256SUMS - echo "--- SHA256SUMS ($(wc -l < SHA256SUMS) entries) ---" - cat SHA256SUMS - gh release upload "$TAG" SHA256SUMS \ - --clobber --repo "$REPO" - - # This job runs after the release is public and nothing gates on it, so a silent failure - # would leave a release whose docs promise a SHA256SUMS that isn't there. Surface it. - - name: Report manifest failure - if: failure() - run: | - echo "### SHA256SUMS generation FAILED for \`${{ matrix.build.tag }}\`" >> "$GITHUB_STEP_SUMMARY" - echo "The release is published but has no checksum manifest. Re-run this job, or generate it locally with \`bash scripts/ci/gen-manifest.sh \` and upload it." >> "$GITHUB_STEP_SUMMARY" - - # The release is created as a DRAFT by `release` and becomes visible only here -- after every - # asset (publish, publish-ios) and the SHA256SUMS manifest are attached. Before this job existed - # the release went public first and the assets followed, so any upload failure left a PUBLIC - # release, possibly badged `latest`, missing artifacts or checksums that consumers would fetch. - # - # If any earlier job fails, this one never runs and the release stays a draft: invisible, - # complete-or-nothing, and there for a human to inspect or delete. - # - # MARK_LATEST is recomputed from deps.json rather than passed through: `release` is a matrix job, - # so its outputs would be last-wins across lines, and deps.json is the same source of truth in - # both places. - finalize: - needs: [prepare, manifest] - runs-on: ubuntu-latest - permissions: - contents: write - strategy: - fail-fast: false # publish every line that made it; one line's failure must not hide another - matrix: - build: ${{ fromJson(needs.prepare.outputs.builds) }} - steps: - - uses: actions/checkout@v7 - - name: Publish the draft release - env: - GH_TOKEN: ${{ github.token }} - run: | - VERSION="${{ matrix.build.version }}" - TAG="${{ matrix.build.tag }}" - # Only the HIGHEST tracked line gets GitHub's "Latest" badge -- a maintenance release on - # an older line must not steal it from the newest major. Same rule the draft was created - # under; --latest is only meaningful once the release is no longer a draft. - HIGHEST="$(jq -r '.ffmpeg[]' deps.json | sort -V | tail -1)" - if [[ "${VERSION}" == "${HIGHEST}" ]]; then MARK_LATEST=true; else MARK_LATEST=false; fi - echo "Publishing ${TAG} (latest=${MARK_LATEST})" - delay=4 - for try in 1 2 3 4 5 6; do - gh release edit "${TAG}" --draft=false --latest="${MARK_LATEST}" --repo "${{ github.repository }}" && exit 0 - if [ "${try}" -eq 6 ]; then - echo "ERROR: could not publish ${TAG} after 6 attempts - it remains a draft" >&2 - exit 1 - fi - wait=$(( delay + (RANDOM % 5) )) - echo " publish failed (attempt ${try}/6) - retrying in ${wait}s..." >&2 - sleep "${wait}"; delay=$(( delay * 2 )) - done + contents: write # the GitHub releases + with: + publish: changed-only diff --git a/.github/workflows/renovate-matrix.yml b/.github/workflows/renovate-matrix.yml deleted file mode 100644 index c964a26..0000000 --- a/.github/workflows/renovate-matrix.yml +++ /dev/null @@ -1,77 +0,0 @@ -name: Renovate matrix sync - -# Renovate edits deps.json but cannot run scripts/gen-matrix.sh, so every ledger bump it opens -# lands with a stale docs/matrix. That is not a cosmetic failure: ci.yml's build-matrix declares -# needs: [resolve, docs-matrix] -# and a failed dependency SKIPS the dependent job whatever its `if:` says, so a red docs-matrix -# silently cancelled the entire build/test fan-out. PR #31 sat at 13 checks instead of 128 and had -# validated nothing about the bump it proposed -- the opposite of what renovate.yml's own header -# promises ("CI (build + docs-matrix) then validates that bump across every FFmpeg line"). -# -# So regenerate the matrices on the Renovate branch itself and push them back. The push uses -# UPDATE_PR_TOKEN rather than GITHUB_TOKEN specifically so the PR's checks re-run -- a -# GITHUB_TOKEN push does not trigger workflows, which would leave the PR red forever. - -on: - push: - branches: - - 'renovate/**' - paths: - - deps.json - -permissions: - contents: read # the push uses UPDATE_PR_TOKEN, not GITHUB_TOKEN - -concurrency: - # Per branch, and cancel superseded runs: if Renovate force-pushes an updated bump while this is - # still regenerating, the older run's matrices are already wrong. - group: renovate-matrix-${{ github.ref }} - cancel-in-progress: true - -jobs: - sync: - # ubuntu-latest for the same reason ci.yml's docs-matrix uses it: ANDROID_NDK_LATEST_HOME is - # preinstalled, which gen-matrix.sh needs for the android rows. - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - with: - ref: ${{ github.ref_name }} - token: ${{ secrets.UPDATE_PR_TOKEN }} - - # Belt and braces against a push loop. The no-drift exit below is the real terminator (run 2 - # regenerates, finds nothing to commit, stops), but that relies on gen-matrix.sh being - # deterministic. If it ever is not, this stops the loop at one extra cycle instead of - # hammering the branch. - - name: Skip if this push was our own regeneration - id: guard - run: | - if [ "$(git log -1 --pretty=%an)" = "ffmpeg-update-bot" ]; then - echo "last commit is ours - nothing to do" - echo "skip=true" >> "$GITHUB_OUTPUT" - else - echo "skip=false" >> "$GITHUB_OUTPUT" - fi - - - name: Regenerate the coverage matrices and push if they drifted - if: steps.guard.outputs.skip != 'true' - run: | - set -euo pipefail - bash scripts/gen-matrix.sh - if git diff --quiet -- docs/matrix; then - echo "docs/matrix already current - nothing to push" - exit 0 - fi - echo "docs/matrix drifted; regenerated:" - git diff --stat -- docs/matrix - git config user.name "ffmpeg-update-bot" - git config user.email "ffmpeg-update-bot@users.noreply.github.com" - git add docs/matrix - # Separate -m flags rather than one multi-line string: a literal newline inside the - # YAML block scalar would need its own indentation and end up inside the message. - git commit \ - -m "docs(matrix): regenerate for this dependency bump" \ - -m "Renovate edits deps.json but cannot run scripts/gen-matrix.sh, so docs-matrix would fail and, because build-matrix needs it, skip the whole build/test fan-out. Generated by .github/workflows/renovate-matrix.yml." - # No --force: this only ever appends, and a non-fast-forward here means Renovate - # rewrote the branch underneath us, in which case the newer run should win. - git push origin "HEAD:${GITHUB_REF_NAME}" diff --git a/.github/workflows/renovate.yml b/.github/workflows/renovate.yml deleted file mode 100644 index 2a2a094..0000000 --- a/.github/workflows/renovate.yml +++ /dev/null @@ -1,187 +0,0 @@ -name: Renovate - -# Self-hosted Renovate: runs the Renovate CLI as a scheduled Action in this repo (no -# external service), same trust model as check-updates.yml. It reads renovate.json, which -# scopes custom regex managers to the DEFAULTS block of deps.json and opens a PR when an -# upstream publishes a newer version -- a newer git tag, a newer tarball on a release listing -# (gmp, libmp3lame, libgsm, opencore-amr, vo-amrwbenc, which have no git remote), or a newer -# commit on the branch a digest pin follows (x264, amf). CI (build + docs-matrix) then validates that bump across -# every FFmpeg line before it can merge; if a line can't take the new version, add an -# overrides.[.platforms] hold in the same PR (Renovate never edits overrides). - -on: - schedule: - - cron: "0 6 * * 1" # weekly, Monday 06:00 UTC - workflow_dispatch: - inputs: - dryRun: - description: "Run without opening PRs (log only)" - type: boolean - default: false - -# These govern GITHUB_TOKEN, used by actions/checkout and the guard step below. They do NOT -# govern Renovate: it authenticates with the UPDATE_PR_TOKEN PAT (see the Run Renovate step), -# so its access is bounded by that PAT's scopes, not by this block. Raising anything here -# cannot fix a Renovate 403 -- the scope has to be added to the PAT itself. -permissions: - contents: write # create branches - pull-requests: write # open/update bump PRs - issues: read # guard step reads the Dependency Dashboard issue - -concurrency: - group: renovate - cancel-in-progress: false - -jobs: - renovate: - runs-on: ubuntu-latest - steps: - # actions/checkout has no retry input; its internal helper makes 3 attempts with a RANDOM - # 10-20s sleep between them, so roughly 20-40s of cover. A DNS or TLS blip longer than that - # kills the job before any of our code runs: - # fatal: unable to access 'https://github.com/...': Could not resolve host: github.com - # The action cannot be wrapped: a local composite action needs the repo ALREADY checked out, - # and retry actions only wrap `run:` steps, not `uses:` steps. So wait for the host to be - # reachable BEFORE checkout, with the same exponential-with-jitter backoff the build scripts - # use (4, 8, 16, 32, 64s + jitter), and do NOT sleep after the final attempt -- nothing probes - # again afterwards. Worst case is ~2 minutes of sleep plus the probe timeouts. - # This never fails the job. If the host is still unreachable it warns and lets checkout run, so - # the real error is reported by the action rather than masked here. - - name: Wait for github.com to be reachable - shell: bash - run: | - command -v curl >/dev/null 2>&1 || { echo "curl unavailable - skipping reachability wait"; exit 0; } - delay=4 - for i in 1 2 3 4 5 6; do - if curl -sSf -o /dev/null --max-time 10 "${GITHUB_SERVER_URL:-https://github.com}"; then - if [ "$i" -gt 1 ]; then echo "github.com reachable after attempt ${i}"; fi - exit 0 - fi - if [ "$i" -eq 6 ]; then break; fi - s=$(( delay + (RANDOM % 5) )) - echo "github.com not reachable (attempt ${i}/6) - retrying in ${s}s" >&2 - sleep "$s" - delay=$(( delay * 2 )) - done - echo "::warning::github.com still unreachable after 6 attempts; letting checkout try anyway" - - uses: actions/checkout@v7 - # Fail FAST and legibly on a missing scope. Renovate's own response to one is an INFO-level - # line buried in a 400-line log plus exit code 0, which is indistinguishable from "nothing - # to update" -- this repo has already lost weeks of bumps to exactly that. - # Classic PATs report scopes in the X-OAuth-Scopes response header. Fine-grained PATs send - # no such header, so its absence means "cannot verify", NOT "no scopes": note it and continue - # rather than fail on a token that simply cannot be introspected this way (see the - # github_pat_ arm below for why that is a plain line, not a warning annotation). - - name: Check the Renovate token carries the scopes Renovate needs - env: - TOKEN: ${{ secrets.UPDATE_PR_TOKEN }} - # dryRun exists to preview what Renovate WOULD do; a missing scope only matters when it - # tries to write. So report the same finding there but don't block the preview. - ENFORCE: ${{ !inputs.dryRun }} - run: | - fatal() { - if [ "${ENFORCE}" = "true" ]; then echo "::error::$*"; exit 1; fi - echo "::warning::$* (dryRun: not failing the job)"; exit 0 - } - if [ -z "${TOKEN}" ]; then - fatal "UPDATE_PR_TOKEN is empty or unset - Renovate cannot run" - fi - hdrs="$(curl -sS -o /dev/null -D - --max-time 30 \ - -H "Authorization: Bearer ${TOKEN}" \ - -H "Accept: application/vnd.github+json" \ - https://api.github.com/user 2>/dev/null || true)" - # The status line comes first in -D output. A token GitHub rejects outright (expired, - # revoked, or never valid) answers 401 whatever its prefix -- a fine-grained PAT that has - # hit its expiry date still starts with github_pat_ -- and that is a hard failure the - # scope check below cannot see, because a 401 carries no scopes header either. No status - # at all means curl itself failed (network), which is "cannot verify", not "rejected". - status="$(printf '%s' "${hdrs}" | tr -d '\r' | sed -n '1s#^HTTP/[0-9.]* \([0-9][0-9][0-9]\).*#\1#p')" - if [ -n "${status}" ] && [ "${status}" != "200" ]; then - fatal "GitHub rejected UPDATE_PR_TOKEN (HTTP ${status} from /user) - the token is expired, revoked or malformed; Renovate would fail on every API call" - fi - scopes="$(printf '%s' "${hdrs}" | tr -d '\r' | sed -n 's/^[Xx]-[Oo][Aa]uth-[Ss]copes:[[:space:]]*//p')" - if [ -z "${scopes}" ]; then - case "${TOKEN}" in - github_pat_*) - # A fine-grained PAT. These never send X-OAuth-Scopes and GitHub exposes no API - # that reports a fine-grained token's permissions, so there is nothing this step - # CAN verify -- by design, not degradation, and not worth a yellow annotation on - # every run that trains people to skim past warnings. The outcome is what proves - # the permissions: the post-run guard below reads the Dependency Dashboard for - # Repository Problems, and a "CI tooling pinned in workflows" PR appearing at all - # proves the Workflows permission (that is the one whose absence discards branches). - echo "fine-grained PAT (github_pat_*): permissions cannot be introspected up front; the post-run Dependency Dashboard guard verifies the outcome" - ;; - *) - echo "::warning::token sends no X-OAuth-Scopes header and is not a github_pat_ token - cannot verify scopes here; the post-run guard still checks the outcome" - ;; - esac - exit 0 - fi - echo "token scopes: ${scopes}" - missing="" - for want in repo workflow; do - printf '%s' ",${scopes}," | tr -d ' ' | grep -q ",${want}," || missing="${missing} ${want}" - done - if [ -n "${missing}" ]; then - fatal "UPDATE_PR_TOKEN is missing required scope(s):${missing}. Without 'workflow' Renovate aborts any branch touching .github/workflows/; without 'repo' it cannot push branches or update the Dependency Dashboard." - fi - echo "ok: token carries repo + workflow" - - name: Run Renovate - uses: renovatebot/github-action@v46.3.6 - with: - # A PAT (not GITHUB_TOKEN): PRs opened with the default token don't trigger other - # workflows, so Renovate's bump PRs wouldn't run CI. UPDATE_PR_TOKEN (also used by - # check-updates.yml) lets the PRs run the build/test/docs-matrix gates. - # - # REQUIRED PAT SCOPES -- Renovate degrades QUIETLY when one is missing, so each of these - # was observed failing in run 35140763146 rather than inferred: - # repo branches, PRs, and the Dependency Dashboard issue. - # workflow push changes under .github/workflows/. Without it Renovate logs - # "Workflows update rejection - aborting branch" and discards the WHOLE - # branch, not just the workflow file -- see the "Renovate itself" rule in - # renovate.json for why that manager is now grouped on its own. - # (issues) covered by `repo` on a classic PAT; a fine-grained PAT needs Issues:RW, - # or Renovate 403s on the dashboard and its reported state silently stales. - # Dependabot alerts must also be readable or Renovate cannot raise security bumps. - token: ${{ secrets.UPDATE_PR_TOKEN }} - configurationFile: renovate.json - # Pin Renovate CORE, not just the action wrapper. The action's default - # renovate-version is a moving major tag, which would leave the tool that - # maintains every other pin unpinned itself. Tracked by a customManager in - # renovate.json, so it stays current the same way the libraries do. - renovate-version: 44.134.3 - env: - RENOVATE_REPOSITORIES: ${{ github.repository }} - RENOVATE_AUTODISCOVER: "false" - # Was `"onboarding": false` in renovate.json. That file is passed as configurationFile - # (Renovate's GLOBAL config) AND read from the default branch as the REPO config, so the - # option took effect globally while the repo-config pass rejected it every run. Setting - # it as env keeps the intent in the layer it belongs to, with no Configuration Error. - RENOVATE_ONBOARDING: "false" - RENOVATE_DRY_RUN: ${{ inputs.dryRun && 'full' || null }} - LOG_LEVEL: info - # Renovate exits 0 whether it opened every PR or silently discarded all of them, so this - # job's own green check proves nothing on its own. Renovate DOES publish what went wrong -- - # as a "Repository Problems" section on the Dependency Dashboard issue -- so read that back - # and fail on it. Skipped for dryRun, which deliberately changes nothing. - - name: Fail if Renovate reported repository problems - if: ${{ !inputs.dryRun }} - env: - GH_TOKEN: ${{ github.token }} - run: | - num="$(gh issue list --repo "${GITHUB_REPOSITORY}" --state open --limit 100 \ - --json number,title \ - --jq '.[] | select(.title == "Dependency Dashboard") | .number' | head -1)" - if [ -z "${num}" ]; then - echo "::warning::no open 'Dependency Dashboard' issue found - cannot verify this run" - exit 0 - fi - body="$(gh issue view "${num}" --repo "${GITHUB_REPOSITORY}" --json body --jq .body)" - if printf '%s' "${body}" | grep -q '^## Repository Problems'; then - echo "Renovate reported problems on issue #${num}:" - printf '%s\n' "${body}" | sed -n '/^## Repository Problems/,/^## /p' | head -30 - echo "::error::Renovate reported repository problems on the Dependency Dashboard (#${num}). Updates may have been silently dropped - see the section above." - exit 1 - fi - echo "ok: no repository problems reported on the Dependency Dashboard (#${num})" diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml deleted file mode 100644 index 1b1ae4a..0000000 --- a/.github/workflows/shellcheck.yml +++ /dev/null @@ -1,166 +0,0 @@ -name: ShellCheck - -# Static analysis of our shell scripts (the bulk of this repo). CodeQL has no shell -# analyzer, so ShellCheck covers scripts/**/*.sh here. Findings are uploaded as SARIF -# so they appear in the Security tab alongside CodeQL. Report-only for now (does not -# fail the build) — flip on a gate once the baseline is triaged (see the commented -# step at the end). - -on: - push: - branches: [main] - pull_request: - branches: [main] - -permissions: - contents: read - security-events: write # upload SARIF to the Security tab - -concurrency: - group: shellcheck-${{ github.ref }} - cancel-in-progress: true - -jobs: - shellcheck: - runs-on: ubuntu-latest - steps: - # actions/checkout has no retry input; its internal helper makes 3 attempts with a RANDOM - # 10-20s sleep between them, so roughly 20-40s of cover. A DNS or TLS blip longer than that - # kills the job before any of our code runs: - # fatal: unable to access 'https://github.com/...': Could not resolve host: github.com - # The action cannot be wrapped: a local composite action needs the repo ALREADY checked out, - # and retry actions only wrap `run:` steps, not `uses:` steps. So wait for the host to be - # reachable BEFORE checkout, with the same exponential-with-jitter backoff the build scripts - # use (4, 8, 16, 32, 64s + jitter), and do NOT sleep after the final attempt -- nothing probes - # again afterwards. Worst case is ~2 minutes of sleep plus the probe timeouts. - # This never fails the job. If the host is still unreachable it warns and lets checkout run, so - # the real error is reported by the action rather than masked here. - - name: Wait for github.com to be reachable - shell: bash - run: | - command -v curl >/dev/null 2>&1 || { echo "curl unavailable - skipping reachability wait"; exit 0; } - delay=4 - for i in 1 2 3 4 5 6; do - if curl -sSf -o /dev/null --max-time 10 "${GITHUB_SERVER_URL:-https://github.com}"; then - if [ "$i" -gt 1 ]; then echo "github.com reachable after attempt ${i}"; fi - exit 0 - fi - if [ "$i" -eq 6 ]; then break; fi - s=$(( delay + (RANDOM % 5) )) - echo "github.com not reachable (attempt ${i}/6) - retrying in ${s}s" >&2 - sleep "$s" - delay=$(( delay * 2 )) - done - echo "::warning::github.com still unreachable after 6 attempts; letting checkout try anyway" - - uses: actions/checkout@v7 - - - name: Dependency ledger checks - shell: bash - run: | - bash scripts/deps/ledger-test.sh - bash scripts/deps/ledger-validate-test.sh - bash scripts/deps/ledger-validate.sh - bash scripts/ci/select-versions-test.sh - bash scripts/ci/gen-manifest-test.sh - bash scripts/ci/pinned-deps-test.sh - bash scripts/ci/renovate-coverage-test.sh - bash scripts/ci/image-pins-test.sh - bash scripts/ci/matrix-consistency-test.sh - bash scripts/ci/renovate-config-test.sh - - # Our dep scripts are SOURCED by build.sh and share its environment, so many variables - # are assigned by the parent, not the script itself; -x follows sourced files so - # ShellCheck sees those assignments. SC2154 (referenced-but-not-assigned) used to be - # excluded wholesale for that pattern, but it produces ZERO findings across all 94 - # scripts, so the exclusion bought nothing and hid real bugs: it silently passed - # `stage_pkgconfig "${prefix}"`, where ${prefix} is a pkg-config variable with no shell - # counterpart, which aborted staging on every RID under set -u. If a genuine false - # positive ever appears, disable it INLINE at that reference with a reason, never - # repo-wide. Severity floor is 'warning'. - - name: Run ShellCheck (SARIF for the Security tab) - run: | - set -euo pipefail - mapfile -t FILES < <(find scripts -name '*.sh' -type f | sort) - echo "Linting ${#FILES[@]} scripts..." - # ShellCheck has no native SARIF formatter; convert its JSON to SARIF inline. - shellcheck -x -S warning -f json1 "${FILES[@]}" > sc.json || true - python3 - <<'PY' - import json - data = json.load(open('sc.json')) - rules, results = {}, [] - for c in data.get('comments', []): - rid = f"SC{c['code']}" - rules.setdefault(rid, {"id": rid, - "helpUri": f"https://www.shellcheck.net/wiki/{rid}", - "shortDescription": {"text": c['message']}}) - lvl = {"error": "error", "warning": "warning", "info": "note", - "style": "note"}.get(c['level'], "warning") - results.append({"ruleId": rid, "level": lvl, - "message": {"text": c['message']}, - "locations": [{"physicalLocation": { - "artifactLocation": {"uri": c['file']}, - "region": {"startLine": c['line'], "startColumn": c.get('column', 1)}}}]}) - sarif = {"version": "2.1.0", - "$schema": "https://json.schemastore.org/sarif-2.1.0.json", - "runs": [{"tool": {"driver": {"name": "ShellCheck", - "informationUri": "https://www.shellcheck.net", - "rules": list(rules.values())}}, "results": results}]} - json.dump(sarif, open('shellcheck.sarif', 'w'), indent=2) - print(f"{len(results)} finding(s)") - PY - - - name: Upload SARIF - if: always() - uses: github/codeql-action/upload-sarif@v4 - with: - sarif_file: shellcheck.sarif - category: shellcheck - - - # Deliberately a SEPARATE job. As a step inside `shellcheck` this reported as - # "shellcheck failing", which reads like a lint error and repeatedly sent people looking - # for one — there were never any findings. A blocked merge should say so in its own name. - matrix-not-narrowed: - runs-on: ubuntu-latest - steps: - # actions/checkout has no retry input; its internal helper makes 3 attempts with a RANDOM - # 10-20s sleep between them, so roughly 20-40s of cover. A DNS or TLS blip longer than that - # kills the job before any of our code runs: - # fatal: unable to access 'https://github.com/...': Could not resolve host: github.com - # The action cannot be wrapped: a local composite action needs the repo ALREADY checked out, - # and retry actions only wrap `run:` steps, not `uses:` steps. So wait for the host to be - # reachable BEFORE checkout, with the same exponential-with-jitter backoff the build scripts - # use (4, 8, 16, 32, 64s + jitter), and do NOT sleep after the final attempt -- nothing probes - # again afterwards. Worst case is ~2 minutes of sleep plus the probe timeouts. - # This never fails the job. If the host is still unreachable it warns and lets checkout run, so - # the real error is reported by the action rather than masked here. - - name: Wait for github.com to be reachable - shell: bash - run: | - command -v curl >/dev/null 2>&1 || { echo "curl unavailable - skipping reachability wait"; exit 0; } - delay=4 - for i in 1 2 3 4 5 6; do - if curl -sSf -o /dev/null --max-time 10 "${GITHUB_SERVER_URL:-https://github.com}"; then - if [ "$i" -gt 1 ]; then echo "github.com reachable after attempt ${i}"; fi - exit 0 - fi - if [ "$i" -eq 6 ]; then break; fi - s=$(( delay + (RANDOM % 5) )) - echo "github.com not reachable (attempt ${i}/6) - retrying in ${s}s" >&2 - sleep "$s" - delay=$(( delay * 2 )) - done - echo "::warning::github.com still unreachable after 6 attempts; letting checkout try anyway" - - uses: actions/checkout@v7 - - name: Fail if a build matrix is still temporarily narrowed - run: | - # The marker is assembled at runtime so THIS workflow's own source does not contain the - # literal string. Grepping for it directly made the guard match itself, so it could never - # pass -- not even with the matrix fully restored. Excluding this file instead would have - # left a blind spot; this keeps every workflow in scope, including this one. - marker="TEMP-""NARROWED" - if grep -rn "${marker}" .github/workflows/; then - echo "::error::A build matrix is still temporarily narrowed — restore the full RID list before merging." - exit 1 - fi - echo "ok: no temporarily narrowed matrices" \ No newline at end of file diff --git a/.github/workflows/test-mobile.yml b/.github/workflows/test-mobile.yml deleted file mode 100644 index fb323a0..0000000 --- a/.github/workflows/test-mobile.yml +++ /dev/null @@ -1,204 +0,0 @@ -name: Test (mobile) - -# Android/iOS tests against the artifacts from build.yml — kept SEPARATE from the -# desktop test workflow because the mobile setup (NDK/Xcode toolchains, arm64 -# emulator boot, iOS simulator via simctl) is slow and comparatively fragile, and -# shouldn't gate or destabilise the fast desktop execution checks. -# -# Two layers, mirroring how these link-only artifacts are consumed: -# 1. ABI link-check — compile the smoke program against the built libraries -# (toolchain present on the runner); proves no undefined symbols. Runs for -# every RID x license. -# 2. Runtime — actually execute on an emulator (Android) / simulator (iOS). The Android -# emulator is x86_64: android-x64 runs on it natively, android-arm64 runs via the -# API-35 image's native bridge (translated). Gated on `matrix.license == 'lgpl'` with -# no license_version restriction, so runtime tests run for BOTH lgpl series (lgplv3 and -# lgplv2) per platform, not gpl — their TLS/Vulkan configuration genuinely differs -# between v3 and v2, so both are worth exercising; gpl only adds x264/x265, which -# the runtime step doesn't touch. -# Chained after build.yml by ci.yml and release.yml. - -permissions: - contents: read - -on: - workflow_call: - inputs: - ffmpeg_version: - required: true - type: string - ref: - required: false - type: string - default: "" - fail_fast: - required: false - type: boolean - default: false - -jobs: - test: - strategy: - fail-fast: ${{ inputs.fail_fast }} - matrix: - rid: [android-arm64, android-x64, ios-arm64, ios-sim-arm64, maccatalyst-arm64, maccatalyst-x64] - license: [lgpl, gpl] - # v3 = OpenSSL 3.x TLS + Vulkan on Linux/Android. v2 = Vulkan dropped everywhere; on - # Linux/Android, gplv2 gets GnuTLS but lgplv2 has NO TLS backend at all. iOS/macOS/Windows - # keep their native SecureTransport/SChannel TLS in every cell, v3 or v2. Mac Catalyst is - # the exception among Apple targets: SecureTransport is unavailable there (the SDK marks - # it "no longer supported" and tls_securetransport.c fails to COMPILE), so Catalyst takes - # the Linux/Android route and its lgplv2 cell has no TLS backend either. - license_version: [3, 2] - include: - - rid: android-arm64 - # x86_64 emulator on ubuntu-latest, KVM-accelerated; its API-35 image translates our - # arm64 code via the native bridge (an actual arm64-v8a emulator has no accel on any - # hosted runner: foreign-arch on x86, no emulator binary on arm64-Linux, HVF blocked on mac). - runner: ubuntu-latest - - rid: android-x64 - # NATIVE on the KVM-accelerated x86_64 emulator — no native-bridge translation, - # unlike android-arm64, whose arm64 binaries the API-35 x86_64 image translates. - runner: ubuntu-latest - - rid: ios-arm64 - runner: macos-latest - - rid: ios-sim-arm64 - runner: macos-latest - # Catalyst binaries are native macOS Mach-O, so each slice is tested on a runner of - # its OWN arch and actually EXECUTES (scripts/test/ios.sh runs the smoke program when - # host arch == slice arch). Running the x86_64 slice on an Apple-Silicon runner would - # depend on Rosetta, so it gets the Intel runner instead of being emulated. - - rid: maccatalyst-arm64 - runner: macos-latest - - rid: maccatalyst-x64 - runner: macos-15-intel - - runs-on: ${{ matrix.runner }} - name: ${{ inputs.ffmpeg_version }} ${{ matrix.rid }} (${{ matrix.license }}v${{ matrix.license_version }}) - - env: - BUILD_RID: ${{ matrix.rid }} - VARIANT: ${{ inputs.ffmpeg_version }}-${{ matrix.rid }}-${{ matrix.license }}v${{ matrix.license_version }} - - steps: - # actions/checkout has no retry input; its internal helper makes 3 attempts with a RANDOM - # 10-20s sleep between them, so roughly 20-40s of cover. A DNS or TLS blip longer than that - # kills the job before any of our code runs: - # fatal: unable to access 'https://github.com/...': Could not resolve host: github.com - # The action cannot be wrapped: a local composite action needs the repo ALREADY checked out, - # and retry actions only wrap `run:` steps, not `uses:` steps. So wait for the host to be - # reachable BEFORE checkout, with the same exponential-with-jitter backoff the build scripts - # use (4, 8, 16, 32, 64s + jitter), and do NOT sleep after the final attempt -- nothing probes - # again afterwards. Worst case is ~2 minutes of sleep plus the probe timeouts. - # This never fails the job. If the host is still unreachable it warns and lets checkout run, so - # the real error is reported by the action rather than masked here. - - name: Wait for github.com to be reachable - shell: bash - run: | - command -v curl >/dev/null 2>&1 || { echo "curl unavailable - skipping reachability wait"; exit 0; } - delay=4 - for i in 1 2 3 4 5 6; do - if curl -sSf -o /dev/null --max-time 10 "${GITHUB_SERVER_URL:-https://github.com}"; then - if [ "$i" -gt 1 ]; then echo "github.com reachable after attempt ${i}"; fi - exit 0 - fi - if [ "$i" -eq 6 ]; then break; fi - s=$(( delay + (RANDOM % 5) )) - echo "github.com not reachable (attempt ${i}/6) - retrying in ${s}s" >&2 - sleep "$s" - delay=$(( delay * 2 )) - done - echo "::warning::github.com still unreachable after 6 attempts; letting checkout try anyway" - - uses: actions/checkout@v7 - with: - # github.sha, NOT github.ref: for a push run github.ref is refs/heads/main, so each - # matrix cell would check out whatever main's tip is when that cell STARTS. Across a - # multi-hour matrix that lets different cells build different commits, and none of - # them need be the commit the release tags. github.sha is the immutable event SHA and - # is shared with the calling workflow, so every cell builds exactly one tree. - ref: ${{ inputs.ref || github.sha }} - - - name: Download build artifact - uses: actions/download-artifact@v8 - with: - name: ${{ env.VARIANT }} - path: artifacts/${{ matrix.rid }}/native - - # ABI link-check: compile the smoke program against the built libraries. The - # NDK (Ubuntu) / Xcode (macOS) toolchain is present on the runner, so this - # proves the libraries have no undefined symbols. - - name: ABI link-check - shell: bash - run: | - chmod +x scripts/test.sh scripts/test/*.sh - if [[ "${BUILD_RID}" == android-* ]]; then - export ANDROID_NDK_HOME="${ANDROID_NDK_HOME:-$ANDROID_NDK_LATEST_HOME}" - fi - bash scripts/test.sh "${BUILD_RID}" "artifacts/${BUILD_RID}/native" - - # iOS simulator runtime: the simulator slice is an arm64 binary, so it runs - # natively on the Apple-Silicon runner (no emulation) — a true execution of - # encode/decode + whisper + TLS. GATING now: iOS is dynamic, so ios-run.sh links - # cleanly against the dylibs and a genuine runtime failure fails the job. - - name: iOS simulator runtime smoke - if: matrix.rid == 'ios-sim-arm64' && matrix.license == 'lgpl' - shell: bash - run: | - # Pick an available iOS runtime AND an iPhone from THAT runtime's own - # supportedDeviceTypes — picking device and runtime independently can yield an - # incompatible pair, which simctl rejects with "Incompatible device" (403). - PAIR="$(xcrun simctl list runtimes -j | python3 -c 'import json,sys; rts=[r for r in json.load(sys.stdin)["runtimes"] if r["name"].startswith("iOS") and r.get("isAvailable") and r.get("supportedDeviceTypes")]; r=rts[-1]; iph=[d for d in r["supportedDeviceTypes"] if "iPhone" in d["name"]] or r["supportedDeviceTypes"]; print(r["identifier"], iph[-1]["identifier"])')" - RT="${PAIR% *}"; DEV="${PAIR#* }" - echo "Using runtime=$RT device=$DEV" - UDID="$(xcrun simctl create ff-smoke "$DEV" "$RT")" - xcrun simctl boot "$UDID" - xcrun simctl bootstatus "$UDID" - bash scripts/test/ios-run.sh "${BUILD_RID}" "artifacts/${BUILD_RID}/native" - xcrun simctl delete "$UDID" || true - - # KVM access for the x86_64 emulator (KVM exists on x86 GitHub runners; the runner user just - # needs permission via this udev rule — the standard, documented step). Tolerant: reports if - # /dev/kvm is somehow absent instead of hard-failing. - - name: Enable KVM - if: startsWith(matrix.rid, 'android-') && matrix.license == 'lgpl' - run: | - if [ -e /dev/kvm ]; then - echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' \ - | sudo tee /etc/udev/rules.d/99-kvm4all.rules - sudo udevadm control --reload-rules - sudo udevadm trigger --name-match=kvm || true - ls -l /dev/kvm - else - echo "WARNING: /dev/kvm absent — emulator will be un-accelerated" - fi - - # Android runtime smoke — KVM-accelerated x86_64 emulator. GATING. Boots in ~40s; android-x64 - # runs natively on it, android-arm64 runs via the API-35 image's native bridge (translated); - # the remaining work is on-device native-lib resolution (see android-run.sh / the handoff). - - name: Android emulator runtime smoke - if: startsWith(matrix.rid, 'android-') && matrix.license == 'lgpl' - uses: reactivecircus/android-emulator-runner@a421e43855164a8197daf9d8d40fe71c6996bb0d # v2 - with: - api-level: 35 - target: google_apis - arch: x86_64 - profile: pixel_5 - force-avd-creation: false - emulator-boot-timeout: 900 - disable-animations: true - emulator-options: -no-snapshot-load -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -camera-front none - script: | - export ANDROID_NDK_HOME="${ANDROID_NDK_HOME:-$ANDROID_NDK_LATEST_HOME}" - bash scripts/test/android-run.sh "${BUILD_RID}" "artifacts/${BUILD_RID}/native" - - # Gate job — single required status check for branch protection. - all-mobile-tests: - if: always() - needs: test - runs-on: ubuntu-latest - steps: - - run: | - if [[ "${{ needs.test.result }}" != "success" ]]; then - echo "One or more mobile test jobs failed" - exit 1 - fi diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 0a72c42..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,279 +0,0 @@ -name: Test (desktop) - -# Desktop/server execution tests against the artifacts from build.yml: download -# each variant and RUN it (version, filter/decoder/protocol enumeration incl. -# https/tls, an encode->decode round-trip) on a runner where the target executes -# natively — Linux on Linux, Windows on Windows, macOS on macOS. Mobile (Android/ -# iOS) is deliberately a SEPARATE workflow (test-mobile.yml): its emulator/simulator -# setup is slow and fiddly and shouldn't gate or destabilise these fast checks. -# Chained after build.yml by ci.yml and release.yml. - -permissions: - contents: read - -on: - workflow_call: - inputs: - ffmpeg_version: - required: true - type: string - ref: - required: false - type: string - default: "" - fail_fast: - required: false - type: boolean - default: false - -jobs: - test: - strategy: - fail-fast: ${{ inputs.fail_fast }} - matrix: - rid: [linux-x64, linux-arm64, linux-armhf, linux-musl-x64, linux-musl-arm64, win-x64, win-arm64, osx-x64, osx-arm64] - license: [lgpl, gpl] - # v3 = OpenSSL 3.x TLS + Vulkan on Linux/Android. v2 = Vulkan dropped everywhere; on - # Linux/Android, gplv2 gets GnuTLS but lgplv2 has NO TLS backend at all. Apple/Windows - # keep their native SecureTransport/SChannel TLS in every cell, v3 or v2. - license_version: [3, 2] - include: - # Tests run where the target executes natively. The glibc Linux builds test - # on the PLAIN Ubuntu runner (not the manylinux build container) — running - # the low-glibc-floor binary on the runner's newer glibc also proves - # portability. Windows tests run on a real Windows runner (native .exe, no - # Wine). - - rid: linux-x64 - runner: ubuntu-latest - - rid: linux-arm64 - runner: ubuntu-24.04-arm - - rid: linux-armhf - runner: ubuntu-latest - - rid: linux-musl-x64 - runner: ubuntu-latest - container: alpine:3.24.2@sha256:294b683cb724975bec92580e1e685676bd4b50bda910ddb8c51d4cabeaec77e6 - # No container: here (unlike linux-musl-x64) — GitHub only supports - # JavaScript actions in Alpine containers on x64 runners, so this RID - # instead docker-runs the pinned Alpine image itself in the Test artifact step - # below, keeping actions/checkout etc. on the host's glibc Node runtime. - - rid: linux-musl-arm64 - runner: ubuntu-24.04-arm - - rid: win-x64 - runner: windows-latest - # GitHub's Windows-on-ARM runner: the artifact is an ARM64 binary, so it - # executes natively here rather than under emulation. - - rid: win-arm64 - runner: windows-11-arm - - rid: osx-x64 - runner: macos-15-intel - - rid: osx-arm64 - runner: macos-latest - - runs-on: ${{ matrix.runner }} - container: ${{ matrix.container || '' }} - name: ${{ inputs.ffmpeg_version }} ${{ matrix.rid }} (${{ matrix.license }}v${{ matrix.license_version }}) - - env: - BUILD_RID: ${{ matrix.rid }} - VARIANT: ${{ inputs.ffmpeg_version }}-${{ matrix.rid }}-${{ matrix.license }}v${{ matrix.license_version }} - - steps: - - name: Bootstrap Alpine container - if: matrix.container - # file: arch check. binutils: nm/strings for symbol and capability checks. - # patchelf: the musl C++ runtime invariant below is verified with it, and without it - # that check fails loudly rather than being skipped. - # libstdc++/libgcc are installed for the TEST HOST only, and deliberately NOT because - # the artifact needs them: the artifact links the C++ runtime statically and must run on - # a bare Alpine image with nothing installed -- scripts/test/linux.sh asserts exactly - # that. They are here so the container can build and run the smoke program. (This - # comment previously said they were "a standard runtime dep ... not something we can - # avoid", which was true of the artifacts as published and is the very thing this - # branch fixed.) - # curl: fetch the (now mandatory) whisper model — Alpine has no curl by default, and - # its absence previously made the model download silently fail (whisper skipped). - run: apk add --no-cache bash git file binutils libstdc++ libgcc curl build-base patchelf - - # actions/checkout has no retry input; its internal helper makes 3 attempts with a RANDOM - # 10-20s sleep between them, so roughly 20-40s of cover. A DNS or TLS blip longer than that - # kills the job before any of our code runs: - # fatal: unable to access 'https://github.com/...': Could not resolve host: github.com - # The action cannot be wrapped: a local composite action needs the repo ALREADY checked out, - # and retry actions only wrap `run:` steps, not `uses:` steps. So wait for the host to be - # reachable BEFORE checkout, with the same exponential-with-jitter backoff the build scripts - # use (4, 8, 16, 32, 64s + jitter), and do NOT sleep after the final attempt -- nothing probes - # again afterwards. Worst case is ~2 minutes of sleep plus the probe timeouts. - # This never fails the job. If the host is still unreachable it warns and lets checkout run, so - # the real error is reported by the action rather than masked here. - - name: Wait for github.com to be reachable - shell: bash - run: | - command -v curl >/dev/null 2>&1 || { echo "curl unavailable - skipping reachability wait"; exit 0; } - delay=4 - for i in 1 2 3 4 5 6; do - if curl -sSf -o /dev/null --max-time 10 "${GITHUB_SERVER_URL:-https://github.com}"; then - if [ "$i" -gt 1 ]; then echo "github.com reachable after attempt ${i}"; fi - exit 0 - fi - if [ "$i" -eq 6 ]; then break; fi - s=$(( delay + (RANDOM % 5) )) - echo "github.com not reachable (attempt ${i}/6) - retrying in ${s}s" >&2 - sleep "$s" - delay=$(( delay * 2 )) - done - echo "::warning::github.com still unreachable after 6 attempts; letting checkout try anyway" - - uses: actions/checkout@v7 - with: - # github.sha, NOT github.ref: for a push run github.ref is refs/heads/main, so each - # matrix cell would check out whatever main's tip is when that cell STARTS. Across a - # multi-hour matrix that lets different cells build different commits, and none of - # them need be the commit the release tags. github.sha is the immutable event SHA and - # is shared with the calling workflow, so every cell builds exactly one tree. - ref: ${{ inputs.ref || github.sha }} - - - name: Download build artifact - uses: actions/download-artifact@v8 - with: - name: ${{ env.VARIANT }} - path: artifacts/${{ matrix.rid }}/native - - - name: Restore executable bits - shell: bash - run: | - # actions/upload-artifact does not preserve the executable bit, so the - # downloaded ffmpeg/ffprobe come back non-executable. Restore them. - for exe in ffmpeg ffprobe ffmpeg.exe ffprobe.exe; do - f="artifacts/${BUILD_RID}/native/${exe}" - [ -f "$f" ] && chmod +x "$f" || true - done - - # Cache a tiny GGML Whisper model so the test runs a REAL af_whisper CPU inference (not just a - # filter-registered check). Stored in the workspace (relative path — works uniformly on every - # OS incl. the native Windows .exe, unlike a git-bash ~/ path) and cached across runs. - - name: Cache Whisper model - id: whisper-cache - uses: actions/cache@v6 - with: - path: whisper-model/ggml-tiny.en.bin - key: whisper-ggml-tiny-en-v1 - # Mandatory, not best-effort: the inference is a gating test, so a failed fetch must fail the - # job (loud) rather than silently drop the check. Cache + retries keep transient HF blips rare. - - name: Fetch Whisper model (mandatory) - shell: bash - run: | - m="whisper-model/ggml-tiny.en.bin" - mkdir -p whisper-model - if [ ! -f "$m" ]; then - # Every matrix cell races for this file on a cold cache, and Hugging Face answers the - # herd with 429. curl's own --retry uses a FIXED delay, so 6 attempts were spent inside - # ~25s and the job failed while the rate-limit window was still open. Back off - # progressively with jitter instead: the cells spread themselves out and later ones find - # the window clear. Worst case is ~7min of waiting, against a >2h matrix. - url="https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.en.bin" - ok=0 - for attempt in 1 2 3 4 5 6 7 8; do - if curl -fsSL --retry 2 --retry-delay 3 --retry-all-errors "$url" -o "$m"; then - ok=1; break - fi - echo "whisper model fetch attempt ${attempt}/8 failed; backing off" >&2 - sleep $(( attempt * 15 + (RANDOM % 20) )) - done - if [ "$ok" -ne 1 ]; then - echo "::error::whisper model fetch failed after 8 attempts"; exit 1 - fi - # A short file means a truncated transfer or an error page that still exited 0. - # The model is 77704715 bytes; anything under 70MB is not it. - sz=$(wc -c < "$m") - if [ "$sz" -lt 70000000 ]; then - echo "::error::whisper model is only ${sz} bytes — truncated download"; rm -f "$m"; exit 1 - fi - fi - # Pass a RELATIVE, colon-free path: the test runs from the workspace (run_functional never - # cd's), so ffmpeg resolves it against cwd on every OS — and unlike an absolute Windows path - # it has no drive-letter ':' to collide with af_whisper's option separator in the filtergraph. - echo "WHISPER_MODEL=$m" >> "$GITHUB_ENV" - - # linux-armhf is 32-bit ARM (ARMv7): NO hosted runner executes it natively — the arm64 - # runners are Ampere/Neoverse-N1, which dropped AArch32. So it MUST run under qemu-user. - # FFmpeg's third-party deps are static-linked into libav*, so the only dynamic deps are the - # base C/C++ runtime — supplied here via the armhf cross-runtime packages (on the amd64 - # archive; they install under /usr/arm-linux-gnueabihf, exactly where linux.sh points qemu's - # -L sysroot). Without this the functional suite now FAILS rather than silently skipping. - - name: Set up qemu-user + armhf runtime (functional cross-test) - if: matrix.rid == 'linux-armhf' - shell: bash - # A stalled mirror must fail fast, not hold the job (apt_get in scripts/lib.sh). - timeout-minutes: 25 - run: | - APT=(-o Acquire::Retries=5 -o Acquire::http::Timeout=30 -o Acquire::https::Timeout=30) - sudo apt-get "${APT[@]}" update -qq - # gcc-arm-linux-gnueabihf: the -dev smoke link must BUILD for armv7, not just run it - # under qemu. Keep the package list on ONE line: an escaped newline written into this - # file literally becomes an argument, and apt then reports it as a missing package. - sudo apt-get "${APT[@]}" install -y -q qemu-user libc6-armhf-cross libstdc++6-armhf-cross libgcc-s1-armhf-cross gcc-arm-linux-gnueabihf - - - name: Test artifact - shell: bash - run: | - set -euo pipefail - chmod +x scripts/test.sh scripts/test/*.sh - if [[ "${BUILD_RID}" == "linux-musl-arm64" ]]; then - # Same reasoning as the build job: GitHub only supports JavaScript - # actions in Alpine containers on x64 runners, so this arm64 runner - # docker-runs the pinned Alpine image for the test itself instead of using - # `container:` on the job (which breaks actions/checkout — see - # linux-musl-x64, which stays on `container:` because its x64 - # runner *is* supported). - # `docker run` pulls the image implicitly, and that pull is a NETWORK operation with no - # retry of any kind -- a registry blip takes the whole build down for a reason that is not - # our code, which is the failure class the curl/git wrappers exist to remove. Observed on - # this branch: "docker: Error response from daemon: received unexpected HTTP status: - # 502 Bad Gateway" pulling quay.io/pypa/manylinux_2_28_x86_64. - # - # Pull explicitly first, with the same exponential+jitter backoff scripts/lib.sh uses, so - # `docker run` below finds the image locally. Retrying the PULL rather than the `docker run` - # matters: re-running the run would repeat the entire build. - _img="alpine:3.24.2@sha256:294b683cb724975bec92580e1e685676bd4b50bda910ddb8c51d4cabeaec77e6" - _delay=4 - for _try in 1 2 3 4 5 6; do - docker pull "${_img}" && break - if [ "${_try}" -eq 6 ]; then - echo "ERROR: docker pull ${_img} failed after 6 attempts" >&2; exit 1 - fi - _wait=$(( _delay + (RANDOM % 5) )) - echo " docker pull failed (attempt ${_try}/6) - retrying in ${_wait}s..." >&2 - sleep "${_wait}" - _delay=$(( _delay * 2 )) - done - docker run --rm -v "${PWD}:/work" -w /work \ - -e BUILD_RID -e WHISPER_MODEL \ - "${_img}" \ - sh -c 'apk add --no-cache bash git file binutils libstdc++ libgcc curl build-base patchelf && chmod +x scripts/test.sh scripts/test/*.sh && bash scripts/test.sh "${BUILD_RID}" "artifacts/${BUILD_RID}/native"' - else - bash scripts/test.sh "${BUILD_RID}" "artifacts/${BUILD_RID}/native" - fi - - # Issue #20: when af_whisper exits 139 on win-x64, exercise_whisper (scripts/test/lib.sh) - # retries once under cdb and leaves the first-run output, the cdb log and (if the crash - # recurred) a full dump in RUNNER_TEMP/whisper-crash. Evidence only -- the test has already - # failed. Usually empty; nothing is uploaded then. - - uses: actions/upload-artifact@v7 - if: always() && matrix.rid == 'win-x64' - with: - name: whisper-crash-${{ env.VARIANT }}-${{ github.run_attempt }} - path: ${{ runner.temp }}/whisper-crash - if-no-files-found: ignore - retention-days: 30 - - - # Gate job — single required status check for branch protection. - all-tests: - if: always() - needs: test - runs-on: ubuntu-latest - steps: - - run: | - if [[ "${{ needs.test.result }}" != "success" ]]; then - echo "One or more desktop test jobs failed" - exit 1 - fi diff --git a/.github/workflows/update-lock.yml b/.github/workflows/update-lock.yml new file mode 100644 index 0000000..32699ea --- /dev/null +++ b/.github/workflows/update-lock.yml @@ -0,0 +1,27 @@ +# The daily lock update: one PR with newer library versions, FFmpeg releases of the same majors and the newest 0.x +# engine, opened as devenvy-bot (so it starts CI and code scanning like any PR) and merged by ci.yml once it passes. +# A new FFmpeg major is reported in the PR and the run summary (ffmpeg-build.yml's notify); adding its targets is a +# person's change. +# +# Permissions: actions: write, contents: write and pull-requests: write (below). +name: Update lock +on: + schedule: + - cron: '41 5 * * *' + workflow_dispatch: + +permissions: {} + +jobs: + update: + uses: devenvy/ffmpeg-build/.github/workflows/update-lock.yml@52201a1204772caf79156ced0954c25407f6b433 # v0.0.5 + permissions: + actions: write + contents: write + pull-requests: write + with: + automerge: true + ci-workflow: ci.yml + app-client-id: ${{ vars.DEVENVY_BOT_CLIENT_ID }} + secrets: + app-private-key: ${{ secrets.DEVENVY_BOT_PRIVATE_KEY }} diff --git a/.gitignore b/.gitignore index 6b151b3..c63f716 100644 --- a/.gitignore +++ b/.gitignore @@ -1,27 +1,15 @@ -# Build artifacts -.build/ -artifacts/ -# Host build tools cached across CI runs (the glslc built by 03_install_packages.sh) -.tools/ +# ffmpeg-build output and work folders +dist/ +build/ -# Stray build/config logs (e.g. an FFmpeg config.log copied out for debugging) -*.log - -# Editor / IDE -*.swp -*.swo -*~ -.vs/ +# editors and OS files .vscode/ -*.user - -# OS junk -Thumbs.db -Desktop.ini +.idea/ +*.swp .DS_Store -# Planning / spec scratch from assisted sessions. These are working artifacts, not -# documentation: they went stale the moment the code moved on (39 factual defects at the -# point they were removed -- stale cell counts, pre-Catalyst assumptions, sample commands -# that no longer run). Keeping them in-tree meant they read as authoritative. +Thumbs.db + +# AI assistant state and working notes +.claude/ .superpowers/ docs/superpowers/ diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md deleted file mode 100644 index 28d851c..0000000 --- a/DEVELOPMENT.md +++ /dev/null @@ -1,623 +0,0 @@ -# Development - -## Project structure - -``` -ffmpeg/ - deps.json # The ledger — FFmpeg versions (.ffmpeg) + library versions & holds - scripts/ - build.sh # Orchestrator — sources the steps below, in order - lib.sh # Shared build helpers (cmake wrapper, build_cmake_dep) - steps/NN_*.sh # One numbered file per build phase (configure → deps → ffmpeg → - # stage → verify → legal); build.sh sources them in sequence - deps/.sh # One script per third-party library — self-guarding on a BUILD_* - # flag, appends its --enable-* to the FFmpeg configure - test.sh # Per-RID test dispatcher → test/.sh - test/.sh # Per-platform checks; test/lib.sh = shared helpers; smoke.c = the - # portable runtime program run on device/emulator/simulator - gen-matrix.sh # Regenerates the coverage matrices from the scripts + each version's configure - gen-coverage.sh # Lists FFmpeg libraries we don't build (used by check-updates) - docs/matrix/README.md # Auto-generated matrix index (do not edit by hand) - docs/matrix/ # Auto-generated coverage matrix per FFmpeg major × license - .github/workflows/ # CI/CD workflows -``` - -**How the build is organized.** `scripts/build.sh` is a thin orchestrator: it resolves the -inputs, then sources each `steps/NN_*.sh` in order (they share one shell environment). Step 6 -(`06_build_libraries.sh`) sources every active `deps/.sh`; each dependency script builds -one static library and appends its `--enable-` flag. The core of adding a library is one -`deps/*.sh`, a `BUILD_*` switch in `02_configure.sh`, and a line in `06_build_libraries.sh` — -but licensing, Renovate coverage, and per-platform gotchas each need a look. See -[Adding a library](#adding-a-library) for the full checklist. - -**Maintaining multiple versions.** the `.ffmpeg` list in `deps.json` is the source of truth for which FFmpeg -releases this repo builds — one exact upstream version per line. Each line is built and -released independently (see [What a merged bump releases](#what-a-merged-bump-releases)), so several major/minor lines -(e.g. `9.0` and `8.1.2`) can be maintained in parallel. **Renovate** keeps each line's point -releases current (8.1.2 → 8.x, grouped with the library bumps into one PR); `check-updates.yml` -only detects a new upstream **major** and opens a PR adding it as a new line (see -[Dependency versions](#dependency-versions)). - -The build downloads a stock upstream FFmpeg release tarball and compiles it — there is no -vendored FFmpeg source. The stock tarball is patched during the build only where a target -requires it (currently `07_build_ffmpeg.sh`'s Mac Catalyst CoreVideo fix); every such patch -lives in `scripts/` and is applied to the pinned upstream release, never vendored. All other -customization is in the `scripts/` tree (which -third-party libraries to build and link, and the per-platform configure flags). - -## Build variants - -Each release covers every platform × license build variant. Each RID is built in **four** -license cells — `gplv3`, `gplv2`, `lgplv3`, `lgplv2` — not one: - -| RID | Platform | Build method | Output | -|---|---|---|---| -| `linux-x64` | Linux glibc x86_64 | manylinux container | shared libs + `ffmpeg`/`ffprobe` | -| `linux-arm64` | Linux glibc ARM64 | manylinux container (ARM runner) | shared libs + `ffmpeg`/`ffprobe` | -| `linux-armhf` | Linux glibc ARMv7 (Raspberry Pi) | Cross-compiled | shared libs + `ffmpeg`/`ffprobe` | -| `linux-musl-x64` | Alpine / musl x86_64 | Native (Alpine container) | shared libs + `ffmpeg`/`ffprobe` | -| `linux-musl-arm64` | Alpine / musl ARM64 | Native (Alpine container, ARM runner) | shared libs + `ffmpeg`/`ffprobe` | -| `win-x64` | Windows x86_64 | Cross-compiled (mingw-w64) | DLLs + `.lib` import libs + `ffmpeg.exe`/`ffprobe.exe` | -| `win-arm64` | Windows on ARM (ARM64) | Cross-compiled (llvm-mingw) | DLLs + `.lib` import libs + `ffmpeg.exe`/`ffprobe.exe` | -| `osx-x64` | macOS Intel | Native | dylibs + `ffmpeg`/`ffprobe` | -| `osx-arm64` | macOS Apple Silicon | Native | dylibs + `ffmpeg`/`ffprobe` | -| `android-arm64` | Android arm64-v8a | Cross-compiled (Android NDK) | `lib/arm64-v8a/*.so` (unversioned) + `include/`, no binaries | -| `android-x64` | Android x86_64 | Cross-compiled (Android NDK) | `lib/x86_64/*.so` (unversioned) + `include/`, no binaries | -| `ios-arm64` | iOS device (arm64) | Cross-compiled (iOS SDK, on macOS) | six `frameworks/*.framework` (dylib + Headers + Info.plist), no binaries | -| `ios-sim-arm64` | iOS simulator (Apple Silicon) | Cross-compiled (simulator SDK) | six `frameworks/*.framework` (lean slice), no binaries | -| `maccatalyst-arm64` | Mac Catalyst (Apple Silicon) | Cross-compiled (macOS SDK, `-target arm64-apple-ios14.0-macabi`) | six `frameworks/*.framework` (dylib + Headers + Info.plist), no binaries | -| `maccatalyst-x64` | Mac Catalyst (Intel) | Cross-compiled (macOS SDK, `-target x86_64-apple-ios14.0-macabi`) | six `frameworks/*.framework` (dylib + Headers + Info.plist), no binaries | - -Each RID is built in 4 license cells: `{rid}-{gplv3,gplv2,lgplv3,lgplv2}` (15 RIDs × 4 = 60 build -jobs). The two axes are **family** — `gpl` (`--enable-gpl`, includes x264 + x265 — except on -the deliberately lean `ios-sim-arm64` slice, which drops both) vs `lgpl` -(`--disable-gpl`, kvazaar for HEVC, no x264/x265) — and **version** — `v3` (`--enable-version3`, -may link Apache-2.0 deps like OpenSSL and Vulkan) vs `v2` (GPLv2 / LGPLv2.1, no `--enable-version3`, -no Vulkan). The `lgplv2` series is the App-Store-safe one (v3's anti-tivoization terms are -incompatible with the Apple App Store); it exists chiefly for the iOS App Store build. The two iOS -slices (`ios-arm64`, `ios-sim-arm64`) plus Mac Catalyst are published as one combined tarball -per licence cell containing **six** `.xcframework`s — one per `libav*` library, each carrying -three platform slices (iOS device, iOS simulator, Mac Catalyst universal). Not one combined -`.xcframework` per license cell — three slices, with the two Catalyst RIDs `lipo`-fused into a -single universal arm64 + x86_64 slice (an `.xcframework` holds at most one framework per -platform+variant). -Desktop targets additionally ship a `-dev` archive (headers, plus MSVC import libraries on Windows). - -**Why build the glibc Linux targets in a container?** `linux-x64` and `linux-arm64` build inside -the **stock** [`manylinux_2_28`](https://github.com/pypa/manylinux) image (AlmaLinux 8, glibc -2.28) — pulled unmodified from `quay.io/pypa`, no custom image to maintain — via `docker run` -from an ordinary Ubuntu runner. That pins the binaries' runtime **glibc floor low** (they run on -RHEL/Alma 8+, Debian 10+, Ubuntu 18.10+) while still compiling with a modern gcc-toolset-14 — a -combination a stock Ubuntu runner can't give (new Ubuntu = high glibc floor; old Ubuntu = a gcc -too old for the C++ deps). The bare image is provisioned at build time by `03_install_packages.sh` -(its `BUILD_CONTAINER=manylinux` branch: dnf toolchain + meson from a bundled CPython + patchelf -0.18 + glslc from source), so nothing is baked into an image. `checkout`/test/upload stay on the -host, so the test step also proves the low-floor binary runs on the runner's newer glibc. Every -other target keeps its runner (`linux-armhf`/`win-x64`/`win-arm64`(build)/`android` on Ubuntu, -`linux-musl` in an Alpine container, `osx`/`ios` on macOS). Windows *tests* run natively on -Windows runners — `win-arm64` on `windows-11-arm`, so the ARM64 binaries are actually executed. - -**Why cross-compile Windows from Linux?** `win-x64` is built with the mingw-w64 toolchain on a -Linux runner — the same approach the upstream FFmpeg project and every major FFmpeg build -service use. It keeps Linux + Windows + Android on one host and one build script, and it loses -nothing: Media Foundation, D3D11VA/DXVA2, AMF, NVENC and QSV all compile against the mingw-w64 -SDK headers. MSVC consumers are handled by generating a COFF import library (`.lib`) per DLL -via `gendef` + `llvm-dlltool`, so a Visual Studio / CMake project links the DLLs directly. - -**Why `win-arm64` uses llvm-mingw, not mingw-w64.** mingw-w64 ships no aarch64 GCC, so the -ARM64 target is cross-compiled with [llvm-mingw](https://github.com/mstorsjo/llvm-mingw) -(clang + compiler-rt + libc++) — pinned in `deps.json` and fetched in -`03_install_packages.sh`. Practical consequences, all handled in `platform/windows.sh`: -- The C++ runtime is **libc++**, not libstdc++. Deps advertise `-lc++` in their `.pc` files, - and a bare `-lc++`/`-lunwind`/`-lpthread` resolves to a *shared* import library. Those are - rewritten to `-l:libc++.a` / `-l:libunwind.a` / `-l:libwinpthread.a` in - `07_build_ffmpeg.sh`, because `-static-libgcc`/`-static-libstdc++` are ignored on `-shared` - links and the resulting DLL imports would not exist on the target machine. -- `CXX_RT_LIB` carries the C++ runtime for dep probes: FFmpeg's `configure` link tests run - through the **C** driver, which adds no C++ runtime of its own. -- No CUDA/NVENC/NVDEC/AMF/libvpl (no ARM64 SDKs); d3d11va, dxva2, MediaFoundation and - SChannel are all kept. SVT-AV1 is off and whisper uses the CPU backend. - -**Delivery format:** -- **Desktop** — flat runtime tarball: binaries, shared libraries, and `legal/` only (no - headers). Dev files ship separately as `ffmpeg-{ver}-{variant}-dev.tar.gz` (the `include/` - headers, plus `lib/*.lib` MSVC import libraries for Windows), so the runtime download stays - lean and consumers don't pick up headers/import libs at runtime. -- **Android** — tarball with `include/` headers + jniLibs-style `lib//*.so` - (`arm64-v8a` for `android-arm64`, `x86_64` for `android-x64`) + `legal/` - (link-only artifact, so headers stay in the main tarball). - Sonames are normalized to unversioned `lib*.so` so Android's loader/Gradle accept them. -- **iOS** — one `.xcframework` per `libav*` library, bundling the device (`ios-arm64`) and - simulator (`ios-sim-arm64`) slices, packaged per license with headers + `legal/`. The slices - are **dynamic** dylibs (iOS's old static `.a` is gone — every platform now ships dynamic - libraries). Dynamic is required for the App-Store `lgplv2` build: LGPLv2.1 §6 obliges the end - user to be able to relink the app against a modified library, which a dynamic framework - satisfies inherently but static linking cannot (it would force shipping object files). The - individual iOS slices are **not** published on their own — they are delivered as xcframeworks. - -Mobile builds drop the `ffmpeg`/`ffprobe` executables (the libraries are consumed directly) -and enable platform hardware decode (MediaCodec / VideoToolbox). - -## LGPL vs GPL - -**LGPL builds** can be used in proprietary/closed-source applications without releasing your -application source, as long as FFmpeg remains dynamically linked (shared libraries). LGPL -builds **cannot include GPL-licensed encoder libraries** like libx264 or libx265: - -- H.264/H.265 **decoding** (software) works normally — FFmpeg's built-in decoders are - LGPL-compatible. -- H.264/H.265 **hardware encoding** (NVENC, VAAPI, QSV, VideoToolbox, MediaFoundation, AMF) - works normally — these are API wrappers, not GPL code. -- **Software H.264 encoding** is available in every build via **OpenH264** (BSD, no GPL - obligation), and **software H.265 encoding** via **kvazaar** (BSD) — the permissive - counterparts that give the LGPL builds software encoders without a GPL obligation (and a - fallback where hardware HEVC encode isn't available). The GPL builds' **libx264/libx265** are - higher quality, so where the GPL is acceptable they remain the better choice; kvazaar is - dropped there (x265 supersedes it). -- **VP8/VP9 encoding** (libvpx) and **AV1 encoding** (libaom, SVT-AV1) — with platform gaps: - `ios-sim-arm64` drops libvpx and libaom, and SVT-AV1 is absent on armhf, Android, iOS and - Catalyst. See the per-cell matrix rather than assuming these are in all - builds — those are BSD-licensed and LGPL-compatible. - -**GPL builds** (except the lean `ios-sim-arm64` simulator slice, which disables both) include -**libx264** (H.264 software encoder) and **libx265** (H.265 software -encoder), enabling full software encoding. Distributing an application that uses a GPL build -requires that application to comply with the GPL (source disclosure). - -**Rule of thumb:** ship LGPL if you link FFmpeg into a closed-source app; use GPL for internal -tooling or GPL-compatible projects that need software H.264/H.265 encoding. - -**License version — v3 and v2 both ship.** The matrix carries both a v3 and a v2 line of each -family, four cells in total (GPLv3, GPLv2, LGPLv3, LGPLv2.1). The **v3** cells set -`--enable-version3`, which lets them link Apache-2.0 deps (OpenSSL 3.x for TLS, and Vulkan) — -Apache-2.0 is compatible with version 3 of the (L)GPL but not with 2.1/2. The **v2** cells omit -`--enable-version3` (so GPLv2 / LGPLv2.1) and drop Vulkan; whisper falls back to CPU where v3 -used the Vulkan backend. The v2 series is the App-Store-safe one: v3's install-information -(anti-tivoization) terms are incompatible with the Apple App Store, so the iOS App Store build is -`lgplv2`. LGPL (either version) still grants the dynamic-linking permission — ship it inside a -proprietary app as a replaceable shared library. `04_select_license.sh` selects the cell and -`10_write_legal.sh` writes each artifact's `legal/LICENSE-NOTICE.txt` stating the effective -license and why, shipping the matching COPYING text (GPLv2/GPLv3/LGPLv2.1/LGPLv3 as appropriate). -Every bundled dependency's own license also ships under `legal/licenses//`. - -## Build script - -The unified build script (`scripts/build.sh`) accepts environment variables: - -| Variable | Required | Default | Values | -|---|---|---|---| -| `BUILD_RID` | Yes | — | `linux-x64`, `linux-arm64`, `linux-armhf`, `linux-musl-x64`, `linux-musl-arm64`, `win-x64`, `win-arm64`, `osx-x64`, `osx-arm64`, `android-arm64`, `android-x64`, `ios-arm64`, `ios-sim-arm64`, `maccatalyst-arm64`, `maccatalyst-x64` | -| `BUILD_LICENSE` | No | `lgpl` | `lgpl`, `gpl` — family (`--disable-gpl` vs `--enable-gpl`) | -| `BUILD_LICENSE_VERSION` | No | `3` | `3` (`--enable-version3`) or `2` (GPLv2 / LGPLv2.1, no version3) | -| `ANDROID_NDK_HOME` | optional | auto-detected | path to the Android NDK (r26+). `platform/android.sh` finds an installed NDK via `ANDROID_NDK_LATEST_HOME`/`ANDROID_SDK_ROOT`; set this only to override or when detection fails. | -| `FFMPEG_VERSION` | No | first line of the `.ffmpeg` list in `deps.json` | e.g., `8.1.2` | -| `SKIP_DEPS` | No | `false` | `true`, `false` — skip apt/apk/brew dependency installation | - -`android-*` builds run on Linux/WSL with the NDK; `ios-*`, `osx-*` and `maccatalyst-*` builds -run on macOS with the -Xcode command-line tools. - -### Local build examples - -```bash -# Linux x64, GPL, skipping apt install (deps already present) -SKIP_DEPS=true BUILD_RID=linux-x64 BUILD_LICENSE=gpl bash scripts/build.sh -# Output: artifacts/linux-x64/native/ - -# Windows x64, LGPL, cross-compiled with mingw-w64 (on Linux) -SKIP_DEPS=true BUILD_RID=win-x64 BUILD_LICENSE=lgpl bash scripts/build.sh - -# Android arm64, LGPL (needs the NDK; runs on Linux/WSL) -ANDROID_NDK_HOME=/path/to/android-ndk-r26d \ - SKIP_DEPS=true BUILD_RID=android-arm64 BUILD_LICENSE=lgpl bash scripts/build.sh -# Output: artifacts/android-arm64/native/ (include/ + lib/arm64-v8a/*.so) - -# iOS device, LGPLv2.1 (the App-Store-safe cell: no version3, no Vulkan; TLS is still -# present here via SecureTransport — it is Linux/Android/Catalyst lgplv2 that has none) -SKIP_DEPS=true BUILD_RID=ios-arm64 BUILD_LICENSE=lgpl BUILD_LICENSE_VERSION=2 bash scripts/build.sh -``` - -The build ends with an in-process static verification gate (`09_verify_build.sh`, all RIDs) -that fails on regressions: the Whisper filter is enabled, `lgpl` builds contain no GPL -components, the platform hardware decoder is registered, mobile headers are present, and Android -sonames are unversioned. - -## Testing - -Post-build, `scripts/test.sh ` dispatches to `test/.sh` -(shared helpers in `test/lib.sh`). Coverage is layered so *something* runs on every target, -however it's built: - -- **Structural (every target, any host).** Reads the artifact without executing it: arch/format, - SONAMEs, exported `av*_version` symbols, the license boundary and enabled features (harvested - from FFmpeg's embedded `./configure` string), the TLS backend, and platform specifics - (Android `libmediandk`/`libc++_shared.so`, unversioned sonames, headers present). `nm`/ - `readelf`/`strings` read foreign-arch binaries fine, so this works from any host. -- **Functional (where the target runs on the runner).** Executes `ffmpeg`: version, filter/ - decoder/protocol enumeration (asserting `https`/`tls` are present on every cell **except** - `lgplv2` on Linux/Android/Catalyst, which drops TLS and is verified to have none; Windows, - macOS and iOS keep their native backend in every cell), and an encode→decode round-trip — natively - on matching hosts (Linux on Linux, **Windows on a real Windows runner**, macOS on macOS), or via - **qemu-user** for cross Linux arches. Execution is the primary signal; a missing binary- - inspection tool (e.g. `file` on a minimal shell) skips a structural check rather than failing. -- **Mobile (no `ffmpeg` binary).** `test/smoke.c` is a portable libav program (encode→decode + - whisper filter, plus `https`/`tls` where the cell has a TLS backend — the check follows the - configured backend, so it is asserted absent only on Linux/Android/Catalyst `lgplv2`, and - asserted present on iOS `lgplv2`, which has SecureTransport) - compiled against the artifact. Compiling+linking it with no - undefined symbols is a real **ABI check** that runs in the `test-mobile` workflow (NDK/Xcode - present on the runner). - Executing it is the **runtime** layer: `test/ios-run.sh` runs it on the iOS **simulator** via - `simctl` (native on the Apple-Silicon runner), and `test/android-run.sh` runs it on an - **x86_64 emulator** — `android-x64` natively, `android-arm64` via the API-35 image's native - bridge (translated). The on-device run is what caught the missing `libc++_shared.so` - bundling — a gap structural checks can't see. - -## CI/CD - -- **CI** (`ci.yml`) — On pull requests to `main`. A `resolve` job diffs the PR (via - `scripts/ci/select-versions.sh`) and builds only the lines it affects: a `scripts/**` change → - all tracked versions; a `deps.json` **library** bump → only lines whose resolved deps changed - (a line that whole-line-pins the bumped dep is skipped); a `deps.json` **`.ffmpeg`** version - change → the added/changed lines; docs-only → nothing. It then chains build → desktop test + - mobile test against the uploaded artifacts, gated by the aggregate `build`/`test` checks plus a - `docs-matrix` drift check. Both PR and release matrices run with **fail-fast disabled** - (`ci.yml` and `release.yml` each pass `fail_fast: false`), so one failing cell never hides the - state of the others. -- **Release** (`release.yml`) — Runs on pushes to `main` that change `deps.json` (FFmpeg versions - or libraries) or a build recipe (`scripts/**`, excluding tests), and can also be started - manually. A `prepare` job uses the same `select-versions.sh` to (re)build only the affected - lines — a `deps.json` change touches only the lines whose resolved deps or `.ffmpeg` version - changed; a build-recipe change rebuilds every line. Tests gate the release (build → test + test-mobile - must pass before the tag/publish). Each selected version gets its own `{version}.{build}` tag + - GitHub Release — all variants built and packaged (desktop/Android tarballs; a `publish-ios` job - assembles the iOS `.xcframework`s on a macOS runner). Only the **highest** tracked line is - marked GitHub "Latest" (`--latest=true`), so an older-major maintenance release never steals the - badge. Bumping one line publishes only that line. -- **Renovate** (`renovate.yml` + `renovate.json`) — Weekly. Bumps the library `defaults` **and** - the FFmpeg `.ffmpeg` point releases in `deps.json`, batched into one grouped PR; it never touches - the `overrides` holds. The ledger is read with JSONata managers (structural queries over the - parsed JSON), so key order and extra fields in `deps.json` don't affect tracking. Pins that live - in workflow files (Renovate's own version, the Alpine build image) get a separate PR. PRs use - `UPDATE_PR_TOKEN` so CI runs on them. Workflow actions are handled separately by Dependabot - (`.github/dependabot.yml`). -- **Check Updates** (`check-updates.yml`) — Weekly. Does only what Renovate can't: when a newer - FFmpeg **major** appears upstream, it opens a PR adding it to `.ffmpeg` (plus the matching - Renovate per-series rule) so Renovate tracks the new line going forward. Uses `UPDATE_PR_TOKEN` - so CI runs; merging triggers the release workflow. - -**Build/test are separate reusable workflows** (`build.yml`, `test.yml`, `test-mobile.yml`), so -tests can grow and re-run without rebuilding. `build.yml` builds each variant and uploads its -artifact; `test.yml` (desktop: linux/win/macOS **execution** — Windows on a real Windows runner) -and `test-mobile.yml` (Android/iOS ABI link-check + emulator/simulator) download those artifacts -and run. Both `ci.yml` (PRs) and `release.yml` chain build → test + test-mobile; in `release.yml` -a failing test blocks the tag/publish. Mobile is split out because its emulator/simulator setup is -slow and fragile and shouldn't gate the fast desktop checks. - -For manual releases, run the **Release** workflow from GitHub Actions. Do not create a GitHub -Release by hand, because manual Releases do not build or attach artifacts. - -## Hardware acceleration by platform - -Which hardware acceleration each platform builds — CUDA/NVENC/NVDEC, VAAPI, QSV, V4L2-M2M, -D3D11VA/DXVA2, AMF, MediaFoundation, MediaCodec, VideoToolbox/AudioToolbox, Vulkan — is enumerated -**per cell** in the auto-generated [build matrix](docs/matrix/README.md) (its Hardware-acceleration -section), which is the single source of truth — this doc doesn't duplicate it (that only drifts -stale). What's worth saying here is *how* those libraries are packaged into the artifact: - -The Linux builds are **self-contained**: the VAAPI/QSV/libdrm dispatch libraries are -static-linked on the glibc *and* musl RIDs, so `ffmpeg` starts on a bare system with no package -install. The Vulkan loader is bundled on `linux-x64`, `linux-arm64` and both `linux-musl-*` -RIDs — **`linux-armhf` bundles none** and reaches Vulkan through the system loader. NVIDIA -(CUDA/NVENC/NVDEC) is loaded at runtime via `dlopen`, not linked in, so it is silently -unavailable if absent. FFmpeg reaches Vulkan the same way; note that Whisper's Vulkan backend -does *not* — it links the loader directly on the Linux RIDs that have one, the system loader on -Android, and a runtime-resolving shim on Windows. To actually **use** hardware acceleration you still need the GPU -**driver** (Intel `intel-media-va-driver`, AMD `mesa-va-drivers`, the NVIDIA driver, or -`mesa-vulkan-drivers` for Vulkan). - -Vulkan is a **v3-only** feature (the `v2` cells drop it — Vulkan-Headers are Apache-2.0). It's -provided by the system driver on Android, a runtime-resolving static shim on Windows, a bundled -libc-only loader on Linux x64/arm64 and both musl RIDs (not armhf), a bundled loader plus -**MoltenVK** on macOS, and statically linked MoltenVK on iOS and Catalyst. It powers FFmpeg's -GPU filters everywhere it is enabled. Whisper's GPU backend is separate: **Vulkan** on Linux -x64/arm64, musl and Android; **Metal** on macOS, iOS and Catalyst; and **CPU** on `linux-armhf` -and `win-arm64`. The auto-generated [build matrix](docs/matrix/README.md) is the exact -per-cell source of truth. - -## Software codec & utility libraries - -Most builds link a set of LGPL-compatible (BSD/MIT/permissive) codec and utility libraries — -though coverage is per-RID and per-cell, not universal (SVT-AV1, WebP, kvazaar, TLS and the -lean simulator's omitted codec/text stack all vary). The per-cell matrices under `docs/matrix/` -are authoritative; this list is orientation, not a guarantee — -AV1 (dav1d/libaom/SVT-AV1), VP8/VP9, Opus, MP3 (LAME), Vorbis, OpenH264, WebP, zimg, libass, -FreeType, whisper.cpp, a TLS backend, and **kvazaar** (permissive H.265 encode — the LGPL -counterpart to x265, and a software fallback where hardware HEVC encode isn't available). The -**GPL builds** swap in **libx264** and **libx265** (higher-quality H.264/H.265) and drop -kvazaar, which x265 supersedes. - -**Which library is built on which platform — and which ones we deliberately don't build — lives -in the auto-generated [docs/matrix/README.md](docs/matrix/README.md)**, an index to one matrix per -maintained FFmpeg major × license cell (`docs/matrix/ffmpeg--.md`). It derives from -the build scripts and each version's own configure, so it never drifts; the per-matrix footnotes -explain the platform gaps (SVT-AV1 needs 64-bit; fontconfig is built on Linux and macOS and -disabled on Windows, Android, iOS and Catalyst, where fonts are supplied by the platform or by -explicit font-file paths; etc.), -and the index flags libraries that differ between versions. Don't restate that coverage in prose -here — update the generator, not this file. - -Two build-mechanics notes that aren't about coverage: -- **TLS backend (depends on the cell) on Linux/Android:** the **v3** cells build **OpenSSL** - (Apache-2.0, allowed by `--enable-version3`); the **gpl-2** cell builds **GnuTLS** (which pulls - in GMP + nettle + libtasn1 — fine under GPLv2); the **lgpl-2** cell on those platforms has **no TLS at all** (no - `https`/`tls`), because GnuTLS's GMP + nettle deps are dual LGPLv3+/GPLv2+ (never LGPLv2.1) and - no other FFmpeg TLS backend is LGPLv2.1-compatible, so a genuine LGPLv2.1 build must drop TLS. - **Windows, macOS and iOS** are unaffected by the v2/v3 split: Windows uses OS-native - **SChannel** and macOS/iOS **SecureTransport** in every cell, with no dependency. **Mac Catalyst - is not** — SecureTransport is unavailable on macabi (the SDK marks `SSLRead`/`SSLWrite` no longer - supported and `tls_securetransport.c` fails to compile, so `apple.sh`'s Catalyst arm omits - `--enable-securetransport`), which puts it on the Linux/Android ladder: OpenSSL on v3, GnuTLS on - gplv2, and no TLS at all on lgplv2. (`--disable-autodetect` is set, so - each backend is requested explicitly.) See [License version](#lgpl-vs-gpl). -- **x265** tracks the latest release on every architecture, from its GitHub home - (`Multicorewareinc/x265`; Bitbucket stopped at 4.2). The former 3.6 hold on the ARM64 targets was - removed in issue #6 — the gpl cells now prove an actual libx265 encode→decode round-trip, not - just registration. It builds with `-DENABLE_ASSEMBLY=OFF` under the NDK/iOS toolchains, where its - aarch64 asm won't assemble. - -## Adding a library - -A checklist for adding a bundled dependency (an FFmpeg external library, or an internal -sub-dependency another lib needs). Work top-to-bottom — the **⚠** items are where past -additions broke CI, usually only on one platform. - -1. **Pin it in the ledger — [`deps.json`](deps.json).** Add a `.defaults` entry: `origin` + - exactly one ref (`tag`/`branch`/`commit`) + **`datasource`** (`github-tags`, etc.). The - `datasource` is what makes **Renovate** track it — omit it and the lib silently stops - getting updates. See [Dependency versions](#dependency-versions) for the full ledger rules. - **⚠ Never provision a dep (or a build-time tool it needs) with a raw unpinned `git clone` - outside the ledger** — it tracks upstream `master` and drifts (that is how the manylinux - `glslc` build broke on a glslang change). Clone with `--branch "$(dep_version )"` and - give it a ledger entry so Renovate covers it. - -2. **Declare the flag — `scripts/steps/02_configure.sh`.** Add `BUILD_MYLIB=1` (with the inline - `# shellcheck disable=SC2034` the siblings carry). All-cells → `1`; if it needs gating - (`--enable-version3`, Vulkan, a platform that has it), set `0` and enable it only where it - qualifies, next to the existing gates in `scripts/platform/.sh` / `04_select_license.sh`. - -3. **Write `scripts/deps/mylib.sh`.** Copy the closest sibling (`soxr.sh`/`libxml2.sh` for CMake, - `harfbuzz.sh` for meson): guard on `BUILD_MYLIB`, build (`build_cmake_dep` / meson), append - `CONFIGURE_FLAGS+=(--enable-mylib)`. The ledger name (step 1) must match the `clone_dep` / - `build_cmake_dep` first arg; the `BUILD_*` guard must match step 2. Confirm the exact - `--enable-*` against `ffmpeg configure --help` (it isn't always `--enable-lib`). A - sub-dependency FFmpeg doesn't consume appends no flag. - - **⚠ `set -e` footgun:** a bare `[ test ] && cmd` as the *last* line of a sourced script - aborts the whole build when the test is false. Use `if … fi`. - - **⚠ C++ libraries** self-supply the runtime (pkg-config doesn't): append the runtime this - RID uses — `-lstdc++` on glibc/win-x64, **`-l:libstdc++.a` on musl** (the artifact must not - depend on a host C++ runtime), `-lc++` on Apple/Android, `-l:libc++.a` on win-arm64 - (GNU/mingw-w64) / `-lc++` (apple, android) / `-l:libc++.a` (win-arm64, via `CXX_RT_LIB`) to `EXTRA_LIBS`, plus `-llog` on android if the lib - calls Android logging (libjxl did). See `libjxl.sh`/`libvmaf.sh`. - - **⚠ Cross `find_library`:** if the lib locates *other* built deps via CMake `find_package`, - add `-DCMAKE_FIND_ROOT_PATH="${DEPS_DIR}"` — the NDK toolchain (unlike win/armhf/ios) omits it. - - **⚠ Broken `.pc`:** some libs emit malformed pkg-config Libs (OpenJPEG's `-l-lpthread` / - `-l-pthread`) that fail FFmpeg's static link test — repair with a portable - `sed -i.bak … && rm -f ….bak` (see `openjpeg.sh`). - - **⚠ Apple case-insensitive FS:** a source file whose name case-collides with the cmake - build dir breaks the configure on macOS/iOS (google/highway ships a Bazel `BUILD` file → - clashes with `build` → "Unable to (re)create ... pkgRedirects"). `build_cmake_dep` builds - in `_build` to avoid this; a bespoke cmake call must pick a non-colliding `-B` dir too. - - **⚠ iOS executable install:** `install(TARGETS RUNTIME …)` fails on iOS (executables - need a BUNDLE destination). Disable a dep's CLI/tools if it installs one — brotli needed - `-DBROTLI_BUILD_TOOLS=OFF`. - -4. **Source it in order — `06_build_libraries.sh`.** After everything it consumes (lcms2 before - libjxl and libplacebo; brotli → highway → libjxl). - -5. **Licensing — check every cell, including transitive static deps.** A lib and everything it - statically links must fit each of the 4 license cells (see [LGPL vs GPL](#lgpl-vs-gpl)). The - **LGPLv2.1 / App-Store** lane is strict: no Apache-2.0 (needs version3), no GPLv3-only parts. - Elect the compatible option on dual-licensed deps (highway → BSD-3), keep optional GPLv3 - plugins off (lcms2's `fastfloat`/`threaded`), and gate to v3 anything that truly needs version3. - -6. **Build-time packages — `⚠` check Alpine specifically.** A tool the lib's build needs must be - in each container's package list: `PKGS` (apt), the manylinux `DNF_PKGS` in - `03_install_packages.sh`, and **`PKGS_APK`** (Alpine) in `scripts/platform/linux.sh`. Alpine - ships **busybox stubs** — its `xxd` lacks `-i`, so libvmaf's model embedding failed on musl - until the real `xxd` package was added. The manylinux (glibc) images had no `xxd` at all, and - there was **no clean fallback**: libvmaf's meson marks `xxd` `required: false` and emits its - built-in models only inside `if xxd.found()`, so those artifacts shipped a `libvmaf` filter - that registered and then returned `-EINVAL` for its own default model. It is a hard build - failure now. A tool can be fine on three platforms and quietly wrong on the fourth. - -7. **Regenerate the matrix.** `bash scripts/gen-matrix.sh` — no Android NDK needed; it builds its - own NDK-shaped stub, so the output is identical on any host. - FFmpeg-facing libs appear automatically; if one shows as a bare token, add a category + label - to the maps in `gen-matrix.sh`. Commit the regenerated `docs/matrix/*.md` (the `docs-matrix` - gate enforces zero drift). - -8. **Vet locally on ALL cross-compilable platforms before the PR.** CI rounds are ~2.5h; local - cross builds catch the platform breaks in ~30-60 min. Build **linux-x64, linux-arm64, - linux-musl-x64 (Alpine — genuinely different), linux-musl-arm64, linux-armhf, win-x64, - win-arm64, android-arm64, android-x64** — not just linux-x64. Only **osx/ios** need - a macOS runner. - Done is NOT "it compiled". `config.h` showing `CONFIG_MYLIB=1` is an intermediate result: it - says configure accepted the library, not that anything it provides survived into the artifact. - That distinction is the whole reason this repo shipped `--enable-vulkan` with zero Vulkan - filters on 9 of 15 RIDs. **Done = the component the library provides is REGISTERED in the - staged artifact on every applicable cell** — add a row to `scripts/test/capabilities.tsv` - naming it, and confirm the capability check passes. `config.h` is worth a glance on the way - (a lib that fails to link is silently autodetect-disabled) but it is not the finish line. Local-env notes: the harness lives in the **Ubuntu-24.04** WSL distro - (`wsl.exe -d Ubuntu-24.04`); **⚠ root-clean reused build dirs** (`docker run --rm -v "$DST:/work" - … rm -rf /work/.build /work/artifacts`) — docker leaves root-owned files a host `rm` can't - delete, and a stale target-arch `glslc` once broke a rebuild. `gen-matrix` needs no NDK: it - creates an NDK-shaped stub itself (it only reads `BUILD_*` flags and never invokes a compiler), - which is also what keeps its output byte-identical across hosts. - -9. **Gates:** `shellcheck` (inline per-line disables only, never file-wide), `jq -e . deps.json`, - `bash scripts/deps/ledger-validate.sh`, `bash scripts/ci/select-versions-test.sh`, matrix zero-drift. - -**Files touched per library:** `deps.json` · `02_configure.sh` · `deps/.sh` · -`06_build_libraries.sh` · `gen-matrix.sh` (only if unlabeled) · a platform/`03` package list (only -if it needs a build tool) · regenerated `docs/matrix/`. - -## Dependency versions - -Every third-party library's version is pinned in one file — **[`deps.json`](deps.json)**, the -dependency ledger — not scattered across the `scripts/deps/*.sh` build scripts. The scripts read -it through a small loader and clone each dep at the pinned ref. - -### The ledger — `deps.json` - -Two blocks: - -- **`defaults`** — one entry per dependency: an `origin` (clone URL) plus exactly one ref - (`tag`, `branch`, or `commit`), and, for the Renovate-tracked deps, a `datasource` (+ optional - `registryUrl`). This is the version every build uses unless an override says otherwise. -- **`overrides.`** — per-FFmpeg-major holds (`"8"`, `"9"`). List a dep here only when it - must differ from its default for that line. Each override carries a required **`reason`**, plus: - - an optional **`issue`** — present ⇒ a *temporary blocker* to revisit (the linked issue is the - reminder to drop the hold); absent ⇒ a *permanent compat fact* (e.g. "8.x's configure caps - this lib at 3.x"). - - an optional **`platforms`** array — scopes the hold to specific RIDs. Without it the hold - covers every platform on that major; with it, only the listed RIDs use the override and every - other platform falls through to the default. - -Example (hypothetical `libfoo`) — track latest everywhere except the ARM64 targets, held at 3.6. -The `reason` should quote the real error and link the upstream report that actually describes it; -the x265 hold this example used to show was removed in issue #6 because its cited reports did not: - -```jsonc -"overrides": { - "9": { - "libfoo": { - "origin": "https://github.com/example/libfoo.git", - "tag": "3.6", - "reason": "libfoo 4.0+ fails to compile on aarch64: (upstream #NNN) …", - "issue": 123, - "platforms": ["linux-arm64", "linux-musl-arm64", "win-arm64", "osx-arm64", "maccatalyst-arm64", "ios-arm64", "ios-sim-arm64", "android-arm64"] - } - } -} -``` - -### How the build resolves a version - -Each `scripts/deps/.sh` calls the loader in [`scripts/deps/lib.sh`](scripts/deps/lib.sh) -instead of hardcoding a clone: - -- `clone_dep ` — resolve, `git clone`, and checkout the ref. If the entry has a - `mirror` (an identical read-only copy, e.g. a project's official GitHub mirror) and the origin - is down, it falls back to the mirror. Single-host outages — SourceForge, gitlab.freedesktop.org, - ftp.gnu.org, each down for hours in one week — otherwise fail every PR at the same step. - Add a mirror only after `bash scripts/ci/mirror-parity-test.sh` shows it serving the pinned ref - at the same commit; re-run it after a version bump. -- Tarball-only deps download through `fetch_tarball ...` (scripts/lib.sh), which tries - each URL in order — e.g. SourceForge then Debian's byte-identical `.orig.tar.gz`, or kernel.org's - GNU mirror then ftp.gnu.org. -- `dep_version ` — just the resolved ref string (used by the tarball deps and to stamp - `.pc` files). - -Resolution precedence: **`overrides[FFMPEG_MAJOR][name]`** (when it applies to this `BUILD_RID`) -**else `defaults[name]`**. A platform-scoped override applies only when the build's RID is in its -`platforms` list. The loader fails the build loudly if a dep is missing from the ledger, -malformed, or `jq` is unavailable — a mis-resolved dependency must stop the build, not silently -clone the wrong thing. `bash scripts/deps/ledger-validate.sh` checks the ledger's shape -(origin + exactly one ref; every override has a reason; `platforms` are known RIDs). - -### Bumping a dependency (and FFmpeg) - -- **Automatically:** self-hosted **Renovate** ([`renovate.json`](renovate.json) + - [`.github/workflows/renovate.yml`](.github/workflows/renovate.yml)) watches, weekly: - - every dependency in the `defaults` block of `deps.json` — tag pins via git-tags (any entry - with a `tag` and a `datasource` key), tarball deps with no git remote (gmp, libmp3lame, libgsm, - opencore-amr, vo-amrwbenc; any entry with a `releasesUrl`) via a custom datasource reading the - upstream release listing, and commit pins (x264, vulkan-shim) as git-refs digests against - the branch recorded in `digestBranch`. These are JSONata queries over the parsed ledger, not - regexes over its text, so reordering or annotating an entry cannot drop it from tracking. - Scoped to `defaults` only: it never edits an **override**, which is where a deliberate - per-platform hold lives, and - - each **FFmpeg** line in the `.ffmpeg` list in `deps.json`, constrained to **its own major** - — any newer release within the major, patch or minor alike (9.0.1 → 9.0.2 → 9.1.0), never a - cross-major jump (9.x → 10.x). - - It batches all of these — libraries **and** FFmpeg point bumps, major/minor/patch/digest alike — - into **one grouped PR** per run. Majors used to be split out for individual review, but every - update edits `deps.json`, so concurrent PRs only conflict; hold a specific major back by pinning - it in `overrides` with a tracking issue instead. Pins that live in **workflow files** (the - `renovate-version` in `renovate.yml`, the build/test container images below) are grouped into - their own PRs, because a token without the workflow scope makes Renovate discard the whole - branch, and that must not take the ledger bumps down with it. Workflow **actions** are handled - separately by **Dependabot** ([`.github/dependabot.yml`](.github/dependabot.yml)); Renovate never - touches them. -- **Build/test container images** (Alpine for musl, manylinux_2_28 for glibc, Debian bookworm for - armhf) are the toolchain, so they are pinned `tag@sha256` in `build.yml`/`test.yml` — never - `:latest` — and Renovate bumps them in their **own** PR (`build container images`), apart from - the ledger batch because that PR edits `.github/workflows/`. Merging it rebuilds and releases - every FFmpeg line (`select-versions.sh` treats a changed `@sha256:` line like a recipe change), - so merge it at the cadence a toolchain change deserves; Renovate keeps the one PR rebased. - `scripts/ci/image-pins-test.sh` fails any ref that is unpinned or that the Renovate regex no - longer matches. -- **A new FFmpeg major line** (e.g. 10.0) is the one thing Renovate can't do — it edits - existing values, not add lines. [`check-updates.yml`](.github/workflows/check-updates.yml) detects - a new upstream major and opens a *separate* PR adding the parallel line (a human-reviewed change: - new sonames / configure flags / libraries worth enabling). When you adopt a new maintained - series, add its 2-line `matchCurrentVersion`/`allowedVersions` rule to `renovate.json` so Renovate - tracks that line's point releases too. -- **By hand:** edit the `tag`/`commit` in `deps.json` (or the version in the `.ffmpeg` list in `deps.json`), run - `bash scripts/deps/ledger-validate.sh`, regenerate the matrices (`bash scripts/gen-matrix.sh`), - and open a PR. - -### What a merged bump releases - -`ci.yml` (on the PR) and `release.yml` (on merge to main) both pick the affected lines through -`scripts/ci/select-versions.sh`: - -- a **build-recipe** change (`scripts/**`, except `scripts/test/**`) → **all** lines; -- a **the `.ffmpeg` list in `deps.json`** change → the **added/changed** lines; -- a **`deps.json`** change → only the lines whose **resolved** dependency set changed. A line that - *whole-line-pins* the bumped dep (an `overrides.` entry with no `platforms`) is **not** - rebuilt or re-released — nothing changed for it. A platform-scoped hold still counts as affected - (the default still applies to its other platforms). - -So a merged dependency bump cuts a release for exactly the lines it touched — never for a line that -pinned the changed lib away. - -**Automerge (future):** the flow is built for it. Merge manually until the build+test gates have -proven themselves, then add `"automerge": true` (with `"platformAutomerge": true`) to the grouping -rule in `renovate.json` to let green bump PRs merge without you. - -### When a bump breaks a build - -CI validates a bump across all platforms and licenses. A red build is one of two kinds — fix it at -the right layer: - -1. **Build-tooling drift** — the dep's own build interface changed (a renamed meson option, a new - minimum toolchain, dropped configure flags). **Fix the `scripts/deps/.sh` build script** - (or the toolchain in `scripts/steps/03_install_packages.sh`) and keep the dep at latest. This is - the common case and needs no override. -2. **FFmpeg-version or platform incompatibility** — a line or an arch genuinely can't consume the - new version. **Add an override** (`overrides.`, with `platforms` if it's arch-specific), - a `reason`, and an `issue` if it's a blocker. If the script must then build *both* the new and - the held version, gate that one flag on `dep_version ` rather than duplicating the script. - -Remove a hold when its blocker is fixed upstream: delete the override entry (the linked issue is -the reminder), let CI build the default across that line, and if green the hold is gone. - -### The coverage matrix stays in sync - -The per-cell matrices in `docs/matrix/` carry a **Version** column sourced from the ledger, -resolved per FFmpeg major and RID. When a platform-scoped override makes a dep's version differ -across platforms, the matrix shows each version in its cell instead of a check. Because the -matrices depend on `deps.json`, the `docs-matrix` CI job regenerates them and fails on drift — so a -dependency bump updates the docs too, not just an FFmpeg change. Never hand-edit the matrices; run -`bash scripts/gen-matrix.sh`. - -## Roadmap - -- **Other libraries** — the per-cell matrices under [docs/matrix/](docs/matrix/README.md) mark - with `—` every library FFmpeg supports that we don't build; the index lists only differences - BETWEEN versions, so it is the wrong place to read that from. SRT, RIST, VMAF and JXL are all - built, so they are not examples of it. `scripts/gen-coverage.sh` prints the current gap. `check-updates.yml` - re-surfaces this gap on each version bump. diff --git a/README.md b/README.md index 8709cc4..b41ffa5 100644 --- a/README.md +++ b/README.md @@ -1,65 +1,64 @@ -# FFmpeg Builds +# FFmpeg builds -Prebuilt, self-contained **FFmpeg** libraries and binaries for every major platform, in four -license variants — multiple major lines (currently **8.x** and **9.x**) built in parallel, each -with the [whisper.cpp](https://github.com/ggml-org/whisper.cpp) speech-to-text filter -(`af_whisper`) built in. No network, no external services; every artifact ships the -governing license text and each bundled dependency's license under `legal/`. +Prebuilt, self-contained FFmpeg libraries and programs for every major platform: FFmpeg 8.x and 9.x, each in four +license variants, with the [whisper.cpp](https://github.com/ggml-org/whisper.cpp) speech-to-text filter (`whisper`) +built in. Download them from the [releases](../../releases). + +They are built from [`ffmpeg-build.yml`](ffmpeg-build.yml) by [ffmpeg-build](https://github.com/devenvy/ffmpeg-build): +every library version is locked in [`ffmpeg.lock`](ffmpeg.lock), every license is checked before anything builds, and +each archive carries its license notices. [Using the builds](docs/install.md) covers each platform. ## Platforms -| OS | RIDs | -|----|------| -| Windows | `win-x64`, `win-arm64` | -| Linux (glibc) | `linux-x64`, `linux-arm64`, `linux-armhf` | -| Linux (musl / Alpine) | `linux-musl-x64`, `linux-musl-arm64` | -| macOS | `osx-x64`, `osx-arm64` | -| Android | `android-arm64`, `android-x64` | -| iOS | `ios-arm64` (device) + `ios-sim-arm64` (simulator), shipped as one `.xcframework` | -| Mac Catalyst | `maccatalyst-arm64` + `maccatalyst-x64`, fused into one universal slice of that same `.xcframework` | - -Every platform ships **dynamic** libraries (`.dll` / `.so` / `.dylib`; iOS as a dynamic-framework -`.xcframework`). The glibc Linux builds are self-contained (old-glibc floor, hwaccel libs -static-linked) so they run on a bare system with no package install; `linux-x64` and -`linux-arm64` additionally bundle a Vulkan loader, while `linux-armhf` does not (it has no -Vulkan Whisper backend and reaches any system loader through FFmpeg's dlopen path). +| OS | RIDs | +| --------------------- | ----------------------------------------------------------------------------- | +| Windows | `win-x64`, `win-arm64` | +| Linux (glibc) | `linux-x64`, `linux-arm64`, `linux-armhf` | +| Linux (musl / Alpine) | `linux-musl-x64`, `linux-musl-arm64` | +| macOS | `osx-x64`, `osx-arm64` | +| Android | `android-arm64`, `android-x64` | +| iOS and Mac Catalyst | `ios-arm64`, `ios-sim-arm64`, `maccatalyst-arm64` + `maccatalyst-x64`, in one `.xcframework` bundle | + +Every platform ships shared libraries (`.dll`, `.so`, `.dylib`; iOS as dynamic frameworks). The Linux builds are +self-contained: nothing to install to run them. ## License variants -Each platform is built in **four cells** — pick by family and version: - -- **Family** — `gpl` adds the x264 + x265 encoders; `lgpl` uses kvazaar for HEVC and omits - x264/x265, so linking it doesn't force your app to the GPL. The one exception is the lean - `ios-sim-arm64` slice, which carries none of the three software H.26x encoders in any cell. -- **Version** — `v3` is `(L)GPLv3` and may link the Apache-2.0 dependencies (OpenSSL TLS + - Vulkan); `v2` is `GPLv2` / `LGPLv2.1` with no Vulkan. **`lgplv2` is the App-Store-safe cell** - — v3's anti-tivoization terms are incompatible with the Apple App Store, so LGPLv2.1 is the - variant you ship to iOS. - -Artifact naming: `ffmpeg-{version}-{rid}-{gplv3|gplv2|lgplv3|lgplv2}.tar.gz`, except the four -Apple mobile RIDs (`ios-arm64`, `ios-sim-arm64`, `maccatalyst-arm64`, `maccatalyst-x64`), which -are merged into one `ffmpeg-{version}-ios-{cell}.tar.gz` asset. The two Catalyst RIDs are -`lipo`-fused into one universal slice, so each xcframework there carries three slices: device, -simulator, and Catalyst. - -The **TLS backend depends on the cell**: OpenSSL on `v3` (Linux/Android/Mac Catalyst), GnuTLS on -`gplv2`, and **no TLS at all** on `lgplv2` (Linux/Android/Mac Catalyst — no LGPLv2.1-compatible -backend exists); Windows uses SChannel and macOS/iOS use SecureTransport in every cell. **Mac -Catalyst is the exception among Apple targets** — SecureTransport is unavailable there, so it -follows the Linux/Android ladder. See the docs for the full breakdown. - -## Documentation - -- **[Install & usage](docs/install/README.md)** — download, link, and consume per platform, plus - the Whisper filter and the development (headers / import-lib) packages. -- **[Build coverage matrix](docs/matrix/README.md)** — every library FFmpeg supports × every - platform × license, ✓ where this repo builds it. -- **[Development](DEVELOPMENT.md)** — how the builds are produced: the build scripts, CI, and how - to add a platform or dependency. -- **[Security](SECURITY.md)** — the security model and how to report an issue. +Each platform is built four times. Pick by family and version: + +- **Family:** `gpl` adds the x264 and x265 encoders; `lgpl` uses kvazaar for HEVC and leaves x264/x265 out, so + linking it doesn't put your app under the GPL. +- **Version:** `v3` (GPLv3 / LGPLv3) may use the Apache-2.0 libraries: OpenSSL, the Vulkan loader, and MoltenVK on + Apple. `v2` (GPLv2 / LGPLv2.1) can't. **`lgplv2` is the App Store variant**: v3's anti-tivoization terms don't fit + the App Store. + +| Variant | TLS (Linux, Android, Mac Catalyst) | SRT/RIST encryption | Vulkan filters | Whisper on the GPU (Vulkan) | +| -------- | ---------------------------------- | ------------------- | -------------- | -------------------------------- | +| `gplv3` | OpenSSL | yes | yes | Linux, Windows, Android | +| `lgplv3` | OpenSSL | yes | yes | Linux, Windows, Android | +| `gplv2` | GnuTLS | yes | no | Windows, Android | +| `lgplv2` | none | no | no | Windows, Android | + +Windows always uses SChannel and macOS/iOS SecureTransport for TLS. Whisper uses Metal on every Apple build, and the +CPU on `linux-armhf` (and wherever no GPU is found). On `v2` Windows and Android builds, Whisper's GPU path uses the +system's own Vulkan library, so nothing Apache-2.0 is shipped. + +## Releases + +Releases are tagged `.`, e.g. `9.0.2.4`; the build number goes up whenever anything a release +is made of changes (a library version, the build definition, the engine). Each release has, per platform and +variant: + +- `ffmpeg---.tar.gz`: the programs and shared libraries, with `THIRD-PARTY-NOTICES.txt` (the + variant's license, how FFmpeg was built, and every bundled library's license texts). +- `ffmpeg----dev.tar.gz` (desktop platforms): headers, pkg-config files and, on Windows, MSVC + import libraries. +- `ffmpeg--ios-.tar.gz`: the iOS and Mac Catalyst `.xcframework` bundle. + +plus `SHA256SUMS`, `manifest.yml` (what each build contains) and `ffmpeg--sources.tar.gz` (the source of +every library in the release). ## License -FFmpeg and its dependencies are licensed under the GNU (L)GPL and various permissive licenses. -Each release artifact carries its effective-license notice and the full text of every bundled -component under `legal/` — see the [install docs](docs/install/README.md) for what to ship. +The build definition in this repository is MIT ([LICENSE](LICENSE)). FFmpeg and the libraries are under the GNU (L)GPL +and various permissive licenses; each archive's `THIRD-PARTY-NOTICES.txt` says which, in full. diff --git a/SECURITY.md b/SECURITY.md index 873cf70..76c7c1e 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,43 +1,16 @@ -# Security Policy +# Security -## What this repository is - -This repository is a **build system** for stock upstream FFmpeg and its supporting -libraries (x264, x265, kvazaar, dav1d, SVT-AV1, OpenSSL, GnuTLS, and others — the TLS -backend varies by license cell). It does **not** vendor or fork that upstream source — each -library is fetched from its official upstream at a pinned release tag and built at CI time, -into a git-ignored, ephemeral `.build/` tree. A small number of targeted build-time patches -are applied in the open, in `scripts/`, to make a source compile for a target it does not yet -support (for example skipping FFmpeg's videotoolbox symbols that the Mac Catalyst SDK marks -unavailable); none add functionality, and each is visible in the script that applies it. The only source original to this -repository is the build tooling (shell scripts and GitHub Actions workflows) plus a -small compile/runtime smoke test (`scripts/test/smoke.c`). - -## Scope - -**In scope** — report here: - -- Vulnerabilities in our build tooling (shell scripts, workflows) — e.g. command - injection, unsafe download/verification, secret handling. -- Supply-chain concerns in how we fetch or pin upstream sources. - -**Out of scope** — please report upstream instead: - -- Vulnerabilities in FFmpeg or any bundled library's own source code. Those belong to - the respective upstream projects; we track and adopt fixed upstream releases through - our version-update process. They are not defects in this repository. - -## How we scan - -- **CodeQL** — the C we own (`scripts/test/`) and our GitHub Actions workflows. -- **ShellCheck** — our shell scripts. - -Both run on pull requests and pushes to `main`, with results in the Security tab. -Upstream library source is never checked out into an analyzed path, so upstream CVEs -are not attributed to this repository. +This repository holds a build definition only: [`ffmpeg-build.yml`](ffmpeg-build.yml), its lock and the workflows +that build and publish the releases. The builds themselves are made by +[ffmpeg-build](https://github.com/devenvy/ffmpeg-build), from each library's upstream source, pinned by commit or +checksum in [`ffmpeg.lock`](ffmpeg.lock). ## Reporting a vulnerability -Please open a private report via the repository's **Security → Report a vulnerability** -page (GitHub private vulnerability reporting), or contact the maintainers directly. We -aim to acknowledge within a few business days. +Please report privately, through **Security → Report a vulnerability** on this repository; don't open a public issue. + +- **The builds or how they are made** (what is downloaded and how it's checked, the toolchains, the workflows): report + it to [ffmpeg-build](https://github.com/devenvy/ffmpeg-build/security). +- **FFmpeg or a bundled library's own code:** report it upstream. Fixed upstream releases reach these builds through + the daily lock update. +- **Anything about this repository's configuration or releases:** here. diff --git a/SOURCE_OFFER.txt b/SOURCE_OFFER.txt deleted file mode 100644 index 81d31e5..0000000 --- a/SOURCE_OFFER.txt +++ /dev/null @@ -1,21 +0,0 @@ -FFmpeg @FFMPEG_VERSION@ — @LICENSE@ build (@RID@) - -This distribution contains FFmpeg together with a set of statically-linked -third-party libraries, produced by an automated, public, reproducible build -recipe: - - @REPO@ - -That repository's build script pins the exact version of FFmpeg and of every -bundled library, and records where each one comes from. The repository — together -with the corresponding unmodified upstream FFmpeg release at -https://ffmpeg.org/releases/ffmpeg-@FFMPEG_VERSION@.tar.xz — is the complete -corresponding source for the FFmpeg libraries in this build, as required by the -GNU @LICENSE@. Everything is public; no request to the distributor is necessary -to obtain it. - -Every bundled library, with the exact version and upstream origin used for this -build, is recorded in that repository's deps.json. Each library's own license text -accompanies this notice under legal/licenses//, alongside the governing -license text for this build's cell. GPL builds additionally include the x264 and -x265 software encoders. diff --git a/deps.json b/deps.json deleted file mode 100644 index c44ab5f..0000000 --- a/deps.json +++ /dev/null @@ -1,330 +0,0 @@ -{ - "ffmpeg": [ - "8.1.3", - "9.0.2" - ], - "defaults": { - "dav1d": { - "origin": "https://code.videolan.org/videolan/dav1d.git", - "tag": "1.5.4", - "datasource": "gitlab-tags", - "registryUrl": "https://code.videolan.org", - "mirror": "https://github.com/videolan/dav1d.git" - }, - "fribidi": { - "origin": "https://github.com/fribidi/fribidi.git", - "tag": "v1.0.17", - "datasource": "github-tags" - }, - "harfbuzz": { - "origin": "https://github.com/harfbuzz/harfbuzz.git", - "tag": "14.5.1", - "datasource": "github-tags" - }, - "kvazaar": { - "origin": "https://github.com/ultravideo/kvazaar.git", - "tag": "v2.3.2", - "datasource": "github-tags" - }, - "libass": { - "origin": "https://github.com/libass/libass.git", - "tag": "0.17.5", - "datasource": "github-tags" - }, - "libdrm": { - "origin": "https://gitlab.freedesktop.org/mesa/drm.git", - "tag": "libdrm-2.4.134", - "datasource": "gitlab-tags", - "registryUrl": "https://gitlab.freedesktop.org" - }, - "libogg": { - "origin": "https://github.com/xiph/ogg.git", - "tag": "v1.3.6", - "datasource": "github-tags" - }, - "libva": { - "origin": "https://github.com/intel/libva.git", - "tag": "2.24.1", - "datasource": "github-tags" - }, - "libvorbis": { - "origin": "https://github.com/xiph/vorbis.git", - "tag": "v1.3.7", - "datasource": "github-tags" - }, - "libvpx": { - "origin": "https://chromium.googlesource.com/webm/libvpx.git", - "tag": "v1.17.0", - "datasource": "git-refs", - "mirror": "https://github.com/webmproject/libvpx.git" - }, - "x265": { - "origin": "https://github.com/Multicorewareinc/x265.git", - "tag": "4.3", - "datasource": "github-tags" - }, - "moltenvk": { - "origin": "https://github.com/KhronosGroup/MoltenVK.git", - "tag": "v1.4.2", - "datasource": "github-tags" - }, - "openh264": { - "origin": "https://github.com/cisco/openh264.git", - "tag": "v2.6.0", - "datasource": "github-tags" - }, - "openssl": { - "origin": "https://github.com/openssl/openssl.git", - "tag": "openssl-3.5.7", - "datasource": "github-tags" - }, - "whisper": { - "origin": "https://github.com/ggml-org/whisper.cpp.git", - "tag": "v1.9.4", - "datasource": "github-tags" - }, - "zimg": { - "origin": "https://github.com/sekrit-twc/zimg.git", - "tag": "release-3.0.6", - "datasource": "github-tags" - }, - "zlib": { - "origin": "https://github.com/madler/zlib.git", - "tag": "v1.3.2", - "datasource": "github-tags" - }, - "gmp": { - "origin": "https://ftp.gnu.org/gnu/gmp/gmp-6.3.0.tar.xz", - "tag": "6.3.0", - "releasesUrl": "https://ftp.gnu.org/gnu/gmp/", - "releasesStyle": "tarball", - "reason": "gmp.sh downloads a GNU tarball (GMP_VER=6.3.0) via dep_version, not git; no canonical git mirror with a matching v6.3.0 tag was found (checked github.com/alisw/GMP and git.savannah.gnu.org/git/gmp — neither has it), so origin/tag here describe the tarball, not a clonable git ref; tag is the bare tarball-filename version. 6.3. Tracked via the tarball-listing custom datasource against releasesUrl, so a new upstream release still raises a PR." - }, - "gnutls": { - "origin": "https://gitlab.com/gnutls/gnutls.git", - "tag": "3.8.13", - "datasource": "gitlab-tags", - "registryUrl": "https://gitlab.com" - }, - "nettle": { - "origin": "https://git.lysator.liu.se/nettle/nettle.git", - "tag": "4.0", - "datasource": "git-refs", - "reason": "nettle.sh downloads a GNU tarball (NETTLE_VER=4.0) built via dep_version, not git clone_dep (nettle git tag has no pre-generated ./configure); tag is the bare tarball-filename version, not the git tag (which is nettle_4.0_release_20260205)." - }, - "libtasn1": { - "origin": "https://gitlab.com/gnutls/libtasn1.git", - "tag": "4.21.0", - "datasource": "gitlab-tags", - "registryUrl": "https://gitlab.com", - "reason": "libtasn1.sh downloads a GNU tarball (TASN1_VER=4.21.0) built via dep_version, not git clone_dep (libtasn1's git tag has no pre-generated ./configure); tag is the bare tarball-filename version, not the git tag (which is v4.21.0)." - }, - "libexpat": { - "origin": "https://github.com/libexpat/libexpat.git", - "tag": "R_2_8_3", - "datasource": "github-tags" - }, - "fontconfig": { - "origin": "https://github.com/fontconfig/fontconfig.git", - "tag": "2.18.3", - "datasource": "github-tags" - }, - "libplacebo": { - "origin": "https://github.com/haasn/libplacebo.git", - "tag": "v7.360.1", - "datasource": "github-tags" - }, - "libpng": { - "origin": "https://github.com/pnggroup/libpng.git", - "tag": "v1.6.59", - "datasource": "github-tags" - }, - "freetype": { - "origin": "https://github.com/freetype/freetype.git", - "tag": "VER-2-14-3", - "datasource": "github-tags" - }, - "amf": { - "origin": "https://github.com/GPUOpen-LibrariesAndSDKs/AMF.git", - "tag": "v1.5.3", - "datasource": "github-tags" - }, - "aom": { - "origin": "https://aomedia.googlesource.com/aom", - "tag": "v3.15.1", - "datasource": "git-refs" - }, - "libmp3lame": { - "origin": "https://downloads.sourceforge.net/project/lame/lame/4.0/lame-4.0.tar.gz", - "tag": "4.0", - "releasesUrl": "https://sourceforge.net/projects/lame/files/lame/", - "releasesStyle": "directory", - "reason": "libmp3lame.sh downloads a SourceForge tarball (lame-3.100.tar.gz) via dep_version, not git; no verified git mirror carries a matching RELEASE__3_100-style tag (checked github.com/rbrito/lame — closest is lame3_100_with_psymodel_v3_99_5, not exact), so this entry cannot be faithfully expressed as a clonable ref; tag is the bare tarball-filename version. 3. Tracked via the tarball-listing custom datasource against releasesUrl, so a new upstream release still raises a PR." - }, - "libvpl": { - "origin": "https://github.com/intel/libvpl.git", - "tag": "v2.17.0", - "datasource": "github-tags" - }, - "libwebp": { - "origin": "https://chromium.googlesource.com/webm/libwebp.git", - "tag": "v1.6.0", - "datasource": "git-refs", - "mirror": "https://github.com/webmproject/libwebp.git" - }, - "libxml2": { - "origin": "https://github.com/GNOME/libxml2.git", - "tag": "v2.15.4", - "datasource": "git-tags" - }, - "lcms2": { - "origin": "https://github.com/mm2/Little-CMS.git", - "tag": "lcms2.19.1", - "datasource": "github-tags" - }, - "openjpeg": { - "origin": "https://github.com/uclouvain/openjpeg.git", - "tag": "v2.5.4", - "datasource": "github-tags" - }, - "libvmaf": { - "origin": "https://github.com/Netflix/vmaf.git", - "tag": "v3.2.1", - "datasource": "github-tags" - }, - "brotli": { - "origin": "https://github.com/google/brotli.git", - "tag": "v1.2.0", - "datasource": "github-tags" - }, - "highway": { - "origin": "https://github.com/google/highway.git", - "tag": "1.4.0", - "datasource": "github-tags" - }, - "libjxl": { - "origin": "https://github.com/libjxl/libjxl.git", - "tag": "v0.12.0", - "datasource": "github-tags" - }, - "nv-codec": { - "origin": "https://github.com/FFmpeg/nv-codec-headers.git", - "tag": "n13.1.15.0", - "datasource": "github-tags" - }, - "opus": { - "origin": "https://github.com/xiph/opus.git", - "tag": "v1.6.1", - "datasource": "github-tags" - }, - "llvm-mingw": { - "origin": "https://github.com/mstorsjo/llvm-mingw.git", - "tag": "20260922", - "datasource": "github-tags" - }, - "patchelf": { - "origin": "https://github.com/NixOS/patchelf.git", - "tag": "0.19.2", - "datasource": "github-tags" - }, - "shaderc": { - "origin": "https://github.com/google/shaderc.git", - "tag": "v2026.4", - "datasource": "github-tags" - }, - "soxr": { - "origin": "https://github.com/dofuuz/soxr.git", - "tag": "0.1.3", - "datasource": "github-tags" - }, - "svtav1": { - "origin": "https://gitlab.com/AOMediaCodec/SVT-AV1.git", - "tag": "v4.2.0", - "datasource": "gitlab-tags", - "registryUrl": "https://gitlab.com", - "mirror": "https://github.com/AOMediaCodec/SVT-AV1.git" - }, - "x264": { - "origin": "https://code.videolan.org/videolan/x264.git", - "commit": "b35605ace3ddf7c1a5d67a2eb553f034aef41d55", - "digestBranch": "stable", - "datasource": "git-refs", - "reason": "x264 has no release tags; pinned reviewed stable HEAD" - }, - "vulkan-shim": { - "origin": "https://github.com/BtbN/Vulkan-Shim-Loader.git", - "commit": "65b3936528cd92eb4ea3de485d03f858a3850484", - "digestBranch": "master", - "datasource": "git-refs", - "reason": "No release tags; pinned reviewed master HEAD. Static stub that LoadLibrary/dlopens the real Vulkan loader at runtime so Windows artifacts carry no hard vulkan-1.dll import - BtbN/FFmpeg-Builds uses the same shim for the same reason." - }, - "vulkan-headers": { - "origin": "https://github.com/KhronosGroup/Vulkan-Headers.git", - "tag": "vulkan-sdk-1.4.363.0", - "datasource": "github-tags" - }, - "vulkan-loader": { - "origin": "https://github.com/KhronosGroup/Vulkan-Loader.git", - "tag": "vulkan-sdk-1.4.363.0", - "datasource": "github-tags" - }, - "spirv-headers": { - "origin": "https://github.com/KhronosGroup/SPIRV-Headers.git", - "tag": "vulkan-sdk-1.4.363.0", - "datasource": "github-tags" - }, - "speex": { - "origin": "https://github.com/xiph/speex.git", - "tag": "Speex-1.2.1", - "datasource": "github-tags" - }, - "chromaprint": { - "origin": "https://github.com/acoustid/chromaprint.git", - "tag": "v1.6.1", - "datasource": "github-tags" - }, - "kissfft": { - "origin": "https://github.com/mborgerding/kissfft.git", - "tag": "131.2.0", - "datasource": "github-tags" - }, - "libgsm": { - "origin": "https://www.quut.com/gsm/", - "tag": "1.0.24", - "releasesUrl": "https://www.quut.com/gsm/", - "releasesStyle": "tarball", - "reason": "libgsm.sh downloads https://www.quut.com/gsm/gsm-.tar.gz via dep_version, not git; there is no clean canonical upstream git repo (the code ships as a hand-packed tarball with a non-standard Makefile). origin is the release DIRECTORY, deliberately without a version in it: Renovate's tarball manager updates `tag` only, so a versioned origin URL goes stale on the first bump -- which is exactly what happened here (origin said 1.0.22 while tag was 1.0.24). tag is the bare tarball-filename version. Tracked via the tarball-listing custom datasource against releasesUrl, so a new upstream release still raises a PR." - }, - "opencore-amr": { - "origin": "https://downloads.sourceforge.net/opencore-amr/opencore-amr-0.1.6.tar.gz", - "tag": "0.1.6", - "releasesUrl": "https://sourceforge.net/projects/opencore-amr/files/opencore-amr/", - "releasesStyle": "tarball", - "reason": "opencore-amr.sh downloads a SourceForge tarball (opencore-amr-0.1.6.tar.gz) via dep_version, not git; no clean canonical git mirror carries a matching bare-version tag, so origin/tag describe the tarball; tag is the bare tarball-filename version. Tracked via the tarball-listing custom datasource against releasesUrl, so a new upstream release still raises a PR." - }, - "vo-amrwbenc": { - "origin": "https://downloads.sourceforge.net/opencore-amr/vo-amrwbenc-0.1.3.tar.gz", - "tag": "0.1.3", - "releasesUrl": "https://sourceforge.net/projects/opencore-amr/files/vo-amrwbenc/", - "releasesStyle": "tarball", - "reason": "vo-amrwbenc.sh downloads a SourceForge tarball (vo-amrwbenc-0.1.3.tar.gz) via dep_version, not git; no clean canonical git mirror carries a matching bare-version tag, so origin/tag describe the tarball; tag is the bare tarball-filename version. Tracked via the tarball-listing custom datasource against releasesUrl, so a new upstream release still raises a PR." - }, - "mbedtls": { - "origin": "https://github.com/Mbed-TLS/mbedtls.git", - "tag": "v3.6.7", - "datasource": "github-tags", - "reason": "Renovate tracks the git tag (git-tags on origin), but mbedtls.sh downloads the matching release tarball (mbedtls-.tar.bz2, v stripped) instead of cloning — the tarball bundles the 'framework' submodule in-tree, avoiding a submodule init. Pin the 3.6 LTS line (4.x is the TF-PSA-Crypto split, not yet consumed by FFmpeg/SRT/librist). Held at 3.x by a renovate.json allowedVersions rule: FFmpeg's tls_mbedtls.c uses mbedtls_ctr_drbg_*/mbedtls_entropy_* unconditionally and mbedTLS 4 removed those headers (moved to PSA Crypto); FFmpeg master has not migrated either. Tracked in issue #18." - }, - "srt": { - "origin": "https://github.com/Haivision/srt.git", - "tag": "v1.5.7", - "datasource": "github-tags" - }, - "librist": { - "origin": "https://code.videolan.org/rist/librist.git", - "tag": "v0.2.20", - "datasource": "gitlab-tags" - } - }, - "overrides": {} -} diff --git a/docs/future-platforms.md b/docs/future-platforms.md deleted file mode 100644 index 6f603bb..0000000 --- a/docs/future-platforms.md +++ /dev/null @@ -1,49 +0,0 @@ -# Future platforms (backlog) - -Candidate RIDs to add on top of what already ships. The prerequisites this file was -originally written against — the v2 license series, dynamic Apple frameworks, and -MoltenVK on macOS — have all landed. The platform-hoist refactor makes each of these a -localized change — a `resolve` line + a `platform/.sh` block — not a per-dep -edit. See the vocabulary note at the bottom. - -## Trivial — existing platform + existing toolchain (resolve line + one block) -| OS/runtime | RID(s) | Platform | Notes | -|---|---|---|---| -| tvOS | `tvos-arm64`, `tvos-sim-arm64` | apple | appletvos SDK; VideoToolbox/Metal; same LGPLv2.1 App-Store story as iOS. Cheapest, plausibly real (big-screen viewing). | -| visionOS | `visionos-arm64`, `visionos-sim-arm64` | apple | xros SDK. Emerging, small market. | - -> `android-x64` and `linux-musl-arm64` shipped 2026-09-10 (#14); `win-arm64` shipped 2026-09-10 -> (#16, llvm-mingw — the first RID needing a new toolchain). Note for future estimates: the -> "resolve line + one platform block" pricing above was optimistic — a RID is currently -> hardcoded in ~15 files (CI matrices, the ledger validator, the coverage-matrix generator, and -> the per-dep host triples). Still mechanical, but budget accordingly. - -## Bigger — new toolchain, new `platform/.sh` -| OS/runtime | RID | Lift | -|---|---|---| -| **Web / WASM** | `browser-wasm` | Emscripten (`emcc`) toolchain; thread/syscall/HW-accel constraints. **Highest-value** for a media/DVR product — in-browser playback, no install (cf. `ffmpeg.wasm`). Own spike. | - -## On-demand niche -`linux-riscv64`, `linux-ppc64le`, `linux-loongarch64`, `android-arm` (32-bit), -FreeBSD (`freebsd-x64`). *(Mac Catalyst shipped — see the RID table in DEVELOPMENT.md.)* - -## Known asymmetries (not platform gaps, but worth fixing) -- **iOS device vs. simulator filter set.** `04_select_license.sh` disables libplacebo - on `ios-sim-arm64` only (the deliberately lean simulator slice), so the two slices - inside one `.xcframework` expose different filters — a `libplacebo` filtergraph that - works on device silently isn't available in the simulator. Consumers building a - capability table need to know. Fixing it means paying the shaderc+libplacebo build - cost on the simulator slice. - -## Vocabulary (keep consistent) -- **RID** = atomic build target `{os}-{arch}[-variant]` — one RID → one build. It is - `${RID}` and the matrix axis, and normally the artifact-name middle too. The exception - is the Apple mobile family: `ios-arm64`, `ios-sim-arm64`, `maccatalyst-arm64` and - `maccatalyst-x64` are four separate builds merged into a single `ios`-token release - asset (`ffmpeg-{version}-ios-{cell}.tar.gz` — the two Catalyst RIDs `lipo`-fuse into - one universal slice), so there one RID does not mean one artifact. - Use RID for anything specific. -- **platform (family)** = toolchain bucket (`apple`/`linux`/`windows`/`android`/`wasm`) - — what `platform/.sh` keys on (`PLATFORM`). Many RIDs per platform. -- The OS name (tvOS, Web) is prose only — "add tvOS" = "add its RIDs". Avoid "target" - (ambiguous). diff --git a/docs/install.md b/docs/install.md new file mode 100644 index 0000000..baad71a --- /dev/null +++ b/docs/install.md @@ -0,0 +1,100 @@ +# Using the builds + +Download an archive from the [releases](../../../releases) and check it against the release's `SHA256SUMS`: + +```bash +gh release download 9.0.2.4 --repo devenvy/ffmpeg --pattern 'ffmpeg-9.0.2-linux-x64-lgplv3.tar.gz' --pattern SHA256SUMS +sha256sum -c --ignore-missing SHA256SUMS # macOS: shasum -a 256 -c --ignore-missing SHA256SUMS +``` + +A product can pin a release instead, and let ffmpeg-build download, check and unpack it (and move the pin within the +same FFmpeg major): `devenvy/ffmpeg@9.0.2.4` in a file such as `ffmpeg.version`, then +`ffmpeg-build fetch ffmpeg.version --target linux-x64-lgplv3 --dev --out vendor/ffmpeg`. + +Ship `THIRD-PARTY-NOTICES.txt` with anything you distribute: it is the variant's license notice and every bundled +library's license text. + +## Which variant + +- **A closed-source app:** an `lgpl` variant (a `gpl` one puts the whole app under the GPL). +- **The Apple App Store:** `lgplv2`. +- **x264/x265 encoding,** where the GPL is fine: a `gpl` variant. +- **Otherwise:** `lgplv3` (TLS everywhere, Vulkan, no GPL obligations). + +The [README](../README.md#license-variants) lists what each variant has: TLS, SRT/RIST encryption, Vulkan, GPU +Whisper. + +## Linux + +```bash +mkdir -p /opt/ffmpeg && tar -xzf ffmpeg-9.0.2-linux-x64-lgplv3.tar.gz -C /opt/ffmpeg +export PATH="/opt/ffmpeg:$PATH" +echo /opt/ffmpeg > /etc/ld.so.conf.d/ffmpeg.conf && ldconfig # to link against the libraries +``` + +Nothing needs installing. `linux-x64` and `linux-arm64` run on glibc 2.28 and later (RHEL/Alma 8+, Debian 10+, Ubuntu +18.10+), `linux-armhf` on glibc 2.36 and later (Debian 12, Raspberry Pi OS Bookworm); a distroless image also needs +`libstdc++.so.6` and `libgcc_s.so.1`. The `linux-musl-*` builds run on a bare `alpine` image: the C++ runtime is linked +in. NVIDIA encoding (NVENC) needs driver 570 or later, on Linux and Windows. Hardware acceleration (VAAPI, QSV, Vulkan) +and GPU Whisper only need the GPU driver (e.g. `mesa-va-drivers`, +`mesa-vulkan-drivers`); without one, FFmpeg runs on the CPU. `linux-armhf` ships no Vulkan loader: its Vulkan filters +use the system's (`libvulkan1`). + +## Windows + +```powershell +tar -xzf ffmpeg-9.0.2-win-x64-lgplv3.tar.gz -C C:\ffmpeg +$env:PATH = "C:\ffmpeg;$env:PATH" +``` + +The DLLs sit beside `ffmpeg.exe`. To link from MSVC or CMake, take the `-dev` archive: `include/` and the `lib/*.lib` +import libraries. Vulkan comes with the GPU driver. `win-arm64` has no NVENC/NVDEC, AMF, QSV or SVT-AV1 (none exist for +Windows on ARM); it decodes in hardware through D3D11VA, DXVA2 and Media Foundation. + +## macOS + +```bash +mkdir -p /opt/ffmpeg && tar -xzf ffmpeg-9.0.2-osx-arm64-lgplv3.tar.gz -C /opt/ffmpeg +export PATH="/opt/ffmpeg:$PATH" +``` + +The `v3` builds run FFmpeg's Vulkan filters (`scale_vulkan`, ...) through MoltenVK, shipped in the archive; point the +Vulkan loader at it: + +```bash +export VK_ICD_FILENAMES=/opt/ffmpeg/MoltenVK_icd.json +ffmpeg -init_hw_device vulkan -i in.mp4 -vf scale_vulkan=1280:720 out.mp4 +``` + +Without it, everything else (VideoToolbox, Metal Whisper) works as usual. + +## Android + +The archive has `include/` and `lib//*.so` (`arm64-v8a` or `x86_64`); put the libraries in your module's +`src/main/jniLibs//`, including the `libc++_shared.so` they need. Ship both ABIs (`android-x64` is for emulators +and x86_64 devices). Hardware decode uses MediaCodec. The minimum is Android 9 (API 28), in every variant. + +## iOS and Mac Catalyst + +`ffmpeg--ios-.tar.gz` holds one dynamic `.xcframework` per `libav*` library, each with the device +(`ios-arm64`), simulator (`ios-sim-arm64`) and Mac Catalyst (arm64 + x64 in one slice) builds. Add them to your Xcode +target; Xcode picks the slice. Hardware decode uses VideoToolbox. The iOS 14.0 minimum applies to Catalyst. + +- The simulator slice leaves out x264, x265, kvazaar, libvpx, libaom, Opus and libass (they don't build for the arm64 + simulator); test that work on a device. +- Mac Catalyst has no SecureTransport, so it takes TLS like Linux: none in `lgplv2`. +- The `v3` frameworks link MoltenVK in for FFmpeg's Vulkan filters; nothing to embed or configure. On Mac Catalyst, + also link `-framework IOKit`. + +## Whisper (speech to text) + +Every build has FFmpeg's `whisper` filter. Download a [GGML model](https://huggingface.co/ggerganov/whisper.cpp) and +point the filter at it: + +```bash +curl -fsSLo ggml-base.en.bin https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin +ffmpeg -i input.mp4 -vn -af "whisper=model=ggml-base.en.bin:language=en:format=srt:destination=subs.srt" -f null - +``` + +It uses the GPU where the build has a backend for it (see the README) and falls back to the CPU; `use_gpu=0` forces +the CPU. `ffmpeg -h filter=whisper` lists its options. diff --git a/docs/install/README.md b/docs/install/README.md deleted file mode 100644 index 86af7f5..0000000 --- a/docs/install/README.md +++ /dev/null @@ -1,105 +0,0 @@ -# Installation & usage - -How to download, install, and link the [FFmpeg builds](../../README.md) — per platform — plus the -bundled Whisper speech-to-text filter and the development (headers/import-lib) packages. - -## Install - -Download a tarball from the [latest release](../../../../releases/latest) and extract. Each platform -ships **four license cells** — the variant name is `{rid}-{gplv3,gplv2,lgplv3,lgplv2}` (e.g. -`linux-x64-lgplv3`). The four Apple mobile RIDs are the exception: `ios-arm64`, `ios-sim-arm64`, -`maccatalyst-arm64` and `maccatalyst-x64` ship as a single `ffmpeg-{VERSION}-ios-{cell}.tar.gz` -asset rather than one tarball per RID. The two Catalyst RIDs are `lipo`-fused into one universal -slice, so each xcframework in it holds three slices: device, simulator, and Catalyst. - -Family: `gpl` bundles x264/x265; `lgpl` doesn't. Version: `v3` links the Apache-2.0 dependencies -— that means Vulkan everywhere it applies, and OpenSSL TLS on the platforms that need a bundled -backend (Linux, Android, Mac Catalyst); Windows and macOS/iOS use the OS-native backend in every -cell. `v2` (GPLv2 / LGPLv2.1) is the App-Store-safe series with no Vulkan, and its `lgplv2` cell -has no TLS on those same three platforms (see [Runtime dependencies](#runtime-dependencies)). -The per-platform pages below each use one cell in their examples; substitute the one you need. - -## Verifying a download - -Releases carry a `SHA256SUMS` asset covering every other artifact on that release, in standard -`sha256sum` format. **Releases published before this was added do not have one** — check the -release's asset list; for those, the per-asset digests are still available from the GitHub -releases API. - -Fetch it alongside whatever you downloaded, and check from the directory containing the -downloads: - -```bash -gh release download --repo / --pattern 'SHA256SUMS' -sha256sum -c --ignore-missing SHA256SUMS # Linux (GNU coreutils >= 8.25) -shasum -a 256 -c --ignore-missing SHA256SUMS # macOS (no sha256sum; shasum ships with it) -``` - -On Windows, `Get-FileHash -Algorithm SHA256` prints the hash to compare against the -matching line, or use `sha256sum` from Git Bash / WSL. - -`--ignore-missing` checks only the files you actually downloaded. Drop it to require the full -set — useful when mirroring a release or staging it for an air-gapped install. - -The manifest does not list itself. Its trust root is the GitHub release it is attached to; the -same per-asset digests are also available from the releases API if you prefer to check one file -without fetching the manifest. - -### Which cell do I pick? - -- **Shipping into a closed-source app** → an **`lgpl`** cell (a GPL build obligates your whole app - to the GPL). -- **Apple App Store** → **`lgplv2`**: v3's anti-tivoization terms are incompatible with the App - Store, so LGPLv2.1 is the App-Store-safe series. (No Vulkan; on Android, no TLS — see below.) -- **Need software H.264/H.265 (x264/x265) encoding**, and the GPL is acceptable (internal tooling, - GPL-compatible project) → a **`gpl`** cell. -- **Want GPU (Vulkan) Whisper** → a **`v3`** cell, and one of `linux-x64`, `linux-arm64`, - `linux-musl-x64`, `linux-musl-arm64`, `win-x64`, `win-arm64`, `android-arm64` or `android-x64`. - `v2` drops Vulkan on every RID, and `linux-armhf` is CPU-only Whisper in every cell. - macOS/iOS/Catalyst use Metal regardless of cell. -- **Want TLS (`https`/`tls`)** → note that only the `lgplv2` cell lacks it, and only on Linux, - Android and Mac Catalyst. `gplv2` has GnuTLS, and Windows/macOS/iOS have their native backend - in all four cells — so `v3` is not required for TLS. -- **No preference otherwise** → **`lgplv3`** is the general-purpose default (dynamic-linking - permission, TLS, no GPL obligation, and GPU Whisper on the RIDs listed above). - -### Runtime dependencies - -Two things travel with the cell you pick — TLS and Vulkan. No platform needs a package install -to make the artifacts run, including Alpine/musl. The cross-platform rules are here; the platform -pages carry the OS-specific steps. - -**TLS and the license cell.** Which cell you pick changes what's inside the binary. On -Linux/Android, `v3` cells carry **OpenSSL**, the `gplv2` cell carries **GnuTLS**, and the -**`lgplv2` cell ships no TLS backend at all** — `https`/`tls` are unavailable, because GnuTLS's -GMP + nettle dependencies are never LGPLv2.1-licensed and no other FFmpeg TLS backend is -LGPLv2.1-compatible. Windows (**SChannel**) and macOS/iOS (**SecureTransport**) use the OS-native -backend in every cell, so their TLS is unaffected by the split. **Mac Catalyst is the exception -among Apple targets**: SecureTransport is unavailable there (the SDK marks it no longer supported -and FFmpeg's backend fails to compile), so Catalyst follows the Linux/Android ladder above and its -`lgplv2` slice has no TLS either — see [iOS / Mac Catalyst](./ios.md#no-tls-in-the-lgplv2-catalyst-slice). - -**Vulkan and the license cell.** The `v2` cells omit **Vulkan** everywhere, so Vulkan Whisper -needs a `v3` cell — but a `v3` cell is not sufficient on its own. The Vulkan Whisper backend is -built only for `linux-x64`, `linux-arm64`, `linux-musl-x64`, `linux-musl-arm64`, `win-x64`, -`win-arm64`, `android-arm64` and `android-x64`; `linux-armhf` runs Whisper on the CPU in every -cell, and macOS/iOS/Catalyst use Metal either way. - -**System packages.** None are required. The glibc Linux builds are self-contained, and the -Alpine (`linux-musl-x64`, `linux-musl-arm64`) builds link the C++ runtime statically, so they run -on a stock `alpine` image with no `apk add`. The only external pieces anywhere are optional GPU -drivers for hardware acceleration. Details on the -[Linux page](./linux.md#runtime-dependencies). Windows and macOS need no extra install. - -## Pages - -- **[Linux](./linux.md)** — glibc + Alpine/musl, self-contained note, and the Dockerfile recipe. -- **[Windows](./windows.md)** — DLLs on `PATH`, and the `-dev` tarball for MSVC `.lib` linking. -- **[macOS](./macos.md)** — dylibs + `PATH`. -- **[Android](./android.md)** — jniLibs `.so`, `libc++_shared.so`, MediaCodec, the API-28/`v3` floor. -- **[iOS](./ios.md)** — the `.xcframework`, dynamic dylibs (LGPLv2.1 §6), VideoToolbox. -- **[Speech-to-text (Whisper ASR)](./whisper.md)** — the bundled `whisper` filter, models, GPU/CPU. -- **[Development headers](./dev-headers.md)** — the `-dev` tarballs (headers + Windows import libs). - -See also the auto-generated **[build coverage matrix](../matrix/README.md)** for which library is -built on which platform × license. diff --git a/docs/install/android.md b/docs/install/android.md deleted file mode 100644 index 3c75846..0000000 --- a/docs/install/android.md +++ /dev/null @@ -1,53 +0,0 @@ -# Android - -Part of the [install docs](./README.md). See there for the four-cell variant naming and the -cross-platform [runtime-dependency overview](./README.md#runtime-dependencies). - -The mobile artifacts are libraries to **link into an app**, not CLI tools. Use an `lgpl` -variant for anything shipped (a GPL build obligates your whole app to the GPL). For the **Apple -App Store**, use the `lgplv2` cell — see [iOS](./ios.md); on Android note that `lgplv2` carries no -Vulkan and no TLS backend (see the [runtime-dependency overview](./README.md#runtime-dependencies)). - -## Install - -**Android** (`ffmpeg-{VERSION}-android-arm64-lgplv3.tar.gz` / `ffmpeg-{VERSION}-android-x64-lgplv3.tar.gz`) -— a tarball with: -- `include/` — the `libav*` headers to compile against. -- `lib/arm64-v8a/*.so` (from `android-arm64`) or `lib/x86_64/*.so` (from `android-x64`) — shared - libraries with unversioned sonames; drop them into your module's `src/main/jniLibs//` (or - point `jniLibs.srcDirs` at `lib/`). -- `legal/` — the LGPL text plus each bundled dependency's license under `legal/licenses//` - (ship it). - -`android-x64` is primarily for **emulators** — every Android emulator image on an x86_64 host is -x86_64, so this is the slice that runs on a Windows or Linux development machine — and it also -covers genuine x86_64 Android **devices** (e.g. ChromeOS's ARC++ Android runtime on Intel/AMD -Chromebooks). Ship both ABIs in your APK/AAB (or let Gradle's ABI splits do it) and the right one -is selected per device. - -32-bit `armeabi-v7a` is not built. See -[future platforms](../future-platforms.md) if you need it. - -Each ABI folder includes **`libc++_shared.so`**. `libavcodec`/`libavfilter` -depend on it at runtime — the codec libraries built from C++ (OpenH264, libass, whisper.cpp) -are linked with `c++_shared`, so the shared NDK C++ runtime must ship alongside them or the app -crashes on load. Keep it in `jniLibs`. If your app (or another native dependency) already -bundles its own `libc++_shared.so`, they are interchangeable — Android loads one by soname, so -drop whichever is newer and remove the duplicate. - -Hardware decode uses Android **MediaCodec** (`--enable-mediacodec --enable-jni`). Nothing to do -at app build time: `libavcodec.so` already carries a `DT_NEEDED` entry for `libmediandk.so`, so -the dynamic linker resolves it from the system on device. - -> **Minimum SDK: Android 9 (API 28) — every cell, both series.** The NDK compiler is pinned to -> `…-linux-android28-clang` for all Android builds, so `minSdkVersion` **28+** applies to any -> artifact here, `v2` included. API 28 was chosen *because* the `v3` cells link Vulkan 1.1 -> symbols (the Whisper filter's GPU backend and FFmpeg's own Vulkan) — the `v2` cells carry no -> Vulkan and run Whisper on CPU, so they don't *need* the floor, but they are still built -> against it and do not lower it. On a `v3` build running on a device with no Vulkan GPU, -> Whisper falls back to CPU automatically. - ---- - -Back to the [install hub](./README.md) · [iOS](./ios.md) · [Whisper](./whisper.md) · -[Development headers](./dev-headers.md) diff --git a/docs/install/dev-headers.md b/docs/install/dev-headers.md deleted file mode 100644 index 7f3ca74..0000000 --- a/docs/install/dev-headers.md +++ /dev/null @@ -1,20 +0,0 @@ -# Development headers - -Part of the [install docs](./README.md). - -Desktop runtime tarballs (`linux-*`, `win-*`, `osx-*`) contain **only** the binaries, shared -libraries, and `legal/` (the per-cell license notice plus each bundled dependency's license under -`legal/licenses//`) — not the `libav*` headers. If you're *linking* against the libraries -(rather than running `ffmpeg`/`ffprobe`), grab the matching **`…-{variant}-dev.tar.gz`** from -the same release: it holds the `include/` headers, and for Windows the `lib/*.lib` MSVC import -libraries. Keeping dev files out of the runtime download keeps it lean and avoids consumers -accidentally picking up headers/import libs at runtime. - -Mobile artifacts are the exception — [Android](./android.md) (`lib//*.so` + `include/`) and -[iOS](./ios.md) (`.xcframework`, headers bundled) ship headers in the main tarball, since those -builds exist only to be linked. - ---- - -Back to the [install hub](./README.md) · [Linux](./linux.md) · [Windows](./windows.md) · -[macOS](./macos.md) diff --git a/docs/install/ios.md b/docs/install/ios.md deleted file mode 100644 index bd00ea5..0000000 --- a/docs/install/ios.md +++ /dev/null @@ -1,102 +0,0 @@ -# iOS - -Part of the [install docs](./README.md). See there for the four-cell variant naming and the -cross-platform [runtime-dependency overview](./README.md#runtime-dependencies). - -The mobile artifacts are libraries to **link into an app**, not CLI tools. For the **Apple App -Store**, use the `lgplv2` cell: v3's anti-tivoization terms are incompatible with the App Store, -so LGPLv2.1 is the App-Store-safe series. The `v2` cells carry **no Vulkan** (Whisper still runs on -Metal on Apple); the `v3` cells add Vulkan via statically-linked MoltenVK — see [Vulkan GPU filters](#vulkan-gpu-filters-v3-only) -below and the [runtime-dependency overview](./README.md#runtime-dependencies). - -## Install - -**iOS** (`ffmpeg-{VERSION}-ios-lgplv2.tar.gz` for the App Store) — one `.xcframework` per `libav*` -library, each bundling the device (`ios-arm64`) and simulator (`ios-sim-arm64`) slices. The slices -are **dynamic** dylibs (the old static `.a` is gone) — the App-Store `lgplv2` build must be dynamic -to satisfy LGPLv2.1 §6, which requires the end user be able to relink the app against a modified -library; a dynamic framework satisfies that inherently. Add the frameworks to your Xcode target -(or a CocoaPods `vendored_frameworks`); Xcode selects the right slice and strips the simulator -slice from the shipped app automatically. Hardware decode uses **VideoToolbox**. The simulator -slice is lean — it drops **x264, x265, kvazaar, libvpx, libaom, Opus, libass** (and freetype / -fontconfig / libplacebo with them), because those configures inject iOS-device-only flags that do -not cross-compile for the arm64 simulator. It is **not** encoder-free: OpenH264 (H.264 encode), -LAME, Vorbis, OpenCORE AMR, OpenJPEG and libjxl are all present, and built-in decoders plus -VideoToolbox cover playback. Ship and test H.265, AV1, VP8/VP9 and Opus work on a device. - -## Mac Catalyst - -The same `.xcframework`s carry a **Mac Catalyst** slice, so an iOS app brought to the Mac links -the identical artifact with no extra download. It is a single universal slice covering both -Apple Silicon and Intel (the `maccatalyst-arm64` and `maccatalyst-x64` builds are `lipo`-fused -before packaging), and Xcode selects it automatically when the target's *Supports Mac Catalyst* -is on — there is nothing to configure. Hardware decode is **VideoToolbox**, same as iOS. - -Catalyst is built against the macOS SDK with an `…-apple-ios14.0-macabi` target triple. **iOS -14.0 is the deployment floor**: an app with a higher minimum still links fine (a library minimum -below the app's is always compatible), but one targeting an earlier iOS will not. - -### No TLS in the `lgplv2` Catalyst slice - -This is the one place Catalyst differs from iOS in capability, and it is worth checking before -you pick a cell. **SecureTransport is unavailable on Mac Catalyst** — the SDK marks -`SSLRead`/`SSLWrite` "no longer supported" there, and FFmpeg's `tls_securetransport.c` does not -merely warn but fails to *compile*. So Catalyst cannot use the OS-native TLS that every other -Apple target relies on, and instead follows the Linux/Android ladder: - -| cell | Catalyst TLS | iOS TLS | -|---|---|---| -| `gplv3` / `lgplv3` | OpenSSL 3.x (Apache-2.0, hence v3-only) | SecureTransport | -| `gplv2` | GnuTLS | SecureTransport | -| `lgplv2` | **none** | SecureTransport | - -`https://`, `tls://` and `rtmps://` inputs therefore do not work in the **`lgplv2` Catalyst -slice**. There is no LGPLv2.1-compatible TLS backend to fall back on, which is the same gap the -`lgplv2` Linux and Android builds have. If your Catalyst app needs TLS *and* App-Store-safe -licensing, fetch over TLS with `URLSession` on the app side and hand FFmpeg the data, or use a -`v3` cell where the App Store is not a constraint. The iOS slices in the same -`.xcframework` are unaffected — only the Catalyst slice lacks it. - -## Vulkan GPU filters (v3 only) - -The **v3** iOS cells enable FFmpeg's Vulkan GPU filters (`scale_vulkan`, `gblur_vulkan`, …) — -there's no Metal equivalent in the filtergraph — by **statically linking MoltenVK** -(Vulkan-over-Metal) into the `libav*` frameworks. There is nothing extra to embed and no -environment variable to set: FFmpeg calls into MoltenVK directly, exactly like the other static -dependencies (whisper/ggml, kvazaar, opus). The artifact is the **same six `.xcframework`s** in -every cell. - -MoltenVK links against `Metal`, `IOSurface`, `Foundation`, `QuartzCore`, `CoreGraphics` and -`UIKit` (its surface code imports `UIKit/UIView.h`, and MoltenVK disables Clang module -autolinking, so nothing pulls it in implicitly). **On Mac Catalyst add `-framework IOKit`**: -MoltenVK compiles as its macOS variant on macabi, which brings in the IOKit-based physical-device -enumeration that the iOS variant does not have. Because the `libav*` frameworks are dynamic, -those are recorded as `libavutil`'s own dependencies and the linker resolves them for you. If -your build system links the frameworks in a mode that does not inherit transitive dependencies, -add them explicitly: - -``` --framework Metal -framework IOSurface -framework Foundation -framework QuartzCore -framework CoreGraphics -framework UIKit -``` - -The `v2` / App-Store cells drop Vulkan entirely (MoltenVK is Apache-2.0, incompatible with -LGPLv2.1) and need none of the above. Whisper's Metal path and VideoToolbox decode are -unaffected in either series. - -> Earlier documentation described embedding a separate `MoltenVK.xcframework` and -> `vulkan.xcframework` and pointing `VK_ICD_FILENAMES` at a bundled `MoltenVK_icd.json`. That -> path never worked, but not because MoltenVK itself was missing: the old `v3` iOS tarball -> genuinely shipped `MoltenVK.xcframework` (staged from `libMoltenVK.dylib` like any other -> framework, then converted to an xcframework by the release build) — seven `.xcframework`s, -> not six. What was never in the tarball were `vulkan.xcframework` (no Khronos loader was ever -> built for iOS) and `MoltenVK_icd.json` (upstream MoltenVK emits that file only for its macOS -> slice). Without the loader or the ICD JSON, FFmpeg's `dlopen` fallback could not have found -> `MoltenVK.framework/MoltenVK` under any of the leaf names it tries, so the old instructions -> could not have worked regardless of MoltenVK's presence. Static linking replaces all of it — -> if you are upgrading from the old instructions, `MoltenVK.xcframework` disappears from the -> artifact entirely; that is expected. - ---- - -Back to the [install hub](./README.md) · [Android](./android.md) · [Whisper](./whisper.md) · -[Development headers](./dev-headers.md) diff --git a/docs/install/linux.md b/docs/install/linux.md deleted file mode 100644 index 8b5a028..0000000 --- a/docs/install/linux.md +++ /dev/null @@ -1,107 +0,0 @@ -# Linux - -Part of the [install docs](./README.md). See there for the four-cell variant naming and the -cross-platform [runtime-dependency overview](./README.md#runtime-dependencies). - -> **Important:** Every Linux build — `linux-x64`, `linux-arm64`, `linux-armhf`, `linux-musl-x64`, -> and `linux-musl-arm64` — is **self-contained** for hardware acceleration: the -> hardware-acceleration libraries (VAAPI/QSV/libdrm) are statically linked, and the Vulkan loader -> is bundled on every Linux build **except `linux-armhf`** (see below), so `ffmpeg` starts with -> **no `apt`/`dnf`/`apk` install** needed for those. *Using* hardware acceleration or GPU transcription still needs the system GPU **driver**, -> but nothing is required just to run. That now includes the `linux-musl-*` (Alpine) builds: the -> C++ runtime Alpine's minimal base image lacks is linked statically into the libraries, so they run on a bare -> `alpine` container with no `apk add` — see [Runtime dependencies](#runtime-dependencies). - -## Install - -```bash -mkdir -p /opt/ffmpeg -tar -xzf ffmpeg-{VERSION}-linux-x64-gplv3.tar.gz -C /opt/ffmpeg/ - -# Add to PATH -echo 'export PATH="/opt/ffmpeg:$PATH"' >> /etc/profile.d/ffmpeg.sh - -# Register libs with the dynamic linker (needed when linking, e.g. from .NET) -echo "/opt/ffmpeg" > /etc/ld.so.conf.d/ffmpeg.conf -ldconfig -``` - -For Alpine containers, use a `linux-musl-*` variant (`-x64` or `-arm64`) instead of -`linux-x64`/`linux-arm64`. - -## Runtime dependencies - -The **`linux-x64`** and **`linux-arm64`** builds have **no runtime package requirements on a -normal distribution** — every codec and hardware-dispatch library is static-linked or bundled, -and they are built in a manylinux_2_28 container (**glibc 2.28**), so they launch on any current -distro (RHEL/Alma 8+, Debian 10+, Ubuntu 18.10+) without installing anything. - -> The C++ codec libraries mean `libavcodec`/`libavfilter` still link `libstdc++.so.6` and -> `libgcc_s.so.1` dynamically. Every ordinary glibc distribution ships those, which is why there -> is nothing to install — but a **minimal or distroless** glibc image may not, and there they -> must be present. (The musl builds link them statically instead; see below.) - -**`linux-armhf`** is built in a Debian Bookworm container, so its floor is **glibc 2.36** — -Raspberry Pi OS Bookworm, Debian 12 and Ubuntu 22.10+. It is cross-compiled rather than built -on an armv7 host (no hosted runner executes 32-bit ARM), and Bookworm is the oldest base whose -glibc still satisfies the Node runtime the CI actions require. - -**`linux-armhf` and Vulkan.** Unlike the other Linux `v3` cells, the armhf build ships no bundled -Vulkan loader. This is not a startup dependency — its `libavfilter` has no `DT_NEEDED` on -`libvulkan.so.1` and reaches Vulkan through FFmpeg's `dlopen` path — so the artifact runs fine -without one. The practical difference is that on armhf, FFmpeg's **Vulkan filters** need the -**system** loader (`apt install libvulkan1`) plus a driver, where the other Linux cells carry -their own loader. This does not affect Whisper: armhf builds Whisper with the **CPU** backend, -so there is no GPU transcription there to enable in the first place. - -To actually **use** hardware acceleration or GPU Whisper you additionally need the system GPU -**driver** — e.g. `intel-media-va-driver`/`mesa-va-drivers` for VAAPI, `mesa-vulkan-drivers` -for Vulkan/GPU transcription. Without one, hardware paths are simply unavailable and Whisper -falls back to CPU, so treat drivers as optional `Recommends`, never a hard dependency. - -**`linux-musl-x64`/`linux-musl-arm64` (Alpine)** — the latter is the Alpine-on-ARM build (AWS -Graviton, Ampere, and Docker Desktop on Apple Silicon, which defaults to arm64 containers) — are -self-contained in the same way as the glibc builds above: the hwaccel dispatch libraries -(libdrm/libva/libvpl/Vulkan-Loader) are built from source and statically linked or bundled -directly in the tarball, not taken from Alpine's `-dev` packages, so they carry no -`libva.so`/`libvpl.so`/`libvulkan.so` runtime dependency either. - -The C++ runtime whisper needs (`libstdc++`, `libgcc`) is **linked statically into the FFmpeg -libraries**, so these run on a bare `alpine` image with nothing installed — no `apk add` step, and -no `libstdc++.so.6`/`libgcc_s.so.1` in the tarball to find at all. - -> Previously this required `apk add libstdc++ libgcc`. That was documented rather than fixed, and -> documentation doesn't make an artifact runnable — a stock Alpine container failed at startup -> with `Error loading shared library libstdc++.so.6`. The runtime is now part of the libraries. - -**How that works.** The C++ runtime is linked **statically** into the FFmpeg libraries rather than shipped alongside them, so there is no `libstdc++.so.6`/`libgcc_s.so.1` to find. That also keeps the licence position clean: the GCC Runtime Library Exception covers statically linked runtime as part of the compiled output, so no GPLv3 library is redistributed — which matters most for the `lgplv2` cell. No platform bundles a GPL runtime. - -TLS and Vulkan availability depend on which license cell you picked — see the cross-platform -[TLS and the license cell](./README.md#runtime-dependencies) overview. - -## Dockerfile - -```dockerfile -ARG VARIANT=linux-x64-gplv3 - -RUN VERSION=$(curl -fsSL "https://api.github.com/repos/OWNER/REPO/releases/latest" \ - | jq -r '.tag_name') \ - && curl -fsSL \ - "https://github.com/OWNER/REPO/releases/download/${VERSION}/ffmpeg-${VERSION%.*}-${VARIANT}.tar.gz" \ - -o /tmp/ffmpeg.tar.gz \ - && mkdir -p /opt/ffmpeg \ - && tar -xzf /tmp/ffmpeg.tar.gz -C /opt/ffmpeg/ \ - && rm /tmp/ffmpeg.tar.gz \ - && echo "/opt/ffmpeg" > /etc/ld.so.conf.d/ffmpeg.conf \ - && ldconfig - -ENV PATH="/opt/ffmpeg:$PATH" -``` - -Replace `OWNER/REPO` with the actual repository path. Assets on a public repo are downloadable -with plain `curl` — no authentication. - ---- - -Back to the [install hub](./README.md) · [Windows](./windows.md) · [macOS](./macos.md) · -[Whisper](./whisper.md) · [Development headers](./dev-headers.md) diff --git a/docs/install/macos.md b/docs/install/macos.md deleted file mode 100644 index 11a4bf2..0000000 --- a/docs/install/macos.md +++ /dev/null @@ -1,40 +0,0 @@ -# macOS - -Part of the [install docs](./README.md). See there for the four-cell variant naming and the -cross-platform [runtime-dependency overview](./README.md#runtime-dependencies). - -## Install - -```bash -mkdir -p /opt/ffmpeg -tar -xzf ffmpeg-{VERSION}-osx-arm64-gplv3.tar.gz -C /opt/ffmpeg/ -export PATH="/opt/ffmpeg:$PATH" -``` - -macOS needs no extra runtime install: Whisper's GPU path uses **Metal** (available regardless of -the v2/v3 split), and TLS uses the OS-native **SecureTransport** backend in every cell — see the -[runtime-dependency overview](./README.md#runtime-dependencies). - -## Vulkan GPU filters (v3 only) - -FFmpeg's Vulkan filters (`scale_vulkan`, `gblur_vulkan`, `chromaber_vulkan`, …) have no Metal -equivalent in the filtergraph, so the **v3** macOS builds ship **MoltenVK** (Vulkan-over-Metal) -alongside the Vulkan loader to make them work. (The `v2` cells drop Vulkan — MoltenVK is -Apache-2.0, incompatible with GPLv2/LGPLv2.1.) - -MoltenVK is an ICD, so the Vulkan loader must be told where to find it. Point `VK_ICD_FILENAMES` -at the bundled `MoltenVK_icd.json` before running: - -```bash -export VK_ICD_FILENAMES="/opt/ffmpeg/MoltenVK_icd.json" -export DYLD_LIBRARY_PATH="/opt/ffmpeg:${DYLD_LIBRARY_PATH:-}" # so ffmpeg finds the bundled loader -ffmpeg -init_hw_device vulkan -i in.mp4 -vf scale_vulkan=1280:720 out.mp4 -``` - -Without those, `ffmpeg` still runs normally — the Vulkan filters just report no device (Metal -Whisper and VideoToolbox decode/encode are unaffected). - ---- - -Back to the [install hub](./README.md) · [Linux](./linux.md) · [Windows](./windows.md) · -[Whisper](./whisper.md) · [Development headers](./dev-headers.md) diff --git a/docs/install/whisper.md b/docs/install/whisper.md deleted file mode 100644 index 25f27a7..0000000 --- a/docs/install/whisper.md +++ /dev/null @@ -1,68 +0,0 @@ -# Speech-to-text (Whisper ASR) - -Part of the [install docs](./README.md). - -Every build enables FFmpeg's `whisper` audio filter (`af_whisper`), which runs -[whisper.cpp](https://github.com/ggml-org/whisper.cpp) speech recognition inside the -filtergraph — no network, no external service. It is MIT/LGPL-clean and present in **all** -variants, including the shippable plain-LGPL builds. - -**Model file (required, not bundled).** Download a GGML Whisper model and pass its path to the -filter. `base.en` (~142 MB) is a good default for English audio; `tiny.en` (~75 MB) is -smaller/faster for on-device use. - -```bash -curl -fsSL -o ggml-base.en.bin \ - https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin -``` - -**Examples:** - -```bash -# Transcribe a file's audio to an SRT subtitle sidecar -ffmpeg -i input.mp4 -vn \ - -af "whisper=model=ggml-base.en.bin:language=en:format=srt:destination=subs.srt" \ - -f null - - -# Transcribe to a plain-text transcript -ffmpeg -i input.mp4 -vn \ - -af "whisper=model=ggml-base.en.bin:language=en:destination=transcript.txt" \ - -f null - -``` - -**Common options** (`ffmpeg -h filter=whisper` on the binary is authoritative): - -| Option | Default | Description | -|--------|---------|-------------| -| `model` | (required) | Path to the GGML model file | -| `language` | `auto` | Language code (e.g. `en`), or `auto` to detect | -| `format` | `text` | Output format: `text`, `srt`, or `json` | -| `destination` | (stdout) | Output file path for the transcript | -| `queue` | `3s` | Audio buffered before each transcription pass | -| `use_gpu` | `1` | Use the GPU backend when available (else CPU) | -| `vad_model` | (none) | Optional VAD model path for speech segmentation | - -**Hardware acceleration & fallback.** The GPU backend is chosen per RID, not per platform: - -| Backend | RIDs | -|---|---| -| **Vulkan** (`v3` cells only) | `linux-x64`, `linux-arm64`, `linux-musl-x64`, `linux-musl-arm64`, `win-x64`, `win-arm64`, `android-arm64`, `android-x64` | -| **Metal** (every cell) | `osx-x64`, `osx-arm64`, `ios-arm64`, `ios-sim-arm64`, `maccatalyst-arm64`, `maccatalyst-x64` | -| **CPU** (every cell) | `linux-armhf` | - -The **`v2`** cells carry no Vulkan, so the Vulkan RIDs above transcribe on the **CPU** there; the -Metal and CPU rows are unaffected by the license cell. When no compatible GPU is present, -transcription also falls back to the CPU automatically (`tiny`/`base` models are roughly -real-time on CPU). Pass `use_gpu=0` to force the CPU even when a GPU is present — for example on -`win-arm64`, where Vulkan Whisper on Adreno drivers has not been validated on real hardware. - -`linux-x64`, `linux-arm64`, `linux-musl-x64` and `linux-musl-arm64` **bundle** the Vulkan loader -in the tarball, so they need nothing from the system. `linux-armhf` bundles none — it is CPU -Whisper in every cell, so the loader would only affect Vulkan *filters*, which reach any system -loader through FFmpeg's dlopen path. See -[Linux runtime dependencies](./linux.md#runtime-dependencies). - ---- - -Back to the [install hub](./README.md) · [Linux](./linux.md) · [Windows](./windows.md) · -[macOS](./macos.md) diff --git a/docs/install/windows.md b/docs/install/windows.md deleted file mode 100644 index 7802ca5..0000000 --- a/docs/install/windows.md +++ /dev/null @@ -1,38 +0,0 @@ -# Windows - -Part of the [install docs](./README.md). See there for the four-cell variant naming and the -cross-platform [runtime-dependency overview](./README.md#runtime-dependencies). - -Two RIDs: **`win-x64`** for Intel/AMD, and **`win-arm64`** for Windows on ARM (Snapdragon X and -similar). Substitute the RID you need in the filenames below — the layout is identical. - -`win-arm64` builds the same software codecs, but its **hardware** acceleration set is smaller, -and necessarily so: NVIDIA's nvcodec (CUDA/NVENC/NVDEC), AMD's AMF and Intel's QSV have no -Windows-on-ARM implementation at all. What remains is D3D11VA, DXVA2 and MediaFoundation, which -cover the platform's own decode paths. SVT-AV1 is also absent (its assembly is x86-only) — AV1 -encode comes from libaom and decode from dav1d instead. The Whisper filter runs on CPU there -rather than the Vulkan GPU backend used on `win-x64`. - -## Install - -```powershell -mkdir C:\opt\ffmpeg -tar -xzf ffmpeg-{VERSION}-win-x64-gplv3.tar.gz -C C:\opt\ffmpeg\ - -# Add to PATH (current session) -$env:PATH = "C:\opt\ffmpeg;$env:PATH" -``` - -DLLs and executables are in the same directory — Windows finds DLLs automatically. To *link* -the DLLs from an MSVC/CMake project, download the separate `…-win-{x64,arm64}-{gplv3,gplv2,lgplv3,lgplv2}-dev.tar.gz`, -which holds the `include/` headers and the `lib/*.lib` MSVC import libraries (see -[Development headers](./dev-headers.md)). - -Windows needs no extra runtime install: the Vulkan loader (`vulkan-1.dll`) ships with the GPU -driver, and TLS uses the OS-native **SChannel** backend in every cell (unaffected by the v2/v3 -split — see the [runtime-dependency overview](./README.md#runtime-dependencies)). - ---- - -Back to the [install hub](./README.md) · [Linux](./linux.md) · [macOS](./macos.md) · -[Whisper](./whisper.md) · [Development headers](./dev-headers.md) diff --git a/docs/matrix/README.md b/docs/matrix/README.md deleted file mode 100644 index 233554a..0000000 --- a/docs/matrix/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# Build coverage matrix - -_Auto-generated by `scripts/gen-matrix.sh` — do not edit by hand._ - -Every library FFmpeg supports × every platform, **✓** where this repo builds it. Sliced per **maintained FFmpeg major** and per **license variant** — the gpl and lgpl builds differ (gpl has x264/x265; lgpl has kvazaar — except the lean `ios-sim-arm64` slice, which carries neither pair). Markers: **✓** built · **—** not built (a choice) · **✗** (lgpl) can't include for license reasons · **n/a** not applicable on the platform. Each cell file also carries a **Version** column — the exact upstream ref each built library is pinned to in the ledger (`deps.json`), resolved for that FFmpeg major — so a dep bump changes these files, not just an FFmpeg change. - -**Four cells per FFmpeg major** — `gplv3` · `gplv2` · `lgplv3` · `lgplv2`. Family: gpl has x264/x265, lgpl has kvazaar (no x264/x265); the lean `ios-sim-arm64` slice carries none of the three. Version: **v3** links the Apache-2.0 deps — Vulkan on every RID that has it, plus OpenSSL TLS on the platforms needing a bundled backend (Linux, Android, Mac Catalyst); **v2** (App-Store-safe) uses GnuTLS (gpl) or **no TLS** (lgpl) on those platforms and drops Vulkan everywhere. Windows (SChannel) and macOS/iOS (SecureTransport) keep TLS in all four cells. Whisper falls back to CPU only where it used Vulkan — Apple is Metal in every cell, `linux-armhf` is CPU in every cell. Every cell ships **dynamic** libraries, iOS as a dynamic-framework `.xcframework`. Open two cells side by side to see exactly what differs. - -## Matrices - -- **FFmpeg 8**: [GPLv3](ffmpeg-8-gplv3.md) · [GPLv2](ffmpeg-8-gplv2.md) · [LGPLv3](ffmpeg-8-lgplv3.md) · [LGPLv2.1](ffmpeg-8-lgplv2.md) -- **FFmpeg 9**: [GPLv3](ffmpeg-9-gplv3.md) · [GPLv2](ffmpeg-9-gplv2.md) · [LGPLv3](ffmpeg-9-lgplv3.md) · [LGPLv2.1](ffmpeg-9-lgplv2.md) - -## Library support by FFmpeg version - -_Libraries FFmpeg added or removed between the maintained versions — check here to see which version you need for a given library. Libraries present in every maintained version are omitted._ - -| Library | FFmpeg 8 | FFmpeg 9 | -|---|---|---| -| CELT — audio (legacy) | ✓ | — | -| glslang — shader compile | ✓ | — | -| libonnxruntime | — | ✓ | -| OpenMAX IL | ✓ | — | -| shaderc — shader compile | ✓ | — | diff --git a/docs/matrix/ffmpeg-8-gplv2.md b/docs/matrix/ffmpeg-8-gplv2.md deleted file mode 100644 index 9df9b4a..0000000 --- a/docs/matrix/ffmpeg-8-gplv2.md +++ /dev/null @@ -1,207 +0,0 @@ -# FFmpeg 8.1.3 · GPLv2 — build coverage - -_Auto-generated by `scripts/gen-matrix.sh` from FFmpeg n8.1.3's `configure` and the build scripts — do not edit by hand. Back to the [matrix index](README.md)._ - -**✓** built · **n/a** not applicable on this platform · **—** FFmpeg supports it but we don't build it here (a choice — no license barrier) · **✗** can't be included in this cell: a GPL lib in an LGPL build, or a version3 lib (needs --enable-version3) in a v2 build — use the matching build instead - -_The **Version** column is the exact upstream ref this build pins for that library — read from the ledger (`deps.json`), resolved for this FFmpeg major (an `overrides.` hold wins over the default). It is the ref the build actually consumes — `clone_dep` checks it out for git-sourced deps, and `dep_version` substitutes it into the download URL for tarball-sourced ones — so it is what actually compiles. Blank = an FFmpeg-internal or OS-native feature with no pinned dependency, or a row not built in this cell. A dep held back only for this line shows its held ref here and so differs from the sibling major's file; if a dep ever needed a different version per platform, the version would move into the per-platform cells instead._ - -_Always-on built-in decoders (H.264/H.265/VP8/VP9 decode, AAC, PCM, …) are compiled into every build and not listed. The iOS-simulator slice is lean — a library present on the iOS device slice but dropped there shows n/a._ - -_This is the **GPLv2** cell — one of four ({gplv3, gplv2, lgplv3, lgplv2}); the siblings are linked from the [matrix index](README.md). Cells differ in x264/x265 (gpl) vs kvazaar (lgpl) — except the lean `ios-sim-arm64` slice, which carries none of the three — and in the Apache-2.0 dependencies. **v3** adds Vulkan on every RID that has it (all but `ios-sim-arm64`: the lean slice drops libplacebo, so it has no SPIR-V compiler and would register no Vulkan filters), and adds OpenSSL on the platforms that need a bundled TLS backend (Linux, Android, Mac Catalyst); **v2** uses GnuTLS (gpl) or NO TLS (lgpl) on those same platforms and drops Vulkan everywhere. Windows (SChannel) and macOS/iOS (SecureTransport) have TLS in all four cells. Dropping Vulkan sends Whisper to the CPU only where the Vulkan backend was in use: Apple targets use Metal in every cell, and `linux-armhf` is CPU in every cell. The per-RID columns below are authoritative; this paragraph is the summary. Every cell ships DYNAMIC libraries — iOS as a dynamic-framework `.xcframework`._ - - -### Video codecs -_7 of 23 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| dav1d — AV1 decode | 1.5.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libaom — AV1 enc/dec | v3.15.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libvpx — VP8/VP9 | v1.17.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| OpenH264 — H.264 encode | v2.6.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SVT-AV1 — AV1 encode[^svtav1] | v4.2.0 | ✓ | ✓ | n/a | ✓ | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| x264 — H.264 encode (GPL) | b35605ace | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| x265 — H.265 encode (GPL) | 4.3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| davs2 — AVS2 decode (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Kvazaar — HEVC encoder | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LCEVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libtheora — Theora | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenAPV — APV codec | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenHarmony HW codec | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| rav1e — AV1 encoder (Rust) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| uavs3d — AVS3 decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| vvenc — H.266/VVC encoder | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| xavs — AVS1 encode (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| xavs2 — AVS2 encode (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVD baseline — EVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVD — MPEG-5 EVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVE baseline — EVC encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVE — MPEG-5 EVC encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Xvid — MPEG-4 ASP (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Audio codecs -_6 of 22 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| libgsm — GSM | 1.0.24 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libmp3lame — MP3 encode | 4.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libopus — Opus | v1.6.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libvorbis — Vorbis | v1.3.7 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SoX resampler | 0.1.3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Speex — speech | Speex-1.2.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| bs2b — stereo→binaural | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| CELT — audio (legacy) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Codec2 — low-bitrate speech | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Flite — speech synthesis | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Game Music Emu | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| iLBC — speech | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LC3 — Bluetooth audio | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libmodplug — tracker music | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libmysofa — SOFA HRTF | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libopenmpt — tracker music | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenCORE — AMR-NB en/decode | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| OpenCORE — AMR-WB decode | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| Rubber Band — time-stretch/pitch (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Shine — fixed-point MP3 | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| TwoLAME — MP2 encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| VisualOn — AMR-WB encode | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | - -### Images / subtitles / text -_8 of 15 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| fontconfig — font-by-name[^fontconfig] | 2.18.3 | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| FreeType — drawtext | VER-2-14-3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libass — SSA/ASS subtitles | 0.17.5 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libfribidi — bidi text (drawtext) | v1.0.17 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libharfbuzz — text shaping | 14.5.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libjxl — JPEG XL | v0.12.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libwebp — WebP[^webp] | v1.6.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| OpenJPEG — JPEG 2000 | v2.5.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| ARIB caption decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Cairo — vector rendering | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libqrencode — QR encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| librsvg — SVG rasterize | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libzvbi — teletext/VBI | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| SVT JPEG-XS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Tesseract — OCR | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Processing -_4 of 19 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| Chromaprint — audio fingerprint | v1.6.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libvmaf — VMAF quality metric | v3.2.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Little CMS — color management | lcms2.19.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| zimg — scaling/colorspace | release-3.0.6 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| frei0r — effect plugins (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| glslang — shader compile | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LADSPA — audio plugins | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libplacebo — GPU processing | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LibTorch — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LV2 — audio plugins | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenColorIO | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenCV — CV filters | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenVINO — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| shaderc — shader compile | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Snappy — HAP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| TensorFlow — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| VapourSynth — frameserver | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| vid.stab — stabilization (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| ZeroMQ — zmq/azmq filters | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Speech-to-text -_1 of 2 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| whisper.cpp — af_whisper ASR | v1.9.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| PocketSphinx — speech recognition | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Networking / streaming / TLS -_5 of 14 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| GnuTLS — TLS/https[^tls] | 3.8.13 | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | — | ✓ | ✓ | — | — | ✓ | ✓ | -| RIST — reliable stream | v0.2.20 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SChannel — TLS/https (OS-native)[^tls] | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| SecureTransport — TLS/https (OS-native)[^tls] | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | ✓ | ✓ | n/a | n/a | -| SRT — secure transport | v1.5.7 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| GMP — bignum (GnuTLS dep; not enabled as an FFmpeg lib) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| libgcrypt — crypto | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| librtmp — RTMP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libssh — SFTP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libtls (LibreSSL) — TLS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| mbedTLS — SRT/librist transport crypto (not FFmpeg's own TLS backend) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| OpenSSL — TLS/https[^tls] | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| RabbitMQ — AMQP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| SMB/CIFS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Hardware acceleration -_15 of 23 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| AMF (AMD) | v1.5.3 | n/a | n/a | n/a | n/a | n/a | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| AudioToolbox | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| CUDA | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| CUVID (NVIDIA decode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| D3D11VA | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| DXVA2 | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| ffnvcodec headers | n13.1.15.0 | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| libdrm | libdrm-2.4.134 | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| MediaFoundation | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| NVDEC (NVIDIA decode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| NVENC (NVIDIA encode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| QSV (oneVPL) | v2.17.0 | ✓ | — | — | ✓ | — | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| V4L2-M2M | | ✓ | ✓ | ✓ | — | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VAAPI | 2.24.1 | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VideoToolbox | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | ✓ | ✓ | ✓ | ✓ | -| CUDA (LLVM/NVVM) | | — | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| D3D12VA[^d3d12] | | n/a | n/a | n/a | n/a | n/a | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| MMAL (Raspberry Pi) | | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| OpenCL | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenMAX IL | | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| QSV (MediaSDK, legacy) | | — | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VDPAU | | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| Vulkan (FFmpeg filters; whisper GPU only where the backend is Vulkan) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Other / miscellaneous -_4 of 23 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| JNI (Android bridge) | | — | — | — | — | — | — | — | — | — | ✓ | ✓ | — | — | — | — | -| libxml2 — DASH/IMF parse | v2.15.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| MediaCodec (Android) | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | -| zlib — deflate (matroska, png, http) | v1.3.2 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| AviSynth — frameserver (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| FireWire capture | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| JACK — audio I/O | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| KLV/VANC | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libaribb24 | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| libbluray — Blu-ray input | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libcaca — ASCII-art output | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libcdio — CD input (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libdc1394 — IIDC cameras | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libdvdnav — DVD nav (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libdvdread — DVD read (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| liblensfun | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| OpenAL — audio capture | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenGL — output | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| PulseAudio — audio I/O | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| quirc — QR decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| rkmpp | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| Video4Linux2 | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Vulkan (static ICD) | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | — | — | — | — | - -[^tls]: TLS/https backend — depends on the license SERIES. v3 builds link OpenSSL 3.x (Apache-2.0, requires --enable-version3) on Linux/Android. The App-Store-safe v2 builds instead use GnuTLS on gpl-2 (its GMP/nettle deps are fine under GPLv2) and DROP TLS ENTIRELY on lgpl-2 (GMP/nettle are never LGPLv2.1 and no other backend is either). Windows uses SChannel and macOS/iOS use SecureTransport (OS-native) in every series. Mac Catalyst is the Apple exception: SecureTransport is unavailable on macabi, so Catalyst follows the Linux/Android ladder instead. All enable the `https`/`tls` protocols EXCEPT lgpl-2 on Linux, Android and Catalyst, which have no TLS. -[^d3d12]: Not built: FFmpeg's `d3d12va` needs `ID3D12VideoDecoder` from `d3d12video.h`, which the mingw-w64 cross-toolchain doesn't ship (it has `d3d12.h` only). Windows hw decode is covered by D3D11VA + DXVA2. -[^svtav1]: Needs 64-bit and a toolchain it cross-compiles under, so it is n/a on armhf, win-arm64, Mac Catalyst and mobile. AV1 encode is still available via libaom everywhere libaom itself is built — which excludes the lean ios-sim-arm64 slice. -[^webp]: Image-only codec; not built on mobile (its CMake build ships no pkg-config file). -[^fontconfig]: Off on Windows/Android/iOS (native DirectWrite/CoreText, or an explicit `fontfile=`); libass still renders via those providers. diff --git a/docs/matrix/ffmpeg-8-gplv3.md b/docs/matrix/ffmpeg-8-gplv3.md deleted file mode 100644 index ff4e574..0000000 --- a/docs/matrix/ffmpeg-8-gplv3.md +++ /dev/null @@ -1,207 +0,0 @@ -# FFmpeg 8.1.3 · GPLv3 — build coverage - -_Auto-generated by `scripts/gen-matrix.sh` from FFmpeg n8.1.3's `configure` and the build scripts — do not edit by hand. Back to the [matrix index](README.md)._ - -**✓** built · **n/a** not applicable on this platform · **—** FFmpeg supports it but we don't build it here (a choice — no license barrier) - -_The **Version** column is the exact upstream ref this build pins for that library — read from the ledger (`deps.json`), resolved for this FFmpeg major (an `overrides.` hold wins over the default). It is the ref the build actually consumes — `clone_dep` checks it out for git-sourced deps, and `dep_version` substitutes it into the download URL for tarball-sourced ones — so it is what actually compiles. Blank = an FFmpeg-internal or OS-native feature with no pinned dependency, or a row not built in this cell. A dep held back only for this line shows its held ref here and so differs from the sibling major's file; if a dep ever needed a different version per platform, the version would move into the per-platform cells instead._ - -_Always-on built-in decoders (H.264/H.265/VP8/VP9 decode, AAC, PCM, …) are compiled into every build and not listed. The iOS-simulator slice is lean — a library present on the iOS device slice but dropped there shows n/a._ - -_This is the **GPLv3** cell — one of four ({gplv3, gplv2, lgplv3, lgplv2}); the siblings are linked from the [matrix index](README.md). Cells differ in x264/x265 (gpl) vs kvazaar (lgpl) — except the lean `ios-sim-arm64` slice, which carries none of the three — and in the Apache-2.0 dependencies. **v3** adds Vulkan on every RID that has it (all but `ios-sim-arm64`: the lean slice drops libplacebo, so it has no SPIR-V compiler and would register no Vulkan filters), and adds OpenSSL on the platforms that need a bundled TLS backend (Linux, Android, Mac Catalyst); **v2** uses GnuTLS (gpl) or NO TLS (lgpl) on those same platforms and drops Vulkan everywhere. Windows (SChannel) and macOS/iOS (SecureTransport) have TLS in all four cells. Dropping Vulkan sends Whisper to the CPU only where the Vulkan backend was in use: Apple targets use Metal in every cell, and `linux-armhf` is CPU in every cell. The per-RID columns below are authoritative; this paragraph is the summary. Every cell ships DYNAMIC libraries — iOS as a dynamic-framework `.xcframework`._ - - -### Video codecs -_7 of 23 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| dav1d — AV1 decode | 1.5.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libaom — AV1 enc/dec | v3.15.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libvpx — VP8/VP9 | v1.17.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| OpenH264 — H.264 encode | v2.6.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SVT-AV1 — AV1 encode[^svtav1] | v4.2.0 | ✓ | ✓ | n/a | ✓ | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| x264 — H.264 encode (GPL) | b35605ace | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| x265 — H.265 encode (GPL) | 4.3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| davs2 — AVS2 decode (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Kvazaar — HEVC encoder | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LCEVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libtheora — Theora | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenAPV — APV codec | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenHarmony HW codec | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| rav1e — AV1 encoder (Rust) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| uavs3d — AVS3 decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| vvenc — H.266/VVC encoder | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| xavs — AVS1 encode (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| xavs2 — AVS2 encode (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVD baseline — EVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVD — MPEG-5 EVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVE baseline — EVC encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVE — MPEG-5 EVC encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Xvid — MPEG-4 ASP (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Audio codecs -_9 of 22 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| libgsm — GSM | 1.0.24 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libmp3lame — MP3 encode | 4.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libopus — Opus | v1.6.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libvorbis — Vorbis | v1.3.7 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| OpenCORE — AMR-NB en/decode | 0.1.6 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| OpenCORE — AMR-WB decode | 0.1.6 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SoX resampler | 0.1.3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Speex — speech | Speex-1.2.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| VisualOn — AMR-WB encode | 0.1.3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| bs2b — stereo→binaural | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| CELT — audio (legacy) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Codec2 — low-bitrate speech | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Flite — speech synthesis | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Game Music Emu | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| iLBC — speech | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LC3 — Bluetooth audio | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libmodplug — tracker music | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libmysofa — SOFA HRTF | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libopenmpt — tracker music | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Rubber Band — time-stretch/pitch (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Shine — fixed-point MP3 | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| TwoLAME — MP2 encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Images / subtitles / text -_8 of 15 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| fontconfig — font-by-name[^fontconfig] | 2.18.3 | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| FreeType — drawtext | VER-2-14-3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libass — SSA/ASS subtitles | 0.17.5 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libfribidi — bidi text (drawtext) | v1.0.17 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libharfbuzz — text shaping | 14.5.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libjxl — JPEG XL | v0.12.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libwebp — WebP[^webp] | v1.6.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| OpenJPEG — JPEG 2000 | v2.5.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| ARIB caption decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Cairo — vector rendering | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libqrencode — QR encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| librsvg — SVG rasterize | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libzvbi — teletext/VBI | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| SVT JPEG-XS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Tesseract — OCR | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Processing -_6 of 19 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| Chromaprint — audio fingerprint | v1.6.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libplacebo — GPU processing | v7.360.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libvmaf — VMAF quality metric | v3.2.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Little CMS — color management | lcms2.19.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| shaderc — shader compile | v2026.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| zimg — scaling/colorspace | release-3.0.6 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| frei0r — effect plugins (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| glslang — shader compile | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LADSPA — audio plugins | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LibTorch — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LV2 — audio plugins | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenColorIO | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenCV — CV filters | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenVINO — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Snappy — HAP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| TensorFlow — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| VapourSynth — frameserver | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| vid.stab — stabilization (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| ZeroMQ — zmq/azmq filters | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Speech-to-text -_1 of 2 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| whisper.cpp — af_whisper ASR | v1.9.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| PocketSphinx — speech recognition | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Networking / streaming / TLS -_6 of 14 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| mbedTLS — SRT/librist transport crypto (not FFmpeg's own TLS backend) | v3.6.7 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| OpenSSL — TLS/https[^tls] | openssl-3.5.7 | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | — | ✓ | ✓ | — | — | ✓ | ✓ | -| RIST — reliable stream | v0.2.20 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SChannel — TLS/https (OS-native)[^tls] | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| SecureTransport — TLS/https (OS-native)[^tls] | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | ✓ | ✓ | n/a | n/a | -| SRT — secure transport | v1.5.7 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| GMP — bignum (GnuTLS dep; not enabled as an FFmpeg lib) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| GnuTLS — TLS/https[^tls] | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libgcrypt — crypto | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| librtmp — RTMP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libssh — SFTP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libtls (LibreSSL) — TLS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| RabbitMQ — AMQP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| SMB/CIFS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Hardware acceleration -_16 of 23 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| AMF (AMD) | v1.5.3 | n/a | n/a | n/a | n/a | n/a | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| AudioToolbox | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| CUDA | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| CUVID (NVIDIA decode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| D3D11VA | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| DXVA2 | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| ffnvcodec headers | n13.1.15.0 | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| libdrm | libdrm-2.4.134 | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| MediaFoundation | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| NVDEC (NVIDIA decode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| NVENC (NVIDIA encode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| QSV (oneVPL) | v2.17.0 | ✓ | — | — | ✓ | — | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| V4L2-M2M | | ✓ | ✓ | ✓ | — | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VAAPI | 2.24.1 | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VideoToolbox | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | ✓ | ✓ | ✓ | ✓ | -| Vulkan (FFmpeg filters; whisper GPU only where the backend is Vulkan) | vulkan-sdk-1.4.363.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | ✓ | ✓ | -| CUDA (LLVM/NVVM) | | — | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| D3D12VA[^d3d12] | | n/a | n/a | n/a | n/a | n/a | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| MMAL (Raspberry Pi) | | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| OpenCL | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenMAX IL | | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| QSV (MediaSDK, legacy) | | — | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VDPAU | | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | - -### Other / miscellaneous -_5 of 23 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| JNI (Android bridge) | | — | — | — | — | — | — | — | — | — | ✓ | ✓ | — | — | — | — | -| libxml2 — DASH/IMF parse | v2.15.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| MediaCodec (Android) | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | -| Vulkan (static ICD) | v1.4.2 | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | n/a | ✓ | ✓ | -| zlib — deflate (matroska, png, http) | v1.3.2 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| AviSynth — frameserver (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| FireWire capture | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| JACK — audio I/O | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| KLV/VANC | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libaribb24 | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libbluray — Blu-ray input | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libcaca — ASCII-art output | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libcdio — CD input (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libdc1394 — IIDC cameras | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libdvdnav — DVD nav (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libdvdread — DVD read (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| liblensfun | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenAL — audio capture | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenGL — output | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| PulseAudio — audio I/O | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| quirc — QR decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| rkmpp | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Video4Linux2 | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -[^tls]: TLS/https backend — depends on the license SERIES. v3 builds link OpenSSL 3.x (Apache-2.0, requires --enable-version3) on Linux/Android. The App-Store-safe v2 builds instead use GnuTLS on gpl-2 (its GMP/nettle deps are fine under GPLv2) and DROP TLS ENTIRELY on lgpl-2 (GMP/nettle are never LGPLv2.1 and no other backend is either). Windows uses SChannel and macOS/iOS use SecureTransport (OS-native) in every series. Mac Catalyst is the Apple exception: SecureTransport is unavailable on macabi, so Catalyst follows the Linux/Android ladder instead. All enable the `https`/`tls` protocols EXCEPT lgpl-2 on Linux, Android and Catalyst, which have no TLS. -[^d3d12]: Not built: FFmpeg's `d3d12va` needs `ID3D12VideoDecoder` from `d3d12video.h`, which the mingw-w64 cross-toolchain doesn't ship (it has `d3d12.h` only). Windows hw decode is covered by D3D11VA + DXVA2. -[^svtav1]: Needs 64-bit and a toolchain it cross-compiles under, so it is n/a on armhf, win-arm64, Mac Catalyst and mobile. AV1 encode is still available via libaom everywhere libaom itself is built — which excludes the lean ios-sim-arm64 slice. -[^webp]: Image-only codec; not built on mobile (its CMake build ships no pkg-config file). -[^fontconfig]: Off on Windows/Android/iOS (native DirectWrite/CoreText, or an explicit `fontfile=`); libass still renders via those providers. diff --git a/docs/matrix/ffmpeg-8-lgplv2.md b/docs/matrix/ffmpeg-8-lgplv2.md deleted file mode 100644 index 7a33a9c..0000000 --- a/docs/matrix/ffmpeg-8-lgplv2.md +++ /dev/null @@ -1,207 +0,0 @@ -# FFmpeg 8.1.3 · LGPLv2.1 — build coverage - -_Auto-generated by `scripts/gen-matrix.sh` from FFmpeg n8.1.3's `configure` and the build scripts — do not edit by hand. Back to the [matrix index](README.md)._ - -**✓** built · **n/a** not applicable on this platform · **—** FFmpeg supports it but we don't build it here (a choice — no license barrier) · **✗** can't be included in this cell: a GPL lib in an LGPL build, or a version3 lib (needs --enable-version3) in a v2 build — use the matching build instead - -_The **Version** column is the exact upstream ref this build pins for that library — read from the ledger (`deps.json`), resolved for this FFmpeg major (an `overrides.` hold wins over the default). It is the ref the build actually consumes — `clone_dep` checks it out for git-sourced deps, and `dep_version` substitutes it into the download URL for tarball-sourced ones — so it is what actually compiles. Blank = an FFmpeg-internal or OS-native feature with no pinned dependency, or a row not built in this cell. A dep held back only for this line shows its held ref here and so differs from the sibling major's file; if a dep ever needed a different version per platform, the version would move into the per-platform cells instead._ - -_Always-on built-in decoders (H.264/H.265/VP8/VP9 decode, AAC, PCM, …) are compiled into every build and not listed. The iOS-simulator slice is lean — a library present on the iOS device slice but dropped there shows n/a._ - -_This is the **LGPLv2.1** cell — one of four ({gplv3, gplv2, lgplv3, lgplv2}); the siblings are linked from the [matrix index](README.md). Cells differ in x264/x265 (gpl) vs kvazaar (lgpl) — except the lean `ios-sim-arm64` slice, which carries none of the three — and in the Apache-2.0 dependencies. **v3** adds Vulkan on every RID that has it (all but `ios-sim-arm64`: the lean slice drops libplacebo, so it has no SPIR-V compiler and would register no Vulkan filters), and adds OpenSSL on the platforms that need a bundled TLS backend (Linux, Android, Mac Catalyst); **v2** uses GnuTLS (gpl) or NO TLS (lgpl) on those same platforms and drops Vulkan everywhere. Windows (SChannel) and macOS/iOS (SecureTransport) have TLS in all four cells. Dropping Vulkan sends Whisper to the CPU only where the Vulkan backend was in use: Apple targets use Metal in every cell, and `linux-armhf` is CPU in every cell. The per-RID columns below are authoritative; this paragraph is the summary. Every cell ships DYNAMIC libraries — iOS as a dynamic-framework `.xcframework`._ - - -### Video codecs -_6 of 23 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| dav1d — AV1 decode | 1.5.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Kvazaar — HEVC encoder | v2.3.2 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libaom — AV1 enc/dec | v3.15.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libvpx — VP8/VP9 | v1.17.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| OpenH264 — H.264 encode | v2.6.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SVT-AV1 — AV1 encode[^svtav1] | v4.2.0 | ✓ | ✓ | n/a | ✓ | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| davs2 — AVS2 decode (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| LCEVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libtheora — Theora | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenAPV — APV codec | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenHarmony HW codec | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| rav1e — AV1 encoder (Rust) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| uavs3d — AVS3 decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| vvenc — H.266/VVC encoder | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| x264 — H.264 encode (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| x265 — H.265 encode (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| xavs — AVS1 encode (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| xavs2 — AVS2 encode (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| XEVD baseline — EVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVD — MPEG-5 EVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVE baseline — EVC encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVE — MPEG-5 EVC encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Xvid — MPEG-4 ASP (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | - -### Audio codecs -_6 of 22 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| libgsm — GSM | 1.0.24 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libmp3lame — MP3 encode | 4.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libopus — Opus | v1.6.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libvorbis — Vorbis | v1.3.7 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SoX resampler | 0.1.3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Speex — speech | Speex-1.2.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| bs2b — stereo→binaural | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| CELT — audio (legacy) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Codec2 — low-bitrate speech | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Flite — speech synthesis | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Game Music Emu | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| iLBC — speech | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LC3 — Bluetooth audio | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libmodplug — tracker music | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libmysofa — SOFA HRTF | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libopenmpt — tracker music | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenCORE — AMR-NB en/decode | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| OpenCORE — AMR-WB decode | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| Rubber Band — time-stretch/pitch (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| Shine — fixed-point MP3 | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| TwoLAME — MP2 encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| VisualOn — AMR-WB encode | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | - -### Images / subtitles / text -_8 of 15 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| fontconfig — font-by-name[^fontconfig] | 2.18.3 | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| FreeType — drawtext | VER-2-14-3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libass — SSA/ASS subtitles | 0.17.5 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libfribidi — bidi text (drawtext) | v1.0.17 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libharfbuzz — text shaping | 14.5.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libjxl — JPEG XL | v0.12.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libwebp — WebP[^webp] | v1.6.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| OpenJPEG — JPEG 2000 | v2.5.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| ARIB caption decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Cairo — vector rendering | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libqrencode — QR encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| librsvg — SVG rasterize | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libzvbi — teletext/VBI | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| SVT JPEG-XS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Tesseract — OCR | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Processing -_4 of 19 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| Chromaprint — audio fingerprint | v1.6.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libvmaf — VMAF quality metric | v3.2.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Little CMS — color management | lcms2.19.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| zimg — scaling/colorspace | release-3.0.6 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| frei0r — effect plugins (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| glslang — shader compile | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LADSPA — audio plugins | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libplacebo — GPU processing | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LibTorch — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LV2 — audio plugins | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenColorIO | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenCV — CV filters | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenVINO — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| shaderc — shader compile | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Snappy — HAP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| TensorFlow — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| VapourSynth — frameserver | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| vid.stab — stabilization (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| ZeroMQ — zmq/azmq filters | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Speech-to-text -_1 of 2 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| whisper.cpp — af_whisper ASR | v1.9.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| PocketSphinx — speech recognition | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Networking / streaming / TLS -_4 of 14 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| RIST — reliable stream | v0.2.20 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SChannel — TLS/https (OS-native)[^tls] | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| SecureTransport — TLS/https (OS-native)[^tls] | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | ✓ | ✓ | n/a | n/a | -| SRT — secure transport | v1.5.7 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| GMP — bignum (GnuTLS dep; not enabled as an FFmpeg lib) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| GnuTLS — TLS/https[^tls] | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libgcrypt — crypto | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| librtmp — RTMP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libssh — SFTP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libtls (LibreSSL) — TLS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| mbedTLS — SRT/librist transport crypto (not FFmpeg's own TLS backend) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| OpenSSL — TLS/https[^tls] | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| RabbitMQ — AMQP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| SMB/CIFS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Hardware acceleration -_15 of 23 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| AMF (AMD) | v1.5.3 | n/a | n/a | n/a | n/a | n/a | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| AudioToolbox | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| CUDA | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| CUVID (NVIDIA decode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| D3D11VA | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| DXVA2 | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| ffnvcodec headers | n13.1.15.0 | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| libdrm | libdrm-2.4.134 | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| MediaFoundation | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| NVDEC (NVIDIA decode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| NVENC (NVIDIA encode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| QSV (oneVPL) | v2.17.0 | ✓ | — | — | ✓ | — | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| V4L2-M2M | | ✓ | ✓ | ✓ | — | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VAAPI | 2.24.1 | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VideoToolbox | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | ✓ | ✓ | ✓ | ✓ | -| CUDA (LLVM/NVVM) | | — | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| D3D12VA[^d3d12] | | n/a | n/a | n/a | n/a | n/a | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| MMAL (Raspberry Pi) | | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| OpenCL | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenMAX IL | | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| QSV (MediaSDK, legacy) | | — | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VDPAU | | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| Vulkan (FFmpeg filters; whisper GPU only where the backend is Vulkan) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Other / miscellaneous -_4 of 23 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| JNI (Android bridge) | | — | — | — | — | — | — | — | — | — | ✓ | ✓ | — | — | — | — | -| libxml2 — DASH/IMF parse | v2.15.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| MediaCodec (Android) | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | -| zlib — deflate (matroska, png, http) | v1.3.2 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| AviSynth — frameserver (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| FireWire capture | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| JACK — audio I/O | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| KLV/VANC | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libaribb24 | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| libbluray — Blu-ray input | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libcaca — ASCII-art output | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libcdio — CD input (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| libdc1394 — IIDC cameras | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libdvdnav — DVD nav (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| libdvdread — DVD read (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| liblensfun | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| OpenAL — audio capture | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenGL — output | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| PulseAudio — audio I/O | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| quirc — QR decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| rkmpp | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| Video4Linux2 | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Vulkan (static ICD) | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | — | — | — | — | - -[^tls]: TLS/https backend — depends on the license SERIES. v3 builds link OpenSSL 3.x (Apache-2.0, requires --enable-version3) on Linux/Android. The App-Store-safe v2 builds instead use GnuTLS on gpl-2 (its GMP/nettle deps are fine under GPLv2) and DROP TLS ENTIRELY on lgpl-2 (GMP/nettle are never LGPLv2.1 and no other backend is either). Windows uses SChannel and macOS/iOS use SecureTransport (OS-native) in every series. Mac Catalyst is the Apple exception: SecureTransport is unavailable on macabi, so Catalyst follows the Linux/Android ladder instead. All enable the `https`/`tls` protocols EXCEPT lgpl-2 on Linux, Android and Catalyst, which have no TLS. -[^d3d12]: Not built: FFmpeg's `d3d12va` needs `ID3D12VideoDecoder` from `d3d12video.h`, which the mingw-w64 cross-toolchain doesn't ship (it has `d3d12.h` only). Windows hw decode is covered by D3D11VA + DXVA2. -[^svtav1]: Needs 64-bit and a toolchain it cross-compiles under, so it is n/a on armhf, win-arm64, Mac Catalyst and mobile. AV1 encode is still available via libaom everywhere libaom itself is built — which excludes the lean ios-sim-arm64 slice. -[^webp]: Image-only codec; not built on mobile (its CMake build ships no pkg-config file). -[^fontconfig]: Off on Windows/Android/iOS (native DirectWrite/CoreText, or an explicit `fontfile=`); libass still renders via those providers. diff --git a/docs/matrix/ffmpeg-8-lgplv3.md b/docs/matrix/ffmpeg-8-lgplv3.md deleted file mode 100644 index e1b62f5..0000000 --- a/docs/matrix/ffmpeg-8-lgplv3.md +++ /dev/null @@ -1,207 +0,0 @@ -# FFmpeg 8.1.3 · LGPLv3 — build coverage - -_Auto-generated by `scripts/gen-matrix.sh` from FFmpeg n8.1.3's `configure` and the build scripts — do not edit by hand. Back to the [matrix index](README.md)._ - -**✓** built · **n/a** not applicable on this platform · **—** FFmpeg supports it but we don't build it here (a choice — no license barrier) · **✗** can't be included in this cell: a GPL lib in an LGPL build, or a version3 lib (needs --enable-version3) in a v2 build — use the matching build instead - -_The **Version** column is the exact upstream ref this build pins for that library — read from the ledger (`deps.json`), resolved for this FFmpeg major (an `overrides.` hold wins over the default). It is the ref the build actually consumes — `clone_dep` checks it out for git-sourced deps, and `dep_version` substitutes it into the download URL for tarball-sourced ones — so it is what actually compiles. Blank = an FFmpeg-internal or OS-native feature with no pinned dependency, or a row not built in this cell. A dep held back only for this line shows its held ref here and so differs from the sibling major's file; if a dep ever needed a different version per platform, the version would move into the per-platform cells instead._ - -_Always-on built-in decoders (H.264/H.265/VP8/VP9 decode, AAC, PCM, …) are compiled into every build and not listed. The iOS-simulator slice is lean — a library present on the iOS device slice but dropped there shows n/a._ - -_This is the **LGPLv3** cell — one of four ({gplv3, gplv2, lgplv3, lgplv2}); the siblings are linked from the [matrix index](README.md). Cells differ in x264/x265 (gpl) vs kvazaar (lgpl) — except the lean `ios-sim-arm64` slice, which carries none of the three — and in the Apache-2.0 dependencies. **v3** adds Vulkan on every RID that has it (all but `ios-sim-arm64`: the lean slice drops libplacebo, so it has no SPIR-V compiler and would register no Vulkan filters), and adds OpenSSL on the platforms that need a bundled TLS backend (Linux, Android, Mac Catalyst); **v2** uses GnuTLS (gpl) or NO TLS (lgpl) on those same platforms and drops Vulkan everywhere. Windows (SChannel) and macOS/iOS (SecureTransport) have TLS in all four cells. Dropping Vulkan sends Whisper to the CPU only where the Vulkan backend was in use: Apple targets use Metal in every cell, and `linux-armhf` is CPU in every cell. The per-RID columns below are authoritative; this paragraph is the summary. Every cell ships DYNAMIC libraries — iOS as a dynamic-framework `.xcframework`._ - - -### Video codecs -_6 of 23 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| dav1d — AV1 decode | 1.5.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Kvazaar — HEVC encoder | v2.3.2 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libaom — AV1 enc/dec | v3.15.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libvpx — VP8/VP9 | v1.17.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| OpenH264 — H.264 encode | v2.6.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SVT-AV1 — AV1 encode[^svtav1] | v4.2.0 | ✓ | ✓ | n/a | ✓ | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| davs2 — AVS2 decode (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| LCEVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libtheora — Theora | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenAPV — APV codec | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenHarmony HW codec | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| rav1e — AV1 encoder (Rust) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| uavs3d — AVS3 decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| vvenc — H.266/VVC encoder | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| x264 — H.264 encode (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| x265 — H.265 encode (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| xavs — AVS1 encode (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| xavs2 — AVS2 encode (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| XEVD baseline — EVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVD — MPEG-5 EVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVE baseline — EVC encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVE — MPEG-5 EVC encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Xvid — MPEG-4 ASP (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | - -### Audio codecs -_9 of 22 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| libgsm — GSM | 1.0.24 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libmp3lame — MP3 encode | 4.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libopus — Opus | v1.6.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libvorbis — Vorbis | v1.3.7 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| OpenCORE — AMR-NB en/decode | 0.1.6 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| OpenCORE — AMR-WB decode | 0.1.6 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SoX resampler | 0.1.3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Speex — speech | Speex-1.2.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| VisualOn — AMR-WB encode | 0.1.3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| bs2b — stereo→binaural | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| CELT — audio (legacy) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Codec2 — low-bitrate speech | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Flite — speech synthesis | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Game Music Emu | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| iLBC — speech | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LC3 — Bluetooth audio | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libmodplug — tracker music | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libmysofa — SOFA HRTF | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libopenmpt — tracker music | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Rubber Band — time-stretch/pitch (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| Shine — fixed-point MP3 | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| TwoLAME — MP2 encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Images / subtitles / text -_8 of 15 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| fontconfig — font-by-name[^fontconfig] | 2.18.3 | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| FreeType — drawtext | VER-2-14-3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libass — SSA/ASS subtitles | 0.17.5 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libfribidi — bidi text (drawtext) | v1.0.17 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libharfbuzz — text shaping | 14.5.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libjxl — JPEG XL | v0.12.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libwebp — WebP[^webp] | v1.6.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| OpenJPEG — JPEG 2000 | v2.5.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| ARIB caption decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Cairo — vector rendering | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libqrencode — QR encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| librsvg — SVG rasterize | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libzvbi — teletext/VBI | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| SVT JPEG-XS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Tesseract — OCR | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Processing -_6 of 19 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| Chromaprint — audio fingerprint | v1.6.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libplacebo — GPU processing | v7.360.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libvmaf — VMAF quality metric | v3.2.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Little CMS — color management | lcms2.19.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| shaderc — shader compile | v2026.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| zimg — scaling/colorspace | release-3.0.6 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| frei0r — effect plugins (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| glslang — shader compile | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LADSPA — audio plugins | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LibTorch — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LV2 — audio plugins | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenColorIO | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenCV — CV filters | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenVINO — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Snappy — HAP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| TensorFlow — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| VapourSynth — frameserver | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| vid.stab — stabilization (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| ZeroMQ — zmq/azmq filters | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Speech-to-text -_1 of 2 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| whisper.cpp — af_whisper ASR | v1.9.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| PocketSphinx — speech recognition | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Networking / streaming / TLS -_6 of 14 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| mbedTLS — SRT/librist transport crypto (not FFmpeg's own TLS backend) | v3.6.7 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| OpenSSL — TLS/https[^tls] | openssl-3.5.7 | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | — | ✓ | ✓ | — | — | ✓ | ✓ | -| RIST — reliable stream | v0.2.20 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SChannel — TLS/https (OS-native)[^tls] | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| SecureTransport — TLS/https (OS-native)[^tls] | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | ✓ | ✓ | n/a | n/a | -| SRT — secure transport | v1.5.7 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| GMP — bignum (GnuTLS dep; not enabled as an FFmpeg lib) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| GnuTLS — TLS/https[^tls] | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libgcrypt — crypto | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| librtmp — RTMP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libssh — SFTP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libtls (LibreSSL) — TLS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| RabbitMQ — AMQP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| SMB/CIFS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Hardware acceleration -_16 of 23 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| AMF (AMD) | v1.5.3 | n/a | n/a | n/a | n/a | n/a | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| AudioToolbox | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| CUDA | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| CUVID (NVIDIA decode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| D3D11VA | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| DXVA2 | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| ffnvcodec headers | n13.1.15.0 | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| libdrm | libdrm-2.4.134 | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| MediaFoundation | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| NVDEC (NVIDIA decode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| NVENC (NVIDIA encode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| QSV (oneVPL) | v2.17.0 | ✓ | — | — | ✓ | — | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| V4L2-M2M | | ✓ | ✓ | ✓ | — | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VAAPI | 2.24.1 | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VideoToolbox | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | ✓ | ✓ | ✓ | ✓ | -| Vulkan (FFmpeg filters; whisper GPU only where the backend is Vulkan) | vulkan-sdk-1.4.363.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | ✓ | ✓ | -| CUDA (LLVM/NVVM) | | — | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| D3D12VA[^d3d12] | | n/a | n/a | n/a | n/a | n/a | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| MMAL (Raspberry Pi) | | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| OpenCL | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenMAX IL | | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| QSV (MediaSDK, legacy) | | — | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VDPAU | | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | - -### Other / miscellaneous -_5 of 23 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| JNI (Android bridge) | | — | — | — | — | — | — | — | — | — | ✓ | ✓ | — | — | — | — | -| libxml2 — DASH/IMF parse | v2.15.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| MediaCodec (Android) | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | -| Vulkan (static ICD) | v1.4.2 | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | n/a | ✓ | ✓ | -| zlib — deflate (matroska, png, http) | v1.3.2 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| AviSynth — frameserver (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| FireWire capture | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| JACK — audio I/O | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| KLV/VANC | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libaribb24 | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libbluray — Blu-ray input | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libcaca — ASCII-art output | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libcdio — CD input (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| libdc1394 — IIDC cameras | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libdvdnav — DVD nav (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| libdvdread — DVD read (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| liblensfun | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenAL — audio capture | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenGL — output | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| PulseAudio — audio I/O | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| quirc — QR decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| rkmpp | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Video4Linux2 | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -[^tls]: TLS/https backend — depends on the license SERIES. v3 builds link OpenSSL 3.x (Apache-2.0, requires --enable-version3) on Linux/Android. The App-Store-safe v2 builds instead use GnuTLS on gpl-2 (its GMP/nettle deps are fine under GPLv2) and DROP TLS ENTIRELY on lgpl-2 (GMP/nettle are never LGPLv2.1 and no other backend is either). Windows uses SChannel and macOS/iOS use SecureTransport (OS-native) in every series. Mac Catalyst is the Apple exception: SecureTransport is unavailable on macabi, so Catalyst follows the Linux/Android ladder instead. All enable the `https`/`tls` protocols EXCEPT lgpl-2 on Linux, Android and Catalyst, which have no TLS. -[^d3d12]: Not built: FFmpeg's `d3d12va` needs `ID3D12VideoDecoder` from `d3d12video.h`, which the mingw-w64 cross-toolchain doesn't ship (it has `d3d12.h` only). Windows hw decode is covered by D3D11VA + DXVA2. -[^svtav1]: Needs 64-bit and a toolchain it cross-compiles under, so it is n/a on armhf, win-arm64, Mac Catalyst and mobile. AV1 encode is still available via libaom everywhere libaom itself is built — which excludes the lean ios-sim-arm64 slice. -[^webp]: Image-only codec; not built on mobile (its CMake build ships no pkg-config file). -[^fontconfig]: Off on Windows/Android/iOS (native DirectWrite/CoreText, or an explicit `fontfile=`); libass still renders via those providers. diff --git a/docs/matrix/ffmpeg-9-gplv2.md b/docs/matrix/ffmpeg-9-gplv2.md deleted file mode 100644 index aca7699..0000000 --- a/docs/matrix/ffmpeg-9-gplv2.md +++ /dev/null @@ -1,204 +0,0 @@ -# FFmpeg 9.0.2 · GPLv2 — build coverage - -_Auto-generated by `scripts/gen-matrix.sh` from FFmpeg n9.0.2's `configure` and the build scripts — do not edit by hand. Back to the [matrix index](README.md)._ - -**✓** built · **n/a** not applicable on this platform · **—** FFmpeg supports it but we don't build it here (a choice — no license barrier) · **✗** can't be included in this cell: a GPL lib in an LGPL build, or a version3 lib (needs --enable-version3) in a v2 build — use the matching build instead - -_The **Version** column is the exact upstream ref this build pins for that library — read from the ledger (`deps.json`), resolved for this FFmpeg major (an `overrides.` hold wins over the default). It is the ref the build actually consumes — `clone_dep` checks it out for git-sourced deps, and `dep_version` substitutes it into the download URL for tarball-sourced ones — so it is what actually compiles. Blank = an FFmpeg-internal or OS-native feature with no pinned dependency, or a row not built in this cell. A dep held back only for this line shows its held ref here and so differs from the sibling major's file; if a dep ever needed a different version per platform, the version would move into the per-platform cells instead._ - -_Always-on built-in decoders (H.264/H.265/VP8/VP9 decode, AAC, PCM, …) are compiled into every build and not listed. The iOS-simulator slice is lean — a library present on the iOS device slice but dropped there shows n/a._ - -_This is the **GPLv2** cell — one of four ({gplv3, gplv2, lgplv3, lgplv2}); the siblings are linked from the [matrix index](README.md). Cells differ in x264/x265 (gpl) vs kvazaar (lgpl) — except the lean `ios-sim-arm64` slice, which carries none of the three — and in the Apache-2.0 dependencies. **v3** adds Vulkan on every RID that has it (all but `ios-sim-arm64`: the lean slice drops libplacebo, so it has no SPIR-V compiler and would register no Vulkan filters), and adds OpenSSL on the platforms that need a bundled TLS backend (Linux, Android, Mac Catalyst); **v2** uses GnuTLS (gpl) or NO TLS (lgpl) on those same platforms and drops Vulkan everywhere. Windows (SChannel) and macOS/iOS (SecureTransport) have TLS in all four cells. Dropping Vulkan sends Whisper to the CPU only where the Vulkan backend was in use: Apple targets use Metal in every cell, and `linux-armhf` is CPU in every cell. The per-RID columns below are authoritative; this paragraph is the summary. Every cell ships DYNAMIC libraries — iOS as a dynamic-framework `.xcframework`._ - - -### Video codecs -_7 of 23 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| dav1d — AV1 decode | 1.5.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libaom — AV1 enc/dec | v3.15.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libvpx — VP8/VP9 | v1.17.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| OpenH264 — H.264 encode | v2.6.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SVT-AV1 — AV1 encode[^svtav1] | v4.2.0 | ✓ | ✓ | n/a | ✓ | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| x264 — H.264 encode (GPL) | b35605ace | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| x265 — H.265 encode (GPL) | 4.3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| davs2 — AVS2 decode (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Kvazaar — HEVC encoder | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LCEVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libtheora — Theora | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenAPV — APV codec | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenHarmony HW codec | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| rav1e — AV1 encoder (Rust) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| uavs3d — AVS3 decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| vvenc — H.266/VVC encoder | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| xavs — AVS1 encode (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| xavs2 — AVS2 encode (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVD baseline — EVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVD — MPEG-5 EVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVE baseline — EVC encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVE — MPEG-5 EVC encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Xvid — MPEG-4 ASP (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Audio codecs -_6 of 21 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| libgsm — GSM | 1.0.24 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libmp3lame — MP3 encode | 4.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libopus — Opus | v1.6.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libvorbis — Vorbis | v1.3.7 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SoX resampler | 0.1.3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Speex — speech | Speex-1.2.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| bs2b — stereo→binaural | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Codec2 — low-bitrate speech | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Flite — speech synthesis | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Game Music Emu | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| iLBC — speech | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LC3 — Bluetooth audio | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libmodplug — tracker music | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libmysofa — SOFA HRTF | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libopenmpt — tracker music | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenCORE — AMR-NB en/decode | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| OpenCORE — AMR-WB decode | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| Rubber Band — time-stretch/pitch (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Shine — fixed-point MP3 | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| TwoLAME — MP2 encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| VisualOn — AMR-WB encode | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | - -### Images / subtitles / text -_8 of 15 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| fontconfig — font-by-name[^fontconfig] | 2.18.3 | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| FreeType — drawtext | VER-2-14-3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libass — SSA/ASS subtitles | 0.17.5 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libfribidi — bidi text (drawtext) | v1.0.17 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libharfbuzz — text shaping | 14.5.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libjxl — JPEG XL | v0.12.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libwebp — WebP[^webp] | v1.6.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| OpenJPEG — JPEG 2000 | v2.5.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| ARIB caption decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Cairo — vector rendering | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libqrencode — QR encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| librsvg — SVG rasterize | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libzvbi — teletext/VBI | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| SVT JPEG-XS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Tesseract — OCR | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Processing -_4 of 17 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| Chromaprint — audio fingerprint | v1.6.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libvmaf — VMAF quality metric | v3.2.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Little CMS — color management | lcms2.19.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| zimg — scaling/colorspace | release-3.0.6 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| frei0r — effect plugins (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LADSPA — audio plugins | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libplacebo — GPU processing | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LibTorch — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LV2 — audio plugins | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenColorIO | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenCV — CV filters | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenVINO — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Snappy — HAP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| TensorFlow — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| VapourSynth — frameserver | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| vid.stab — stabilization (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| ZeroMQ — zmq/azmq filters | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Speech-to-text -_1 of 2 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| whisper.cpp — af_whisper ASR | v1.9.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| PocketSphinx — speech recognition | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Networking / streaming / TLS -_5 of 14 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| GnuTLS — TLS/https[^tls] | 3.8.13 | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | — | ✓ | ✓ | — | — | ✓ | ✓ | -| RIST — reliable stream | v0.2.20 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SChannel — TLS/https (OS-native)[^tls] | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| SecureTransport — TLS/https (OS-native)[^tls] | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | ✓ | ✓ | n/a | n/a | -| SRT — secure transport | v1.5.7 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| GMP — bignum (GnuTLS dep; not enabled as an FFmpeg lib) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| libgcrypt — crypto | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| librtmp — RTMP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libssh — SFTP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libtls (LibreSSL) — TLS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| mbedTLS — SRT/librist transport crypto (not FFmpeg's own TLS backend) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| OpenSSL — TLS/https[^tls] | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| RabbitMQ — AMQP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| SMB/CIFS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Hardware acceleration -_15 of 22 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| AMF (AMD) | v1.5.3 | n/a | n/a | n/a | n/a | n/a | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| AudioToolbox | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| CUDA | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| CUVID (NVIDIA decode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| D3D11VA | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| DXVA2 | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| ffnvcodec headers | n13.1.15.0 | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| libdrm | libdrm-2.4.134 | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| MediaFoundation | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| NVDEC (NVIDIA decode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| NVENC (NVIDIA encode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| QSV (oneVPL) | v2.17.0 | ✓ | — | — | ✓ | — | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| V4L2-M2M | | ✓ | ✓ | ✓ | — | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VAAPI | 2.24.1 | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VideoToolbox | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | ✓ | ✓ | ✓ | ✓ | -| CUDA (LLVM/NVVM) | | — | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| D3D12VA[^d3d12] | | n/a | n/a | n/a | n/a | n/a | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| MMAL (Raspberry Pi) | | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| OpenCL | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| QSV (MediaSDK, legacy) | | — | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VDPAU | | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| Vulkan (FFmpeg filters; whisper GPU only where the backend is Vulkan) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Other / miscellaneous -_4 of 24 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| JNI (Android bridge) | | — | — | — | — | — | — | — | — | — | ✓ | ✓ | — | — | — | — | -| libxml2 — DASH/IMF parse | v2.15.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| MediaCodec (Android) | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | -| zlib — deflate (matroska, png, http) | v1.3.2 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| AviSynth — frameserver (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| FireWire capture | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| JACK — audio I/O | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| KLV/VANC | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libaribb24 | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| libbluray — Blu-ray input | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libcaca — ASCII-art output | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libcdio — CD input (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libdc1394 — IIDC cameras | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libdvdnav — DVD nav (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libdvdread — DVD read (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| liblensfun | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| libonnxruntime | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenAL — audio capture | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenGL — output | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| PulseAudio — audio I/O | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| quirc — QR decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| rkmpp | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| Video4Linux2 | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Vulkan (static ICD) | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | — | — | — | — | - -[^tls]: TLS/https backend — depends on the license SERIES. v3 builds link OpenSSL 3.x (Apache-2.0, requires --enable-version3) on Linux/Android. The App-Store-safe v2 builds instead use GnuTLS on gpl-2 (its GMP/nettle deps are fine under GPLv2) and DROP TLS ENTIRELY on lgpl-2 (GMP/nettle are never LGPLv2.1 and no other backend is either). Windows uses SChannel and macOS/iOS use SecureTransport (OS-native) in every series. Mac Catalyst is the Apple exception: SecureTransport is unavailable on macabi, so Catalyst follows the Linux/Android ladder instead. All enable the `https`/`tls` protocols EXCEPT lgpl-2 on Linux, Android and Catalyst, which have no TLS. -[^d3d12]: Not built: FFmpeg's `d3d12va` needs `ID3D12VideoDecoder` from `d3d12video.h`, which the mingw-w64 cross-toolchain doesn't ship (it has `d3d12.h` only). Windows hw decode is covered by D3D11VA + DXVA2. -[^svtav1]: Needs 64-bit and a toolchain it cross-compiles under, so it is n/a on armhf, win-arm64, Mac Catalyst and mobile. AV1 encode is still available via libaom everywhere libaom itself is built — which excludes the lean ios-sim-arm64 slice. -[^webp]: Image-only codec; not built on mobile (its CMake build ships no pkg-config file). -[^fontconfig]: Off on Windows/Android/iOS (native DirectWrite/CoreText, or an explicit `fontfile=`); libass still renders via those providers. diff --git a/docs/matrix/ffmpeg-9-gplv3.md b/docs/matrix/ffmpeg-9-gplv3.md deleted file mode 100644 index 3a4b8e9..0000000 --- a/docs/matrix/ffmpeg-9-gplv3.md +++ /dev/null @@ -1,204 +0,0 @@ -# FFmpeg 9.0.2 · GPLv3 — build coverage - -_Auto-generated by `scripts/gen-matrix.sh` from FFmpeg n9.0.2's `configure` and the build scripts — do not edit by hand. Back to the [matrix index](README.md)._ - -**✓** built · **n/a** not applicable on this platform · **—** FFmpeg supports it but we don't build it here (a choice — no license barrier) - -_The **Version** column is the exact upstream ref this build pins for that library — read from the ledger (`deps.json`), resolved for this FFmpeg major (an `overrides.` hold wins over the default). It is the ref the build actually consumes — `clone_dep` checks it out for git-sourced deps, and `dep_version` substitutes it into the download URL for tarball-sourced ones — so it is what actually compiles. Blank = an FFmpeg-internal or OS-native feature with no pinned dependency, or a row not built in this cell. A dep held back only for this line shows its held ref here and so differs from the sibling major's file; if a dep ever needed a different version per platform, the version would move into the per-platform cells instead._ - -_Always-on built-in decoders (H.264/H.265/VP8/VP9 decode, AAC, PCM, …) are compiled into every build and not listed. The iOS-simulator slice is lean — a library present on the iOS device slice but dropped there shows n/a._ - -_This is the **GPLv3** cell — one of four ({gplv3, gplv2, lgplv3, lgplv2}); the siblings are linked from the [matrix index](README.md). Cells differ in x264/x265 (gpl) vs kvazaar (lgpl) — except the lean `ios-sim-arm64` slice, which carries none of the three — and in the Apache-2.0 dependencies. **v3** adds Vulkan on every RID that has it (all but `ios-sim-arm64`: the lean slice drops libplacebo, so it has no SPIR-V compiler and would register no Vulkan filters), and adds OpenSSL on the platforms that need a bundled TLS backend (Linux, Android, Mac Catalyst); **v2** uses GnuTLS (gpl) or NO TLS (lgpl) on those same platforms and drops Vulkan everywhere. Windows (SChannel) and macOS/iOS (SecureTransport) have TLS in all four cells. Dropping Vulkan sends Whisper to the CPU only where the Vulkan backend was in use: Apple targets use Metal in every cell, and `linux-armhf` is CPU in every cell. The per-RID columns below are authoritative; this paragraph is the summary. Every cell ships DYNAMIC libraries — iOS as a dynamic-framework `.xcframework`._ - - -### Video codecs -_7 of 23 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| dav1d — AV1 decode | 1.5.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libaom — AV1 enc/dec | v3.15.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libvpx — VP8/VP9 | v1.17.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| OpenH264 — H.264 encode | v2.6.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SVT-AV1 — AV1 encode[^svtav1] | v4.2.0 | ✓ | ✓ | n/a | ✓ | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| x264 — H.264 encode (GPL) | b35605ace | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| x265 — H.265 encode (GPL) | 4.3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| davs2 — AVS2 decode (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Kvazaar — HEVC encoder | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LCEVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libtheora — Theora | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenAPV — APV codec | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenHarmony HW codec | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| rav1e — AV1 encoder (Rust) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| uavs3d — AVS3 decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| vvenc — H.266/VVC encoder | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| xavs — AVS1 encode (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| xavs2 — AVS2 encode (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVD baseline — EVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVD — MPEG-5 EVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVE baseline — EVC encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVE — MPEG-5 EVC encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Xvid — MPEG-4 ASP (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Audio codecs -_9 of 21 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| libgsm — GSM | 1.0.24 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libmp3lame — MP3 encode | 4.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libopus — Opus | v1.6.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libvorbis — Vorbis | v1.3.7 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| OpenCORE — AMR-NB en/decode | 0.1.6 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| OpenCORE — AMR-WB decode | 0.1.6 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SoX resampler | 0.1.3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Speex — speech | Speex-1.2.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| VisualOn — AMR-WB encode | 0.1.3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| bs2b — stereo→binaural | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Codec2 — low-bitrate speech | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Flite — speech synthesis | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Game Music Emu | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| iLBC — speech | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LC3 — Bluetooth audio | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libmodplug — tracker music | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libmysofa — SOFA HRTF | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libopenmpt — tracker music | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Rubber Band — time-stretch/pitch (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Shine — fixed-point MP3 | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| TwoLAME — MP2 encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Images / subtitles / text -_8 of 15 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| fontconfig — font-by-name[^fontconfig] | 2.18.3 | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| FreeType — drawtext | VER-2-14-3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libass — SSA/ASS subtitles | 0.17.5 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libfribidi — bidi text (drawtext) | v1.0.17 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libharfbuzz — text shaping | 14.5.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libjxl — JPEG XL | v0.12.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libwebp — WebP[^webp] | v1.6.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| OpenJPEG — JPEG 2000 | v2.5.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| ARIB caption decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Cairo — vector rendering | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libqrencode — QR encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| librsvg — SVG rasterize | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libzvbi — teletext/VBI | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| SVT JPEG-XS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Tesseract — OCR | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Processing -_5 of 17 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| Chromaprint — audio fingerprint | v1.6.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libplacebo — GPU processing | v7.360.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libvmaf — VMAF quality metric | v3.2.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Little CMS — color management | lcms2.19.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| zimg — scaling/colorspace | release-3.0.6 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| frei0r — effect plugins (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LADSPA — audio plugins | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LibTorch — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LV2 — audio plugins | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenColorIO | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenCV — CV filters | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenVINO — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Snappy — HAP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| TensorFlow — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| VapourSynth — frameserver | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| vid.stab — stabilization (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| ZeroMQ — zmq/azmq filters | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Speech-to-text -_1 of 2 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| whisper.cpp — af_whisper ASR | v1.9.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| PocketSphinx — speech recognition | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Networking / streaming / TLS -_6 of 14 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| mbedTLS — SRT/librist transport crypto (not FFmpeg's own TLS backend) | v3.6.7 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| OpenSSL — TLS/https[^tls] | openssl-3.5.7 | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | — | ✓ | ✓ | — | — | ✓ | ✓ | -| RIST — reliable stream | v0.2.20 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SChannel — TLS/https (OS-native)[^tls] | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| SecureTransport — TLS/https (OS-native)[^tls] | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | ✓ | ✓ | n/a | n/a | -| SRT — secure transport | v1.5.7 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| GMP — bignum (GnuTLS dep; not enabled as an FFmpeg lib) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| GnuTLS — TLS/https[^tls] | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libgcrypt — crypto | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| librtmp — RTMP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libssh — SFTP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libtls (LibreSSL) — TLS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| RabbitMQ — AMQP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| SMB/CIFS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Hardware acceleration -_16 of 22 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| AMF (AMD) | v1.5.3 | n/a | n/a | n/a | n/a | n/a | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| AudioToolbox | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| CUDA | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| CUVID (NVIDIA decode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| D3D11VA | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| DXVA2 | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| ffnvcodec headers | n13.1.15.0 | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| libdrm | libdrm-2.4.134 | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| MediaFoundation | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| NVDEC (NVIDIA decode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| NVENC (NVIDIA encode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| QSV (oneVPL) | v2.17.0 | ✓ | — | — | ✓ | — | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| V4L2-M2M | | ✓ | ✓ | ✓ | — | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VAAPI | 2.24.1 | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VideoToolbox | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | ✓ | ✓ | ✓ | ✓ | -| Vulkan (FFmpeg filters; whisper GPU only where the backend is Vulkan) | vulkan-sdk-1.4.363.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | ✓ | ✓ | -| CUDA (LLVM/NVVM) | | — | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| D3D12VA[^d3d12] | | n/a | n/a | n/a | n/a | n/a | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| MMAL (Raspberry Pi) | | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| OpenCL | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| QSV (MediaSDK, legacy) | | — | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VDPAU | | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | - -### Other / miscellaneous -_5 of 24 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| JNI (Android bridge) | | — | — | — | — | — | — | — | — | — | ✓ | ✓ | — | — | — | — | -| libxml2 — DASH/IMF parse | v2.15.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| MediaCodec (Android) | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | -| Vulkan (static ICD) | v1.4.2 | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | n/a | ✓ | ✓ | -| zlib — deflate (matroska, png, http) | v1.3.2 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| AviSynth — frameserver (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| FireWire capture | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| JACK — audio I/O | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| KLV/VANC | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libaribb24 | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libbluray — Blu-ray input | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libcaca — ASCII-art output | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libcdio — CD input (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libdc1394 — IIDC cameras | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libdvdnav — DVD nav (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libdvdread — DVD read (GPL) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| liblensfun | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libonnxruntime | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenAL — audio capture | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenGL — output | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| PulseAudio — audio I/O | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| quirc — QR decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| rkmpp | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Video4Linux2 | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -[^tls]: TLS/https backend — depends on the license SERIES. v3 builds link OpenSSL 3.x (Apache-2.0, requires --enable-version3) on Linux/Android. The App-Store-safe v2 builds instead use GnuTLS on gpl-2 (its GMP/nettle deps are fine under GPLv2) and DROP TLS ENTIRELY on lgpl-2 (GMP/nettle are never LGPLv2.1 and no other backend is either). Windows uses SChannel and macOS/iOS use SecureTransport (OS-native) in every series. Mac Catalyst is the Apple exception: SecureTransport is unavailable on macabi, so Catalyst follows the Linux/Android ladder instead. All enable the `https`/`tls` protocols EXCEPT lgpl-2 on Linux, Android and Catalyst, which have no TLS. -[^d3d12]: Not built: FFmpeg's `d3d12va` needs `ID3D12VideoDecoder` from `d3d12video.h`, which the mingw-w64 cross-toolchain doesn't ship (it has `d3d12.h` only). Windows hw decode is covered by D3D11VA + DXVA2. -[^svtav1]: Needs 64-bit and a toolchain it cross-compiles under, so it is n/a on armhf, win-arm64, Mac Catalyst and mobile. AV1 encode is still available via libaom everywhere libaom itself is built — which excludes the lean ios-sim-arm64 slice. -[^webp]: Image-only codec; not built on mobile (its CMake build ships no pkg-config file). -[^fontconfig]: Off on Windows/Android/iOS (native DirectWrite/CoreText, or an explicit `fontfile=`); libass still renders via those providers. diff --git a/docs/matrix/ffmpeg-9-lgplv2.md b/docs/matrix/ffmpeg-9-lgplv2.md deleted file mode 100644 index e54c461..0000000 --- a/docs/matrix/ffmpeg-9-lgplv2.md +++ /dev/null @@ -1,204 +0,0 @@ -# FFmpeg 9.0.2 · LGPLv2.1 — build coverage - -_Auto-generated by `scripts/gen-matrix.sh` from FFmpeg n9.0.2's `configure` and the build scripts — do not edit by hand. Back to the [matrix index](README.md)._ - -**✓** built · **n/a** not applicable on this platform · **—** FFmpeg supports it but we don't build it here (a choice — no license barrier) · **✗** can't be included in this cell: a GPL lib in an LGPL build, or a version3 lib (needs --enable-version3) in a v2 build — use the matching build instead - -_The **Version** column is the exact upstream ref this build pins for that library — read from the ledger (`deps.json`), resolved for this FFmpeg major (an `overrides.` hold wins over the default). It is the ref the build actually consumes — `clone_dep` checks it out for git-sourced deps, and `dep_version` substitutes it into the download URL for tarball-sourced ones — so it is what actually compiles. Blank = an FFmpeg-internal or OS-native feature with no pinned dependency, or a row not built in this cell. A dep held back only for this line shows its held ref here and so differs from the sibling major's file; if a dep ever needed a different version per platform, the version would move into the per-platform cells instead._ - -_Always-on built-in decoders (H.264/H.265/VP8/VP9 decode, AAC, PCM, …) are compiled into every build and not listed. The iOS-simulator slice is lean — a library present on the iOS device slice but dropped there shows n/a._ - -_This is the **LGPLv2.1** cell — one of four ({gplv3, gplv2, lgplv3, lgplv2}); the siblings are linked from the [matrix index](README.md). Cells differ in x264/x265 (gpl) vs kvazaar (lgpl) — except the lean `ios-sim-arm64` slice, which carries none of the three — and in the Apache-2.0 dependencies. **v3** adds Vulkan on every RID that has it (all but `ios-sim-arm64`: the lean slice drops libplacebo, so it has no SPIR-V compiler and would register no Vulkan filters), and adds OpenSSL on the platforms that need a bundled TLS backend (Linux, Android, Mac Catalyst); **v2** uses GnuTLS (gpl) or NO TLS (lgpl) on those same platforms and drops Vulkan everywhere. Windows (SChannel) and macOS/iOS (SecureTransport) have TLS in all four cells. Dropping Vulkan sends Whisper to the CPU only where the Vulkan backend was in use: Apple targets use Metal in every cell, and `linux-armhf` is CPU in every cell. The per-RID columns below are authoritative; this paragraph is the summary. Every cell ships DYNAMIC libraries — iOS as a dynamic-framework `.xcframework`._ - - -### Video codecs -_6 of 23 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| dav1d — AV1 decode | 1.5.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Kvazaar — HEVC encoder | v2.3.2 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libaom — AV1 enc/dec | v3.15.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libvpx — VP8/VP9 | v1.17.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| OpenH264 — H.264 encode | v2.6.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SVT-AV1 — AV1 encode[^svtav1] | v4.2.0 | ✓ | ✓ | n/a | ✓ | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| davs2 — AVS2 decode (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| LCEVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libtheora — Theora | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenAPV — APV codec | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenHarmony HW codec | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| rav1e — AV1 encoder (Rust) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| uavs3d — AVS3 decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| vvenc — H.266/VVC encoder | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| x264 — H.264 encode (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| x265 — H.265 encode (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| xavs — AVS1 encode (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| xavs2 — AVS2 encode (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| XEVD baseline — EVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVD — MPEG-5 EVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVE baseline — EVC encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVE — MPEG-5 EVC encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Xvid — MPEG-4 ASP (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | - -### Audio codecs -_6 of 21 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| libgsm — GSM | 1.0.24 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libmp3lame — MP3 encode | 4.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libopus — Opus | v1.6.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libvorbis — Vorbis | v1.3.7 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SoX resampler | 0.1.3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Speex — speech | Speex-1.2.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| bs2b — stereo→binaural | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Codec2 — low-bitrate speech | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Flite — speech synthesis | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Game Music Emu | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| iLBC — speech | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LC3 — Bluetooth audio | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libmodplug — tracker music | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libmysofa — SOFA HRTF | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libopenmpt — tracker music | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenCORE — AMR-NB en/decode | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| OpenCORE — AMR-WB decode | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| Rubber Band — time-stretch/pitch (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| Shine — fixed-point MP3 | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| TwoLAME — MP2 encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| VisualOn — AMR-WB encode | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | - -### Images / subtitles / text -_8 of 15 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| fontconfig — font-by-name[^fontconfig] | 2.18.3 | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| FreeType — drawtext | VER-2-14-3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libass — SSA/ASS subtitles | 0.17.5 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libfribidi — bidi text (drawtext) | v1.0.17 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libharfbuzz — text shaping | 14.5.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libjxl — JPEG XL | v0.12.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libwebp — WebP[^webp] | v1.6.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| OpenJPEG — JPEG 2000 | v2.5.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| ARIB caption decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Cairo — vector rendering | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libqrencode — QR encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| librsvg — SVG rasterize | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libzvbi — teletext/VBI | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| SVT JPEG-XS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Tesseract — OCR | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Processing -_4 of 17 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| Chromaprint — audio fingerprint | v1.6.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libvmaf — VMAF quality metric | v3.2.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Little CMS — color management | lcms2.19.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| zimg — scaling/colorspace | release-3.0.6 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| frei0r — effect plugins (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| LADSPA — audio plugins | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libplacebo — GPU processing | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LibTorch — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LV2 — audio plugins | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenColorIO | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenCV — CV filters | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenVINO — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Snappy — HAP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| TensorFlow — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| VapourSynth — frameserver | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| vid.stab — stabilization (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| ZeroMQ — zmq/azmq filters | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Speech-to-text -_1 of 2 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| whisper.cpp — af_whisper ASR | v1.9.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| PocketSphinx — speech recognition | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Networking / streaming / TLS -_4 of 14 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| RIST — reliable stream | v0.2.20 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SChannel — TLS/https (OS-native)[^tls] | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| SecureTransport — TLS/https (OS-native)[^tls] | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | ✓ | ✓ | n/a | n/a | -| SRT — secure transport | v1.5.7 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| GMP — bignum (GnuTLS dep; not enabled as an FFmpeg lib) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| GnuTLS — TLS/https[^tls] | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libgcrypt — crypto | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| librtmp — RTMP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libssh — SFTP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libtls (LibreSSL) — TLS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| mbedTLS — SRT/librist transport crypto (not FFmpeg's own TLS backend) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| OpenSSL — TLS/https[^tls] | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| RabbitMQ — AMQP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| SMB/CIFS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Hardware acceleration -_15 of 22 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| AMF (AMD) | v1.5.3 | n/a | n/a | n/a | n/a | n/a | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| AudioToolbox | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| CUDA | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| CUVID (NVIDIA decode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| D3D11VA | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| DXVA2 | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| ffnvcodec headers | n13.1.15.0 | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| libdrm | libdrm-2.4.134 | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| MediaFoundation | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| NVDEC (NVIDIA decode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| NVENC (NVIDIA encode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| QSV (oneVPL) | v2.17.0 | ✓ | — | — | ✓ | — | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| V4L2-M2M | | ✓ | ✓ | ✓ | — | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VAAPI | 2.24.1 | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VideoToolbox | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | ✓ | ✓ | ✓ | ✓ | -| CUDA (LLVM/NVVM) | | — | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| D3D12VA[^d3d12] | | n/a | n/a | n/a | n/a | n/a | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| MMAL (Raspberry Pi) | | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| OpenCL | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| QSV (MediaSDK, legacy) | | — | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VDPAU | | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| Vulkan (FFmpeg filters; whisper GPU only where the backend is Vulkan) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Other / miscellaneous -_4 of 24 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| JNI (Android bridge) | | — | — | — | — | — | — | — | — | — | ✓ | ✓ | — | — | — | — | -| libxml2 — DASH/IMF parse | v2.15.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| MediaCodec (Android) | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | -| zlib — deflate (matroska, png, http) | v1.3.2 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| AviSynth — frameserver (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| FireWire capture | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| JACK — audio I/O | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| KLV/VANC | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libaribb24 | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| libbluray — Blu-ray input | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libcaca — ASCII-art output | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libcdio — CD input (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| libdc1394 — IIDC cameras | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libdvdnav — DVD nav (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| libdvdread — DVD read (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| liblensfun | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| libonnxruntime | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenAL — audio capture | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenGL — output | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| PulseAudio — audio I/O | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| quirc — QR decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| rkmpp | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| Video4Linux2 | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Vulkan (static ICD) | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | — | — | — | — | - -[^tls]: TLS/https backend — depends on the license SERIES. v3 builds link OpenSSL 3.x (Apache-2.0, requires --enable-version3) on Linux/Android. The App-Store-safe v2 builds instead use GnuTLS on gpl-2 (its GMP/nettle deps are fine under GPLv2) and DROP TLS ENTIRELY on lgpl-2 (GMP/nettle are never LGPLv2.1 and no other backend is either). Windows uses SChannel and macOS/iOS use SecureTransport (OS-native) in every series. Mac Catalyst is the Apple exception: SecureTransport is unavailable on macabi, so Catalyst follows the Linux/Android ladder instead. All enable the `https`/`tls` protocols EXCEPT lgpl-2 on Linux, Android and Catalyst, which have no TLS. -[^d3d12]: Not built: FFmpeg's `d3d12va` needs `ID3D12VideoDecoder` from `d3d12video.h`, which the mingw-w64 cross-toolchain doesn't ship (it has `d3d12.h` only). Windows hw decode is covered by D3D11VA + DXVA2. -[^svtav1]: Needs 64-bit and a toolchain it cross-compiles under, so it is n/a on armhf, win-arm64, Mac Catalyst and mobile. AV1 encode is still available via libaom everywhere libaom itself is built — which excludes the lean ios-sim-arm64 slice. -[^webp]: Image-only codec; not built on mobile (its CMake build ships no pkg-config file). -[^fontconfig]: Off on Windows/Android/iOS (native DirectWrite/CoreText, or an explicit `fontfile=`); libass still renders via those providers. diff --git a/docs/matrix/ffmpeg-9-lgplv3.md b/docs/matrix/ffmpeg-9-lgplv3.md deleted file mode 100644 index 4d82361..0000000 --- a/docs/matrix/ffmpeg-9-lgplv3.md +++ /dev/null @@ -1,204 +0,0 @@ -# FFmpeg 9.0.2 · LGPLv3 — build coverage - -_Auto-generated by `scripts/gen-matrix.sh` from FFmpeg n9.0.2's `configure` and the build scripts — do not edit by hand. Back to the [matrix index](README.md)._ - -**✓** built · **n/a** not applicable on this platform · **—** FFmpeg supports it but we don't build it here (a choice — no license barrier) · **✗** can't be included in this cell: a GPL lib in an LGPL build, or a version3 lib (needs --enable-version3) in a v2 build — use the matching build instead - -_The **Version** column is the exact upstream ref this build pins for that library — read from the ledger (`deps.json`), resolved for this FFmpeg major (an `overrides.` hold wins over the default). It is the ref the build actually consumes — `clone_dep` checks it out for git-sourced deps, and `dep_version` substitutes it into the download URL for tarball-sourced ones — so it is what actually compiles. Blank = an FFmpeg-internal or OS-native feature with no pinned dependency, or a row not built in this cell. A dep held back only for this line shows its held ref here and so differs from the sibling major's file; if a dep ever needed a different version per platform, the version would move into the per-platform cells instead._ - -_Always-on built-in decoders (H.264/H.265/VP8/VP9 decode, AAC, PCM, …) are compiled into every build and not listed. The iOS-simulator slice is lean — a library present on the iOS device slice but dropped there shows n/a._ - -_This is the **LGPLv3** cell — one of four ({gplv3, gplv2, lgplv3, lgplv2}); the siblings are linked from the [matrix index](README.md). Cells differ in x264/x265 (gpl) vs kvazaar (lgpl) — except the lean `ios-sim-arm64` slice, which carries none of the three — and in the Apache-2.0 dependencies. **v3** adds Vulkan on every RID that has it (all but `ios-sim-arm64`: the lean slice drops libplacebo, so it has no SPIR-V compiler and would register no Vulkan filters), and adds OpenSSL on the platforms that need a bundled TLS backend (Linux, Android, Mac Catalyst); **v2** uses GnuTLS (gpl) or NO TLS (lgpl) on those same platforms and drops Vulkan everywhere. Windows (SChannel) and macOS/iOS (SecureTransport) have TLS in all four cells. Dropping Vulkan sends Whisper to the CPU only where the Vulkan backend was in use: Apple targets use Metal in every cell, and `linux-armhf` is CPU in every cell. The per-RID columns below are authoritative; this paragraph is the summary. Every cell ships DYNAMIC libraries — iOS as a dynamic-framework `.xcframework`._ - - -### Video codecs -_6 of 23 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| dav1d — AV1 decode | 1.5.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Kvazaar — HEVC encoder | v2.3.2 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libaom — AV1 enc/dec | v3.15.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libvpx — VP8/VP9 | v1.17.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| OpenH264 — H.264 encode | v2.6.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SVT-AV1 — AV1 encode[^svtav1] | v4.2.0 | ✓ | ✓ | n/a | ✓ | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| davs2 — AVS2 decode (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| LCEVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libtheora — Theora | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenAPV — APV codec | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenHarmony HW codec | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| rav1e — AV1 encoder (Rust) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| uavs3d — AVS3 decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| vvenc — H.266/VVC encoder | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| x264 — H.264 encode (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| x265 — H.265 encode (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| xavs — AVS1 encode (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| xavs2 — AVS2 encode (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| XEVD baseline — EVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVD — MPEG-5 EVC decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVE baseline — EVC encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| XEVE — MPEG-5 EVC encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Xvid — MPEG-4 ASP (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | - -### Audio codecs -_9 of 21 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| libgsm — GSM | 1.0.24 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libmp3lame — MP3 encode | 4.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libopus — Opus | v1.6.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libvorbis — Vorbis | v1.3.7 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| OpenCORE — AMR-NB en/decode | 0.1.6 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| OpenCORE — AMR-WB decode | 0.1.6 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SoX resampler | 0.1.3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Speex — speech | Speex-1.2.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| VisualOn — AMR-WB encode | 0.1.3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| bs2b — stereo→binaural | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Codec2 — low-bitrate speech | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Flite — speech synthesis | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Game Music Emu | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| iLBC — speech | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LC3 — Bluetooth audio | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libmodplug — tracker music | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libmysofa — SOFA HRTF | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libopenmpt — tracker music | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Rubber Band — time-stretch/pitch (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| Shine — fixed-point MP3 | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| TwoLAME — MP2 encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Images / subtitles / text -_8 of 15 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| fontconfig — font-by-name[^fontconfig] | 2.18.3 | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| FreeType — drawtext | VER-2-14-3 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libass — SSA/ASS subtitles | 0.17.5 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libfribidi — bidi text (drawtext) | v1.0.17 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libharfbuzz — text shaping | 14.5.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libjxl — JPEG XL | v0.12.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libwebp — WebP[^webp] | v1.6.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| OpenJPEG — JPEG 2000 | v2.5.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| ARIB caption decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Cairo — vector rendering | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libqrencode — QR encode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| librsvg — SVG rasterize | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libzvbi — teletext/VBI | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| SVT JPEG-XS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Tesseract — OCR | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Processing -_5 of 17 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| Chromaprint — audio fingerprint | v1.6.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| libplacebo — GPU processing | v7.360.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | n/a | ✓ | ✓ | -| libvmaf — VMAF quality metric | v3.2.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Little CMS — color management | lcms2.19.1 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| zimg — scaling/colorspace | release-3.0.6 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| frei0r — effect plugins (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| LADSPA — audio plugins | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LibTorch — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| LV2 — audio plugins | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenColorIO | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenCV — CV filters | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenVINO — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Snappy — HAP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| TensorFlow — DNN backend | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| VapourSynth — frameserver | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| vid.stab — stabilization (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| ZeroMQ — zmq/azmq filters | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Speech-to-text -_1 of 2 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| whisper.cpp — af_whisper ASR | v1.9.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| PocketSphinx — speech recognition | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Networking / streaming / TLS -_6 of 14 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| mbedTLS — SRT/librist transport crypto (not FFmpeg's own TLS backend) | v3.6.7 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| OpenSSL — TLS/https[^tls] | openssl-3.5.7 | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | — | ✓ | ✓ | — | — | ✓ | ✓ | -| RIST — reliable stream | v0.2.20 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SChannel — TLS/https (OS-native)[^tls] | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| SecureTransport — TLS/https (OS-native)[^tls] | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | ✓ | ✓ | n/a | n/a | -| SRT — secure transport | v1.5.7 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| GMP — bignum (GnuTLS dep; not enabled as an FFmpeg lib) | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| GnuTLS — TLS/https[^tls] | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libgcrypt — crypto | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| librtmp — RTMP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libssh — SFTP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libtls (LibreSSL) — TLS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| RabbitMQ — AMQP | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| SMB/CIFS | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -### Hardware acceleration -_16 of 22 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| AMF (AMD) | v1.5.3 | n/a | n/a | n/a | n/a | n/a | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| AudioToolbox | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | -| CUDA | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| CUVID (NVIDIA decode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| D3D11VA | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| DXVA2 | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| ffnvcodec headers | n13.1.15.0 | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| libdrm | libdrm-2.4.134 | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| MediaFoundation | | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| NVDEC (NVIDIA decode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| NVENC (NVIDIA encode) | | ✓ | ✓ | — | ✓ | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| QSV (oneVPL) | v2.17.0 | ✓ | — | — | ✓ | — | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| V4L2-M2M | | ✓ | ✓ | ✓ | — | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VAAPI | 2.24.1 | ✓ | ✓ | — | ✓ | ✓ | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VideoToolbox | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | ✓ | ✓ | ✓ | ✓ | -| Vulkan (FFmpeg filters; whisper GPU only where the backend is Vulkan) | vulkan-sdk-1.4.363.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | ✓ | ✓ | -| CUDA (LLVM/NVVM) | | — | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| D3D12VA[^d3d12] | | n/a | n/a | n/a | n/a | n/a | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| MMAL (Raspberry Pi) | | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| OpenCL | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| QSV (MediaSDK, legacy) | | — | — | — | — | — | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | -| VDPAU | | — | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | - -### Other / miscellaneous -_5 of 24 built._ - -| Feature | Version | lin-x64 | lin-a64 | lin-hf | musl | musl-a64 | win | win-a64 | osx-x64 | osx-a64 | android | android-x64 | ios | ios-sim | mcat-a64 | mcat-x64 | -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| JNI (Android bridge) | | — | — | — | — | — | — | — | — | — | ✓ | ✓ | — | — | — | — | -| libxml2 — DASH/IMF parse | v2.15.4 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| MediaCodec (Android) | | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | ✓ | n/a | n/a | n/a | n/a | -| Vulkan (static ICD) | v1.4.2 | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✓ | n/a | ✓ | ✓ | -| zlib — deflate (matroska, png, http) | v1.3.2 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| AviSynth — frameserver (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| FireWire capture | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| JACK — audio I/O | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| KLV/VANC | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libaribb24 | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libbluray — Blu-ray input | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libcaca — ASCII-art output | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libcdio — CD input (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| libdc1394 — IIDC cameras | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libdvdnav — DVD nav (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| libdvdread — DVD read (GPL) | | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | -| liblensfun | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| libonnxruntime | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenAL — audio capture | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| OpenGL — output | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| PulseAudio — audio I/O | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| quirc — QR decode | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| rkmpp | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | -| Video4Linux2 | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | - -[^tls]: TLS/https backend — depends on the license SERIES. v3 builds link OpenSSL 3.x (Apache-2.0, requires --enable-version3) on Linux/Android. The App-Store-safe v2 builds instead use GnuTLS on gpl-2 (its GMP/nettle deps are fine under GPLv2) and DROP TLS ENTIRELY on lgpl-2 (GMP/nettle are never LGPLv2.1 and no other backend is either). Windows uses SChannel and macOS/iOS use SecureTransport (OS-native) in every series. Mac Catalyst is the Apple exception: SecureTransport is unavailable on macabi, so Catalyst follows the Linux/Android ladder instead. All enable the `https`/`tls` protocols EXCEPT lgpl-2 on Linux, Android and Catalyst, which have no TLS. -[^d3d12]: Not built: FFmpeg's `d3d12va` needs `ID3D12VideoDecoder` from `d3d12video.h`, which the mingw-w64 cross-toolchain doesn't ship (it has `d3d12.h` only). Windows hw decode is covered by D3D11VA + DXVA2. -[^svtav1]: Needs 64-bit and a toolchain it cross-compiles under, so it is n/a on armhf, win-arm64, Mac Catalyst and mobile. AV1 encode is still available via libaom everywhere libaom itself is built — which excludes the lean ios-sim-arm64 slice. -[^webp]: Image-only codec; not built on mobile (its CMake build ships no pkg-config file). -[^fontconfig]: Off on Windows/Android/iOS (native DirectWrite/CoreText, or an explicit `fontfile=`); libass still renders via those providers. diff --git a/ffmpeg-build.yml b/ffmpeg-build.yml new file mode 100644 index 0000000..9428d3c --- /dev/null +++ b/ffmpeg-build.yml @@ -0,0 +1,765 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/devenvy/ffmpeg-build/v0/schema/ffmpeg-build.schema.json +# ffmpeg-build.yml: made by `ffmpeg-build init` from the shipped devenvy targets. Each target is one build +# (one platform, one license, one FFmpeg series); bases hold what targets share. `ffmpeg-build show ` +# lists what a target gets and where each entry comes from. +# say when an FFmpeg major newer than every target's series is out (update-lock's PR and run summary) +notify: { new-ffmpeg: true } +# NVIDIA's encoder headers stay on SDK 13.0 (driver 570+): 13.1 needs driver 610+, which NVIDIA's 580 branch never +# reaches, and that branch is the last for Maxwell, Pascal and Volta (GTX 900/10-series). FFmpeg's NVENC refuses to open +# on an older driver. 13.0.x patch releases still arrive. Tracking issue: #54. +pin: + nvenc: '13.0' +bases: + common: + with: [openh264, dav1d, openjpeg, jxl, zimg, vmaf, lcms2, vorbis, mp3lame, speex, gsm, soxr, chromaprint, + xml2, zlib, srt, rist, whisper] + android: + with: [aom, vpx, opus, freetype, fribidi, harfbuzz, ass, jni, mediacodec] + ios: + with: [aom, vpx, opus, freetype, fribidi, harfbuzz, ass, securetransport, videotoolbox] + ios-sim: + with: [securetransport, videotoolbox] + linux: + with: [aom, vpx, opus, freetype, fribidi, harfbuzz, ass, fontconfig, v4l2-m2m, webp] + linux-musl: + with: [aom, vpx, opus, freetype, fribidi, harfbuzz, ass, drm, fontconfig, nvenc, svtav1, vaapi, webp] + maccatalyst: + with: [aom, vpx, opus, freetype, fribidi, harfbuzz, ass, videotoolbox] + osx: + with: [aom, vpx, opus, freetype, fribidi, harfbuzz, ass, audiotoolbox, fontconfig, securetransport, + svtav1, videotoolbox, webp] + win: + with: [aom, vpx, opus, freetype, fribidi, harfbuzz, ass, d3d11va, dxva2, mediafoundation, schannel, webp] + gplv3: + with: [opencore-amrnb, opencore-amrwb, vo-amrwbenc] + lgplv3: + with: [opencore-amrnb, opencore-amrwb, vo-amrwbenc] +targets: + android-arm64-gplv2: + platform: android-arm64 + license: gplv2 + ffmpeg: "9" + base: [common, android] + with: [gnutls, x264, x265] + android-arm64-gplv2-ffmpeg8: + platform: android-arm64 + license: gplv2 + ffmpeg: "8" + base: [common, android] + with: [gnutls, x264, x265] + android-arm64-gplv3: + platform: android-arm64 + license: gplv3 + ffmpeg: "9" + base: [common, android, gplv3] + with: [openssl, vulkan, placebo, x264, x265] + android-arm64-gplv3-ffmpeg8: + platform: android-arm64 + license: gplv3 + ffmpeg: "8" + base: [common, android, gplv3] + with: [openssl, vulkan, placebo, shaderc, x264, x265] + android-arm64-lgplv2: + platform: android-arm64 + license: lgplv2 + ffmpeg: "9" + base: [common, android] + with: [kvazaar] + android-arm64-lgplv2-ffmpeg8: + platform: android-arm64 + license: lgplv2 + ffmpeg: "8" + base: [common, android] + with: [kvazaar] + android-arm64-lgplv3: + platform: android-arm64 + license: lgplv3 + ffmpeg: "9" + base: [common, android, lgplv3] + with: [openssl, vulkan, placebo, kvazaar] + android-arm64-lgplv3-ffmpeg8: + platform: android-arm64 + license: lgplv3 + ffmpeg: "8" + base: [common, android, lgplv3] + with: [openssl, vulkan, placebo, shaderc, kvazaar] + android-x64-gplv2: + platform: android-x64 + license: gplv2 + ffmpeg: "9" + base: [common, android] + with: [gnutls, x264, x265] + android-x64-gplv2-ffmpeg8: + platform: android-x64 + license: gplv2 + ffmpeg: "8" + base: [common, android] + with: [gnutls, x264, x265] + android-x64-gplv3: + platform: android-x64 + license: gplv3 + ffmpeg: "9" + base: [common, android, gplv3] + with: [openssl, vulkan, placebo, x264, x265] + android-x64-gplv3-ffmpeg8: + platform: android-x64 + license: gplv3 + ffmpeg: "8" + base: [common, android, gplv3] + with: [openssl, vulkan, placebo, shaderc, x264, x265] + android-x64-lgplv2: + platform: android-x64 + license: lgplv2 + ffmpeg: "9" + base: [common, android] + with: [kvazaar] + android-x64-lgplv2-ffmpeg8: + platform: android-x64 + license: lgplv2 + ffmpeg: "8" + base: [common, android] + with: [kvazaar] + android-x64-lgplv3: + platform: android-x64 + license: lgplv3 + ffmpeg: "9" + base: [common, android, lgplv3] + with: [openssl, vulkan, placebo, kvazaar] + android-x64-lgplv3-ffmpeg8: + platform: android-x64 + license: lgplv3 + ffmpeg: "8" + base: [common, android, lgplv3] + with: [openssl, vulkan, placebo, shaderc, kvazaar] + ios-arm64-gplv2: + platform: ios-arm64 + license: gplv2 + ffmpeg: "9" + base: [common, ios] + with: [x264, x265] + ios-arm64-gplv2-ffmpeg8: + platform: ios-arm64 + license: gplv2 + ffmpeg: "8" + base: [common, ios] + with: [x264, x265] + ios-arm64-gplv3: + platform: ios-arm64 + license: gplv3 + ffmpeg: "9" + base: [common, ios, gplv3] + with: [vulkan, placebo, x264, x265] + ios-arm64-gplv3-ffmpeg8: + platform: ios-arm64 + license: gplv3 + ffmpeg: "8" + base: [common, ios, gplv3] + with: [vulkan, placebo, shaderc, x264, x265] + ios-arm64-lgplv2: + platform: ios-arm64 + license: lgplv2 + ffmpeg: "9" + base: [common, ios] + with: [kvazaar] + ios-arm64-lgplv2-ffmpeg8: + platform: ios-arm64 + license: lgplv2 + ffmpeg: "8" + base: [common, ios] + with: [kvazaar] + ios-arm64-lgplv3: + platform: ios-arm64 + license: lgplv3 + ffmpeg: "9" + base: [common, ios, lgplv3] + with: [vulkan, placebo, kvazaar] + ios-arm64-lgplv3-ffmpeg8: + platform: ios-arm64 + license: lgplv3 + ffmpeg: "8" + base: [common, ios, lgplv3] + with: [vulkan, placebo, shaderc, kvazaar] + ios-sim-arm64-gplv2: + platform: ios-sim-arm64 + license: gplv2 + ffmpeg: "9" + base: [common, ios-sim] + without: [x264, x265, aom, vpx, opus, freetype, fribidi, harfbuzz, ass] + ios-sim-arm64-gplv2-ffmpeg8: + platform: ios-sim-arm64 + license: gplv2 + ffmpeg: "8" + base: [common, ios-sim] + without: [x264, x265, aom, vpx, opus, freetype, fribidi, harfbuzz, ass] + ios-sim-arm64-gplv3: + platform: ios-sim-arm64 + license: gplv3 + ffmpeg: "9" + base: [common, ios-sim, gplv3] + without: [x264, x265, aom, vpx, opus, freetype, fribidi, harfbuzz, ass] + ios-sim-arm64-gplv3-ffmpeg8: + platform: ios-sim-arm64 + license: gplv3 + ffmpeg: "8" + base: [common, ios-sim, gplv3] + without: [x264, x265, aom, vpx, opus, freetype, fribidi, harfbuzz, ass] + ios-sim-arm64-lgplv2: + platform: ios-sim-arm64 + license: lgplv2 + ffmpeg: "9" + base: [common, ios-sim] + without: [kvazaar, aom, vpx, opus, freetype, fribidi, harfbuzz, ass] + ios-sim-arm64-lgplv2-ffmpeg8: + platform: ios-sim-arm64 + license: lgplv2 + ffmpeg: "8" + base: [common, ios-sim] + without: [kvazaar, aom, vpx, opus, freetype, fribidi, harfbuzz, ass] + ios-sim-arm64-lgplv3: + platform: ios-sim-arm64 + license: lgplv3 + ffmpeg: "9" + base: [common, ios-sim, lgplv3] + without: [kvazaar, aom, vpx, opus, freetype, fribidi, harfbuzz, ass] + ios-sim-arm64-lgplv3-ffmpeg8: + platform: ios-sim-arm64 + license: lgplv3 + ffmpeg: "8" + base: [common, ios-sim, lgplv3] + without: [kvazaar, aom, vpx, opus, freetype, fribidi, harfbuzz, ass] + linux-arm64-gplv2: + platform: linux-arm64 + license: gplv2 + ffmpeg: "9" + base: [common, linux] + with: [gnutls, nvenc, vaapi, drm, x264, x265, svtav1] + linux-arm64-gplv2-ffmpeg8: + platform: linux-arm64 + license: gplv2 + ffmpeg: "8" + base: [common, linux] + with: [gnutls, nvenc, vaapi, drm, x264, x265, svtav1] + linux-arm64-gplv3: + platform: linux-arm64 + license: gplv3 + ffmpeg: "9" + base: [common, linux, gplv3] + with: [openssl, nvenc, vaapi, drm, vulkan, placebo, x264, x265, svtav1] + linux-arm64-gplv3-ffmpeg8: + platform: linux-arm64 + license: gplv3 + ffmpeg: "8" + base: [common, linux, gplv3] + with: [openssl, nvenc, vaapi, drm, vulkan, placebo, shaderc, x264, x265, svtav1] + linux-arm64-lgplv2: + platform: linux-arm64 + license: lgplv2 + ffmpeg: "9" + base: [common, linux] + with: [nvenc, vaapi, drm, kvazaar, svtav1] + linux-arm64-lgplv2-ffmpeg8: + platform: linux-arm64 + license: lgplv2 + ffmpeg: "8" + base: [common, linux] + with: [nvenc, vaapi, drm, kvazaar, svtav1] + linux-arm64-lgplv3: + platform: linux-arm64 + license: lgplv3 + ffmpeg: "9" + base: [common, linux, lgplv3] + with: [openssl, nvenc, vaapi, drm, vulkan, placebo, kvazaar, svtav1] + linux-arm64-lgplv3-ffmpeg8: + platform: linux-arm64 + license: lgplv3 + ffmpeg: "8" + base: [common, linux, lgplv3] + with: [openssl, nvenc, vaapi, drm, vulkan, placebo, shaderc, kvazaar, svtav1] + linux-armhf-gplv2: + platform: linux-armhf + license: gplv2 + ffmpeg: "9" + base: [common, linux] + with: [gnutls, x264, x265] + without: [vaapi, drm] + linux-armhf-gplv2-ffmpeg8: + platform: linux-armhf + license: gplv2 + ffmpeg: "8" + base: [common, linux] + with: [gnutls, x264, x265] + without: [vaapi, drm] + linux-armhf-gplv3: + platform: linux-armhf + license: gplv3 + ffmpeg: "9" + base: [common, linux, gplv3] + with: [openssl, vulkan, placebo, x264, x265] + without: [vaapi, drm] + linux-armhf-gplv3-ffmpeg8: + platform: linux-armhf + license: gplv3 + ffmpeg: "8" + base: [common, linux, gplv3] + with: [openssl, vulkan, placebo, shaderc, x264, x265] + without: [vaapi, drm] + linux-armhf-lgplv2: + platform: linux-armhf + license: lgplv2 + ffmpeg: "9" + base: [common, linux] + with: [kvazaar] + without: [vaapi, drm] + linux-armhf-lgplv2-ffmpeg8: + platform: linux-armhf + license: lgplv2 + ffmpeg: "8" + base: [common, linux] + with: [kvazaar] + without: [vaapi, drm] + linux-armhf-lgplv3: + platform: linux-armhf + license: lgplv3 + ffmpeg: "9" + base: [common, linux, lgplv3] + with: [openssl, vulkan, placebo, kvazaar] + without: [vaapi, drm] + linux-armhf-lgplv3-ffmpeg8: + platform: linux-armhf + license: lgplv3 + ffmpeg: "8" + base: [common, linux, lgplv3] + with: [openssl, vulkan, placebo, shaderc, kvazaar] + without: [vaapi, drm] + linux-musl-arm64-gplv2: + platform: linux-musl-arm64 + license: gplv2 + ffmpeg: "9" + base: [common, linux-musl] + with: [gnutls, v4l2-m2m, x264, x265] + linux-musl-arm64-gplv2-ffmpeg8: + platform: linux-musl-arm64 + license: gplv2 + ffmpeg: "8" + base: [common, linux-musl] + with: [gnutls, v4l2-m2m, x264, x265] + linux-musl-arm64-gplv3: + platform: linux-musl-arm64 + license: gplv3 + ffmpeg: "9" + base: [common, linux-musl, gplv3] + with: [openssl, v4l2-m2m, vulkan, placebo, x264, x265] + linux-musl-arm64-gplv3-ffmpeg8: + platform: linux-musl-arm64 + license: gplv3 + ffmpeg: "8" + base: [common, linux-musl, gplv3] + with: [openssl, v4l2-m2m, vulkan, placebo, shaderc, x264, x265] + linux-musl-arm64-lgplv2: + platform: linux-musl-arm64 + license: lgplv2 + ffmpeg: "9" + base: [common, linux-musl] + with: [v4l2-m2m, kvazaar] + linux-musl-arm64-lgplv2-ffmpeg8: + platform: linux-musl-arm64 + license: lgplv2 + ffmpeg: "8" + base: [common, linux-musl] + with: [v4l2-m2m, kvazaar] + linux-musl-arm64-lgplv3: + platform: linux-musl-arm64 + license: lgplv3 + ffmpeg: "9" + base: [common, linux-musl, lgplv3] + with: [openssl, v4l2-m2m, vulkan, placebo, kvazaar] + linux-musl-arm64-lgplv3-ffmpeg8: + platform: linux-musl-arm64 + license: lgplv3 + ffmpeg: "8" + base: [common, linux-musl, lgplv3] + with: [openssl, v4l2-m2m, vulkan, placebo, shaderc, kvazaar] + linux-musl-x64-gplv2: + platform: linux-musl-x64 + license: gplv2 + ffmpeg: "9" + base: [common, linux-musl] + with: [gnutls, vpl, x264, x265] + linux-musl-x64-gplv2-ffmpeg8: + platform: linux-musl-x64 + license: gplv2 + ffmpeg: "8" + base: [common, linux-musl] + with: [gnutls, vpl, x264, x265] + linux-musl-x64-gplv3: + platform: linux-musl-x64 + license: gplv3 + ffmpeg: "9" + base: [common, linux-musl, gplv3] + with: [openssl, vpl, vulkan, placebo, x264, x265] + linux-musl-x64-gplv3-ffmpeg8: + platform: linux-musl-x64 + license: gplv3 + ffmpeg: "8" + base: [common, linux-musl, gplv3] + with: [openssl, vpl, vulkan, placebo, shaderc, x264, x265] + linux-musl-x64-lgplv2: + platform: linux-musl-x64 + license: lgplv2 + ffmpeg: "9" + base: [common, linux-musl] + with: [vpl, kvazaar] + linux-musl-x64-lgplv2-ffmpeg8: + platform: linux-musl-x64 + license: lgplv2 + ffmpeg: "8" + base: [common, linux-musl] + with: [vpl, kvazaar] + linux-musl-x64-lgplv3: + platform: linux-musl-x64 + license: lgplv3 + ffmpeg: "9" + base: [common, linux-musl, lgplv3] + with: [openssl, vpl, vulkan, placebo, kvazaar] + linux-musl-x64-lgplv3-ffmpeg8: + platform: linux-musl-x64 + license: lgplv3 + ffmpeg: "8" + base: [common, linux-musl, lgplv3] + with: [openssl, vpl, vulkan, placebo, shaderc, kvazaar] + linux-x64-gplv2: + platform: linux-x64 + license: gplv2 + ffmpeg: "9" + base: [common, linux] + with: [gnutls, nvenc, vaapi, drm, vpl, x264, x265, svtav1] + linux-x64-gplv2-ffmpeg8: + platform: linux-x64 + license: gplv2 + ffmpeg: "8" + base: [common, linux] + with: [gnutls, nvenc, vaapi, drm, vpl, x264, x265, svtav1] + linux-x64-gplv3: + platform: linux-x64 + license: gplv3 + ffmpeg: "9" + base: [common, linux, gplv3] + with: [openssl, nvenc, vaapi, drm, vpl, vulkan, placebo, x264, x265, svtav1] + linux-x64-gplv3-ffmpeg8: + platform: linux-x64 + license: gplv3 + ffmpeg: "8" + base: [common, linux, gplv3] + with: [openssl, nvenc, vaapi, drm, vpl, vulkan, placebo, shaderc, x264, x265, svtav1] + linux-x64-lgplv2: + platform: linux-x64 + license: lgplv2 + ffmpeg: "9" + base: [common, linux] + with: [nvenc, vaapi, drm, vpl, kvazaar, svtav1] + linux-x64-lgplv2-ffmpeg8: + platform: linux-x64 + license: lgplv2 + ffmpeg: "8" + base: [common, linux] + with: [nvenc, vaapi, drm, vpl, kvazaar, svtav1] + linux-x64-lgplv3: + platform: linux-x64 + license: lgplv3 + ffmpeg: "9" + base: [common, linux, lgplv3] + with: [openssl, nvenc, vaapi, drm, vpl, vulkan, placebo, kvazaar, svtav1] + linux-x64-lgplv3-ffmpeg8: + platform: linux-x64 + license: lgplv3 + ffmpeg: "8" + base: [common, linux, lgplv3] + with: [openssl, nvenc, vaapi, drm, vpl, vulkan, placebo, shaderc, kvazaar, svtav1] + maccatalyst-arm64-gplv2: + platform: maccatalyst-arm64 + license: gplv2 + ffmpeg: "9" + base: [common, maccatalyst] + with: [gnutls, x264, x265] + maccatalyst-arm64-gplv2-ffmpeg8: + platform: maccatalyst-arm64 + license: gplv2 + ffmpeg: "8" + base: [common, maccatalyst] + with: [gnutls, x264, x265] + maccatalyst-arm64-gplv3: + platform: maccatalyst-arm64 + license: gplv3 + ffmpeg: "9" + base: [common, maccatalyst, gplv3] + with: [openssl, vulkan, placebo, x264, x265] + maccatalyst-arm64-gplv3-ffmpeg8: + platform: maccatalyst-arm64 + license: gplv3 + ffmpeg: "8" + base: [common, maccatalyst, gplv3] + with: [openssl, vulkan, placebo, shaderc, x264, x265] + maccatalyst-arm64-lgplv2: + platform: maccatalyst-arm64 + license: lgplv2 + ffmpeg: "9" + base: [common, maccatalyst] + with: [kvazaar] + maccatalyst-arm64-lgplv2-ffmpeg8: + platform: maccatalyst-arm64 + license: lgplv2 + ffmpeg: "8" + base: [common, maccatalyst] + with: [kvazaar] + maccatalyst-arm64-lgplv3: + platform: maccatalyst-arm64 + license: lgplv3 + ffmpeg: "9" + base: [common, maccatalyst, lgplv3] + with: [openssl, vulkan, placebo, kvazaar] + maccatalyst-arm64-lgplv3-ffmpeg8: + platform: maccatalyst-arm64 + license: lgplv3 + ffmpeg: "8" + base: [common, maccatalyst, lgplv3] + with: [openssl, vulkan, placebo, shaderc, kvazaar] + maccatalyst-x64-gplv2: + platform: maccatalyst-x64 + license: gplv2 + ffmpeg: "9" + base: [common, maccatalyst] + with: [gnutls, x264, x265] + maccatalyst-x64-gplv2-ffmpeg8: + platform: maccatalyst-x64 + license: gplv2 + ffmpeg: "8" + base: [common, maccatalyst] + with: [gnutls, x264, x265] + maccatalyst-x64-gplv3: + platform: maccatalyst-x64 + license: gplv3 + ffmpeg: "9" + base: [common, maccatalyst, gplv3] + with: [openssl, vulkan, placebo, x264, x265] + maccatalyst-x64-gplv3-ffmpeg8: + platform: maccatalyst-x64 + license: gplv3 + ffmpeg: "8" + base: [common, maccatalyst, gplv3] + with: [openssl, vulkan, placebo, shaderc, x264, x265] + maccatalyst-x64-lgplv2: + platform: maccatalyst-x64 + license: lgplv2 + ffmpeg: "9" + base: [common, maccatalyst] + with: [kvazaar] + maccatalyst-x64-lgplv2-ffmpeg8: + platform: maccatalyst-x64 + license: lgplv2 + ffmpeg: "8" + base: [common, maccatalyst] + with: [kvazaar] + maccatalyst-x64-lgplv3: + platform: maccatalyst-x64 + license: lgplv3 + ffmpeg: "9" + base: [common, maccatalyst, lgplv3] + with: [openssl, vulkan, placebo, kvazaar] + maccatalyst-x64-lgplv3-ffmpeg8: + platform: maccatalyst-x64 + license: lgplv3 + ffmpeg: "8" + base: [common, maccatalyst, lgplv3] + with: [openssl, vulkan, placebo, shaderc, kvazaar] + osx-arm64-gplv2: + platform: osx-arm64 + license: gplv2 + ffmpeg: "9" + base: [common, osx] + with: [x264, x265] + osx-arm64-gplv2-ffmpeg8: + platform: osx-arm64 + license: gplv2 + ffmpeg: "8" + base: [common, osx] + with: [x264, x265] + osx-arm64-gplv3: + platform: osx-arm64 + license: gplv3 + ffmpeg: "9" + base: [common, osx, gplv3] + with: [vulkan, placebo, x264, x265] + osx-arm64-gplv3-ffmpeg8: + platform: osx-arm64 + license: gplv3 + ffmpeg: "8" + base: [common, osx, gplv3] + with: [vulkan, placebo, shaderc, x264, x265] + osx-arm64-lgplv2: + platform: osx-arm64 + license: lgplv2 + ffmpeg: "9" + base: [common, osx] + with: [kvazaar] + osx-arm64-lgplv2-ffmpeg8: + platform: osx-arm64 + license: lgplv2 + ffmpeg: "8" + base: [common, osx] + with: [kvazaar] + osx-arm64-lgplv3: + platform: osx-arm64 + license: lgplv3 + ffmpeg: "9" + base: [common, osx, lgplv3] + with: [vulkan, placebo, kvazaar] + osx-arm64-lgplv3-ffmpeg8: + platform: osx-arm64 + license: lgplv3 + ffmpeg: "8" + base: [common, osx, lgplv3] + with: [vulkan, placebo, shaderc, kvazaar] + osx-x64-gplv2: + platform: osx-x64 + license: gplv2 + ffmpeg: "9" + base: [common, osx] + with: [x264, x265] + osx-x64-gplv2-ffmpeg8: + platform: osx-x64 + license: gplv2 + ffmpeg: "8" + base: [common, osx] + with: [x264, x265] + osx-x64-gplv3: + platform: osx-x64 + license: gplv3 + ffmpeg: "9" + base: [common, osx, gplv3] + with: [vulkan, placebo, x264, x265] + osx-x64-gplv3-ffmpeg8: + platform: osx-x64 + license: gplv3 + ffmpeg: "8" + base: [common, osx, gplv3] + with: [vulkan, placebo, shaderc, x264, x265] + osx-x64-lgplv2: + platform: osx-x64 + license: lgplv2 + ffmpeg: "9" + base: [common, osx] + with: [kvazaar] + osx-x64-lgplv2-ffmpeg8: + platform: osx-x64 + license: lgplv2 + ffmpeg: "8" + base: [common, osx] + with: [kvazaar] + osx-x64-lgplv3: + platform: osx-x64 + license: lgplv3 + ffmpeg: "9" + base: [common, osx, lgplv3] + with: [vulkan, placebo, kvazaar] + osx-x64-lgplv3-ffmpeg8: + platform: osx-x64 + license: lgplv3 + ffmpeg: "8" + base: [common, osx, lgplv3] + with: [vulkan, placebo, shaderc, kvazaar] + win-arm64-gplv2: + platform: win-arm64 + license: gplv2 + ffmpeg: "9" + base: [common, win] + with: [x264, x265] + win-arm64-gplv2-ffmpeg8: + platform: win-arm64 + license: gplv2 + ffmpeg: "8" + base: [common, win] + with: [x264, x265] + win-arm64-gplv3: + platform: win-arm64 + license: gplv3 + ffmpeg: "9" + base: [common, win, gplv3] + with: [vulkan, placebo, x264, x265] + win-arm64-gplv3-ffmpeg8: + platform: win-arm64 + license: gplv3 + ffmpeg: "8" + base: [common, win, gplv3] + with: [vulkan, placebo, shaderc, x264, x265] + win-arm64-lgplv2: + platform: win-arm64 + license: lgplv2 + ffmpeg: "9" + base: [common, win] + with: [kvazaar] + win-arm64-lgplv2-ffmpeg8: + platform: win-arm64 + license: lgplv2 + ffmpeg: "8" + base: [common, win] + with: [kvazaar] + win-arm64-lgplv3: + platform: win-arm64 + license: lgplv3 + ffmpeg: "9" + base: [common, win, lgplv3] + with: [vulkan, placebo, kvazaar] + win-arm64-lgplv3-ffmpeg8: + platform: win-arm64 + license: lgplv3 + ffmpeg: "8" + base: [common, win, lgplv3] + with: [vulkan, placebo, shaderc, kvazaar] + win-x64-gplv2: + platform: win-x64 + license: gplv2 + ffmpeg: "9" + base: [common, win] + with: [nvenc, vpl, amf, x264, x265, svtav1] + win-x64-gplv2-ffmpeg8: + platform: win-x64 + license: gplv2 + ffmpeg: "8" + base: [common, win] + with: [nvenc, vpl, amf, x264, x265, svtav1] + win-x64-gplv3: + platform: win-x64 + license: gplv3 + ffmpeg: "9" + base: [common, win, gplv3] + with: [nvenc, vpl, amf, vulkan, placebo, x264, x265, svtav1] + win-x64-gplv3-ffmpeg8: + platform: win-x64 + license: gplv3 + ffmpeg: "8" + base: [common, win, gplv3] + with: [nvenc, vpl, amf, vulkan, placebo, shaderc, x264, x265, svtav1] + win-x64-lgplv2: + platform: win-x64 + license: lgplv2 + ffmpeg: "9" + base: [common, win] + with: [nvenc, vpl, amf, kvazaar, svtav1] + win-x64-lgplv2-ffmpeg8: + platform: win-x64 + license: lgplv2 + ffmpeg: "8" + base: [common, win] + with: [nvenc, vpl, amf, kvazaar, svtav1] + win-x64-lgplv3: + platform: win-x64 + license: lgplv3 + ffmpeg: "9" + base: [common, win, lgplv3] + with: [nvenc, vpl, amf, vulkan, placebo, kvazaar, svtav1] + win-x64-lgplv3-ffmpeg8: + platform: win-x64 + license: lgplv3 + ffmpeg: "8" + base: [common, win, lgplv3] + with: [nvenc, vpl, amf, vulkan, placebo, shaderc, kvazaar, svtav1] diff --git a/ffmpeg.lock b/ffmpeg.lock new file mode 100644 index 0000000..bc47f47 --- /dev/null +++ b/ffmpeg.lock @@ -0,0 +1,63 @@ +# ffmpeg.lock - written only by `ffmpeg-build update` / `ffmpeg-build lock`. Do not edit. +engine: 0.0.3 +ffmpeg: + "8": { version: 8.1.3, sha256: 7138d28c96d9d3e3af4ee3d8cad72741f8ffb40da90c1112235dea3ecd3178a3 } + "9": { version: 9.0.2, sha256: 8c3850283eb25fa026482078a04051e0be17347b09ef81a0849bec15a96e002e } +libraries: + amf: { version: 1.5.3, commit: 8c648005e07d4309033282bfd9947df2c7e76104 } + aom: { version: 3.15.2, commit: af3dc9aadc793c1b00edc003e3fc19a44fdeb574 } + brotli: { version: 1.2.0, commit: 028fb5a23661f123017c060daa546b55cf4bde29 } + chromaprint: { version: 1.6.1, commit: aed8eba2202dd9d7b3b0a56c77904cc805490d72 } + dav1d: { version: 1.5.4, commit: 54706fc6bc0cdecab7e9593974a4039cc038fca7 } + fontconfig: { version: 2.18.3, commit: 0f236723a3c26bd9745e32ba2b3ee21e5f809295 } + freetype: { version: 2.15.0, commit: 37515cf56ba3349656049edbed89ffc6f6466f2d } + fribidi: { version: 1.0.17, commit: b93119f5fdc7ea47672cc304c1455ffa6dfe7536 } + gmp: { version: 6.3.0, sha256: a3c2b80201b89e68616f4ad30bc66aee4927c3ce50e33929ca819d5c43538898 } + gnutls: { version: 3.8.13, sha256: ffed8ec1bf09c2426d4f14aae377de4753b53e537d685e604e99a8b16ca9c97e } + harfbuzz: { version: 14.6.0, commit: c7a7457b7385f33178e8cf87615ca077a810bbe7 } + highway: { version: 1.4.0, commit: 2607d3b5b0113992fe84d3848859eae13b3b52c1 } + kissfft: { version: 131.2.0, commit: 7bce4153c6bc8aba2db0e889e576f9d00505cbe1 } + kvazaar: { version: 2.3.2, commit: 6040962bed5cc68c5ad01234c38c08b8b2822068 } + lcms2: { version: 2.19.1, commit: 21c582a594fe5279f90c0b93437c398f93bf62b0 } + libass: { version: 0.17.5, commit: 4a05d8127f525943ebf45fdc6497c9e665947f0d } + libdrm: { version: 2.4.134, commit: e984d448b8b17aab853369e6c203e53719f46de1 } + libexpat: { version: 2.9.0, commit: a76b1174c1ea52abb639a4c69d52b630a8a106a2 } + libgsm: { version: 1.0.24, sha256: a3c40c6471928383f4abfcb2e8f24012a1f562be2f17b8d672145d5986681a92 } + libjxl: { version: 0.12.0, commit: a7a9c787341cf703dede03c2009fa460cae5e5df } + libmp3lame: { version: 4.0, sha256: 3df5124d5ad3a98312ffd7ba6a9b36230e4f8a3e66d3ce0f425e336c32d216eb } + libogg: { version: 1.3.6, commit: be05b13e98b048f0b5a0f5fa8ce514d56db5f822 } + libplacebo: { version: 7.360.1, commit: cee9b076f2c63104ccfd497fa79c39a867293ec4 } + libpng: { version: 1.6.59, commit: cd952f49f95bb27154ae77dbb103032d95f6e580 } + librist: { version: 0.2.20, commit: 4f45ef8f78983892d52ccd52d9f675435b23738f } + libtasn1: { version: 4.21.0, sha256: 1d8a444a223cc5464240777346e125de51d8e6abf0b8bac742ac84609167dc87 } + libva: { version: 2.24.1, commit: 710eb465c6277ee2cac3e6948767b01eebe7e77a } + libvmaf: { version: 3.2.1, commit: f85a853692a8c730d0270cd733c8bb30b5b93b7c } + libvorbis: { version: 1.3.7, commit: 0657aee69dec8508a0011f47f3b69d7538e9d262 } + libvpl: { version: 2.17.0, commit: d77f9195cf495b937631607333288fd917ae8939 } + libvpx: { version: 1.17.0, commit: 6df3ec34557879fff673706f4a1d9fbd0f3a6f0e } + libwebp: { version: 1.6.0, commit: 4fa21912338357f89e4fd51cf2368325b59e9bd9 } + libxml2: { version: 2.15.4, commit: 96498992efa48d52b0e8b83058bd88dbdaf153c1 } + mbedtls: { version: 3.6.7, sha256: a7e8bcbec0e6f761b4af24f25677626b35f762f68eef79c08677a363212d11f6 } + moltenvk: { version: 1.4.2, commit: db66022459ffb663aa2b50f6b018bc2e124f5edf } + nettle: { version: 4.0, sha256: 3addbc00da01846b232fb3bc453538ea5468da43033f21bb345cb1e9073f5094 } + nv-codec: { version: 13.0.19.1, commit: 88fee5c37318c991a8762d423530f91681e32e3a } + opencore-amr: { version: 0.1.6, sha256: 483eb4061088e2b34b358e47540b5d495a96cd468e361050fae615b1809dc4a1 } + openh264: { version: 2.6.0, commit: 652bdb7719f30b52b08e506645a7322ff1b2cc6f } + openjpeg: { version: 2.5.4, commit: 6c4a29b00211eb0430fa0e5e890f1ce5c80f409f } + openssl: { version: 3.5.9, commit: 45e844fa2a14ec92d146bd8f5778ac130b6625fb } + opus: { version: 1.6.1, commit: 22244de5a79bd1d6d623c32e72bf1954b56235be } + shaderc: { version: 2026.4, commit: b64fd42c4a2a9d501c47aca5d3571f7673a5e9cc } + soxr: { version: 0.1.3, commit: 945b592b70470e29f917f4de89b4281fbbd540c0 } + speex: { version: 1.2.1, commit: 5dceaaf3e23ee7fd17c80cb5f02a838fd6c18e01 } + spirv-headers: { version: 1.4.363.0, commit: 496543121ce6419f23d6fa5d7194ba66c36212d2 } + srt: { version: 1.5.7, commit: 899348d8318eb9a3c5a5b6ec43c4a1114288773a } + svtav1: { version: 4.2.0, commit: 9292ec8e32bce26f781f277ec8739b53426c4300 } + vo-amrwbenc: { version: 0.1.3, sha256: 5652b391e0f0e296417b841b02987d3fd33e6c0af342c69542cbb016a71d9d4e } + vulkan-headers: { version: 1.4.363.0, commit: 6802bb4733b63ed5efd3adb308a6c885ef180ea1 } + vulkan-loader: { version: 1.4.363.0, commit: fa218055ff4948b159f31d43f800c808a13d51df } + vulkan-shim: 65b3936528cd92eb4ea3de485d03f858a3850484 + whisper.cpp: { version: 1.9.5, commit: d1be6fde11ac6e0407606b4e42fe72d34add8037 } + x264: b35605ace3ddf7c1a5d67a2eb553f034aef41d55 + x265: { version: 4.3, commit: e9b88125dc21393b3fd8d68e98083bdfb89778a8 } + zimg: { version: 3.0.6, commit: f819b14e8f39d1282400b0d9543e8ef73c1b2bbd } + zlib: { version: 1.3.2, commit: da607da739fa6047df13e66a2af6b8bec7c2a498 } diff --git a/renovate.json b/renovate.json deleted file mode 100644 index d28e004..0000000 --- a/renovate.json +++ /dev/null @@ -1,192 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:recommended" - ], - "enabledManagers": [ - "custom.jsonata", - "custom.regex" - ], - "gitAuthor": "ryan-morris ", - "dependencyDashboard": false, - "labels": [ - "dependencies" - ], - "customManagers": [ - { - "customType": "jsonata", - "fileFormat": "json", - "description": "Tag-pinned deps in the DEFAULTS block of the ledger (deps.json). JSONata reads the parsed document, so the ledger's key order and any extra fields (reason, registryUrl, ...) no longer matter -- the regex managers this replaced required origin/tag/datasource to be contiguous and in order, and a harmless reorder silently dropped a dep from tracking. Only .defaults is queried; .overrides (per-version / per-platform holds) is never touched. A dep is tracked iff it has a `tag` AND a `datasource` key: the datasource VALUE is informational (all git hosts are queried uniformly through git-tags against the clone URL, which is also what the packageRules below match on), its PRESENCE is the opt-in. Commit pins and tarball deps are handled by the two managers below, so every ledger dep is tracked by exactly one manager -- asserted by scripts/ci/renovate-coverage-test.sh.", - "managerFilePatterns": [ - "/^deps\\.json$/" - ], - "matchStrings": [ - "$each(defaults, function($v, $k) { $v.tag and $v.datasource ? { \"depName\": $k, \"packageName\": $v.origin, \"currentValue\": $v.tag } })" - ], - "datasourceTemplate": "git-tags" - }, - { - "customType": "jsonata", - "fileFormat": "json", - "description": "Deps pinned to a reviewed commit rather than a tag (x264 publishes no release tags; the Vulkan shim has no releases). Tracked as git-refs digests against the branch the pin actually follows: the key is digestBranch, NOT branch, because the ledger treats tag/branch/commit as mutually exclusive ref types (scripts/deps/lib.sh picks the first one present), so a second ref key would fail ledger-validate and could change which ref gets built.", - "managerFilePatterns": [ - "/^deps\\.json$/" - ], - "matchStrings": [ - "$each(defaults, function($v, $k) { $v.commit and $v.digestBranch ? { \"depName\": $k, \"packageName\": $v.origin, \"currentDigest\": $v.commit, \"currentValue\": $v.digestBranch } })" - ], - "datasourceTemplate": "git-refs" - }, - { - "customType": "jsonata", - "fileFormat": "json", - "description": "Deps that ship as a plain tarball with no git remote (GNU FTP, SourceForge, quut.com): versions come from the upstream release listing via the html custom datasource, selected by a `releasesUrl` key. The extractVersion is anchored to each project's OWN artifact name -- an html listing exposes every link on the page, so a shape-only pattern would accept an unrelated project's archive on a shared listing (SourceForge hosts opencore-amr and vo-amrwbenc under one project). The per-dep patterns live in the $lookup table here; a tarball dep missing from it yields no extractVersion, which renovate-coverage-test.sh fails on rather than letting Renovate treat every link as a version. Numeric-dot only: 'loose' records a trailing suffix as suffix rather than prerelease, so a future 3.102beta would otherwise rank as stable. [.] rather than \\. in the patterns because JSONata string literals reject that escape.", - "managerFilePatterns": [ - "/^deps\\.json$/" - ], - "matchStrings": [ - "$each(defaults, function($v, $k) { $v.releasesUrl ? { \"depName\": $k, \"currentValue\": $v.tag, \"registryUrl\": $v.releasesUrl, \"extractVersion\": $lookup({ \"gmp\": \"gmp-(?[0-9]+(?:[.][0-9]+)*)[.]tar[.](?:gz|xz|bz2)(?:/|$)\", \"libgsm\": \"gsm-(?[0-9]+(?:[.][0-9]+)*)[.]tar[.](?:gz|xz|bz2)(?:/|$)\", \"opencore-amr\": \"opencore-amr-(?[0-9]+(?:[.][0-9]+)*)[.]tar[.](?:gz|xz|bz2)(?:/|$)\", \"vo-amrwbenc\": \"vo-amrwbenc-(?[0-9]+(?:[.][0-9]+)*)[.]tar[.](?:gz|xz|bz2)(?:/|$)\", \"libmp3lame\": \"/files/lame/(?[0-9]+(?:[.][0-9]+)*)/\" }, $k) } })" - ], - "datasourceTemplate": "custom.tarball-listing", - "versioningTemplate": "loose" - }, - { - "customType": "jsonata", - "fileFormat": "json", - "description": "FFmpeg point releases: one entry per maintained major line in the .ffmpeg array of deps.json (e.g. 8.1.2). FFmpeg's upstream tags are n, stripped via extractVersion. The per-major packageRules below keep each line inside its own major.", - "managerFilePatterns": [ - "/^deps\\.json$/" - ], - "matchStrings": [ - "$map(ffmpeg, function($v) { { \"currentValue\": $v } })" - ], - "depNameTemplate": "FFmpeg", - "packageNameTemplate": "https://github.com/FFmpeg/FFmpeg.git", - "datasourceTemplate": "git-tags", - "extractVersionTemplate": "^n(?.+)$" - }, - { - "customType": "regex", - "description": "Pinning the ACTION (renovatebot/github-action) does not pin Renovate itself: the action's default renovate-version pulls a moving major tag, so the tool that maintains every other pin was itself unpinned and untracked. renovate.yml pins a full version and this manager keeps it updated from the published container tags.", - "managerFilePatterns": [ - "/^\\.github/workflows/renovate\\.yml$/" - ], - "matchStrings": [ - "renovate-version:\\s*'?(?[0-9]+\\.[0-9]+\\.[0-9]+)'?" - ], - "datasourceTemplate": "docker", - "depNameTemplate": "renovate/renovate", - "versioningTemplate": "semver" - }, - { - "customType": "regex", - "description": "Build/test container images (issue #26). The musl, glibc and armhf builds run inside these images, so the image IS the toolchain: a floating alpine:latest or untagged manylinux ref changed GCC/musl/glibc between runs with no diff on our side. Every ref in build.yml/test.yml is pinned tag@sha256 and tracked here; scripts/ci/image-pins-test.sh asserts none is left unpinned or unmatched. Tag and digest are captured separately so Renovate can bump either -- bookworm only ever moves its digest.", - "managerFilePatterns": [ - "/^\\.github/workflows/(build|test)\\.yml$/" - ], - "matchStrings": [ - "(?quay\\.io/pypa/manylinux_2_28_(?:x86_64|aarch64)|alpine|debian):(?[A-Za-z0-9][A-Za-z0-9._-]*)@(?sha256:[a-f0-9]{64})" - ], - "datasourceTemplate": "docker" - } - ], - "packageRules": [ - { - "description": "Group all ledger dependency bumps under a clear prefix so CI (build + docs-matrix) validates each PR against every FFmpeg line before merge.", - "matchManagers": [ - "custom.jsonata", - "custom.regex" - ], - "commitMessagePrefix": "chore(deps):", - "semanticCommits": "disabled" - }, - { - "description": "Batch EVERY ledger update -- major, minor, patch and digest alike -- into ONE grouped PR per run. Majors used to be left ungrouped so each got individual scrutiny, but every one of these updates edits deps.json, so concurrent PRs conflict with each other and the conflict resolution costs more than the separate review buys. One PR means one deps.json to reason about and one CI run (build + docs-matrix) validating the whole set against every FFmpeg line. A major that needs to be held back can be split out by pinning it in .overrides with a tracking issue.", - "matchManagers": [ - "custom.jsonata", - "custom.regex" - ], - "groupName": "FFmpeg + library dependencies", - "separateMajorMinor": false, - "separateMinorPatch": false - }, - { - "description": "Anything pinned INSIDE a workflow file (renovate-version; the build/test container images are split further into their own group by the next rule) gets its OWN PR, separate from the ledger group above. Renovate cannot push to .github/workflows/ unless its token carries the workflow scope, and when it cannot it does not skip that one file -- it logs 'Workflows update rejection - aborting branch' and discards the ENTIRE branch, so a single un-writable file silently took out every library bump in the batch (measured: vmaf, whisper.cpp, shaderc and libmp3lame updates were all dropped while the job still reported success). Splitting by file keeps the blast radius of a missing scope to this PR alone, and the ledger keeps flowing regardless. Matched by file rather than by dep name so a future workflow pin lands here automatically.", - "matchFileNames": [ - ".github/workflows/**" - ], - "groupName": "CI tooling pinned in workflows", - "separateMajorMinor": false, - "separateMinorPatch": false - }, - { - "description": "Build/test container images in their OWN PR, after the ledger group above so it wins. Same reason as Renovate itself: these refs live in .github/workflows/, and a token without the workflow scope aborts the whole branch, so they must not ride in the ledger batch. A merged bump rebuilds and releases every FFmpeg line (select-versions.sh keys on the changed @sha256 line), so this is one PR Renovate keeps rebased rather than one per image: merge it at the cadence a toolchain change deserves.", - "matchManagers": [ - "custom.regex" - ], - "matchDepNames": [ - "quay.io/pypa/manylinux_2_28_x86_64", - "quay.io/pypa/manylinux_2_28_aarch64", - "alpine", - "debian" - ], - "groupName": "build container images", - "commitMessagePrefix": "chore(images):", - "separateMajorMinor": false, - "separateMinorPatch": false - }, - { - "description": "manylinux publishes date tags (YYYY.MM.DD-N, N = same-day rebuild). Default docker versioning reads the -N suffix as a compatibility marker rather than an ordinal, so spell the scheme out: build orders same-day rebuilds.", - "matchDepNames": [ - "quay.io/pypa/manylinux_2_28_x86_64", - "quay.io/pypa/manylinux_2_28_aarch64" - ], - "versioning": "regex:^(?\\d{4})\\.(?\\d{2})\\.(?\\d{2})-(?\\d+)$" - }, - { - "description": "Alpine: offer patch and minor releases (3.24.x -> 3.25.y) -- a minor IS a new GCC/musl and therefore a new ABI floor for the musl artifacts, which is exactly why it must arrive as a reviewable PR rather than silently. Never the edge/date-tagged development stream.", - "matchDepNames": [ - "alpine" - ], - "allowedVersions": "/^3\\.\\d+\\.\\d+$/" - }, - { - "description": "Vulkan-Headers/Loader + SPIRV-Headers ship in lockstep on vulkan-sdk-* release tags (the ledger pins the same SDK version across all three). Each repo ALSO carries a parallel v1.4.x tag scheme; restrict Renovate to the vulkan-sdk-* versioning so it can't cross namespaces or desync the trio (which it otherwise would — it proposed v1.4.360 for Loader+SPIRV but not Headers).", - "matchPackageNames": [ - "https://github.com/KhronosGroup/Vulkan-Headers.git", - "https://github.com/KhronosGroup/Vulkan-Loader.git", - "https://github.com/KhronosGroup/SPIRV-Headers.git" - ], - "versioning": "regex:^vulkan-sdk-(?\\d+)\\.(?\\d+)\\.(?\\d+)\\.(?\\d+)$" - }, - { - "description": "Constrain each FFmpeg line to its own MAJOR: Renovate offers any newer release within the major — patch or minor alike (9.0.1 -> 9.0.2 -> 9.1.0) — but never a cross-major jump (9.x -> 10.x). One rule per maintained major; matchCurrentVersion scopes it to the line at that major, allowedVersions filters candidates to that major. A NEW major is a new line that check-updates.yml adds (with its matching rule).", - "matchPackageNames": [ - "https://github.com/FFmpeg/FFmpeg.git" - ], - "matchCurrentVersion": "/^8\\./", - "allowedVersions": "/^8\\./" - }, - { - "matchPackageNames": [ - "https://github.com/FFmpeg/FFmpeg.git" - ], - "matchCurrentVersion": "/^9\\./", - "allowedVersions": "/^9\\./" - }, - { - "description": "Hold mbedTLS on 3.x. FFmpeg's libavformat/tls_mbedtls.c includes and and calls mbedtls_ctr_drbg_seed/mbedtls_entropy_init/mbedtls_entropy_func unconditionally, with no version guard; mbedTLS 4.x removed those headers when that work moved to PSA Crypto, so 4.x cannot compile against any FFmpeg line we ship. Without this the grouped PR would be permanently red on an impossible bump, which is worse than not offering it. Remove once FFmpeg's mbedTLS backend supports 4.x. Tracked in issue #18.", - "matchPackageNames": [ - "https://github.com/Mbed-TLS/mbedtls.git" - ], - "allowedVersions": "<4.0.0" - } - ], - "customDatasources": { - "tarball-listing": { - "description": "Upstream release listing for deps that ship as a plain tarball with no git remote (GNU FTP, SourceForge, quut.com). format:html makes Renovate return every on the page verbatim; the manager's extractVersion then pulls the version out of whichever shape that site uses.", - "defaultRegistryUrlTemplate": "https://example.invalid/", - "format": "html" - } - } -} diff --git a/scripts/build.sh b/scripts/build.sh deleted file mode 100644 index ecffe65..0000000 --- a/scripts/build.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# Parameterized FFmpeg build script -# -# Build parameters (environment variables): -# FFMPEG_VERSION - FFmpeg version (default: first entry of deps.json .ffmpeg) -# BUILD_RID - Runtime identifier (required): -# linux-x64, linux-arm64, linux-armhf, -# linux-musl-x64, linux-musl-arm64, -# win-x64, win-arm64, osx-x64, osx-arm64, -# android-arm64, android-x64, -# ios-arm64, ios-sim-arm64 -# maccatalyst-arm64, maccatalyst-x64 -# BUILD_LICENSE - License family: gpl or lgpl (default: lgpl) -# BUILD_LICENSE_VERSION - License series: 3 (default) or 2 (GPLv2 / LGPLv2.1) -# SKIP_DEPS - true to skip host toolchain/package installation -# -# The per-RID toolchain (cross-gcc, mingw-w64, the iOS SDK, the Android NDK) is expected in the -# environment like any build tool — not a build parameter. The Android NDK is auto-detected from -# the SDK; if it can't be found the build errors out, same as a missing compiler. - -############################################ -# Step 1: Inputs & Paths -# -# Resolve the build inputs — FFmpeg version (first line of deps.json's .ffmpeg list), -# target RID, and license (lgpl/gpl) — and lay out the working and output -# directories used by the rest of the script. - -ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -FFMPEG_VERSION="${FFMPEG_VERSION:-$(jq -r '.ffmpeg[0]' "${ROOT_DIR}/deps.json")}" -RID="${BUILD_RID:?BUILD_RID is required}" -LICENSE="${BUILD_LICENSE:-lgpl}" - -WORK_DIR="${ROOT_DIR}/.build/${RID}" -# shellcheck disable=SC2034 # set here; consumed by a sourced sibling script -SRC_DIR="${WORK_DIR}/src" -# shellcheck disable=SC2034 # set here; consumed by a sourced sibling script -PREFIX_DIR="${WORK_DIR}/install" -OUT_DIR="${ROOT_DIR}/artifacts/${RID}/native" - -echo "=============================================" -echo "FFmpeg ${FFMPEG_VERSION} build" -echo " RID: ${RID}" -echo " License: ${LICENSE}" -echo "=============================================" - -mkdir -p "${WORK_DIR}" "${OUT_DIR}" - -# Shared helpers (cmake wrapper, build_cmake_dep) used by the build steps. -. "${ROOT_DIR}/scripts/lib.sh" -. "${ROOT_DIR}/scripts/deps/lib.sh" - -############################################ -# Build -# -# The whole build, one step per line. Each steps/NN_*.sh is SOURCED (runs in -# this shell, sharing the environment configured above) and does one part of -# the build; the details live in that step's file. Comment out a line to skip -# that step when debugging. -############################################ -S="${ROOT_DIR}/scripts/steps" -. "${S}/02_configure.sh" # per-RID toolchain, hwaccel flags, BUILD_* switches -. "${S}/04_select_license.sh" # apply gpl/lgpl flag; lean iOS-simulator trims -. "${S}/03_install_packages.sh" # install host build packages (apt/apk/brew) -# 04 BEFORE 03, deliberately. 04_select_license is pure flag logic -- no command substitution, -# no external tool -- while 03 PROVISIONS tools based on those flags, and the v2 series clears -# BUILD_VULKAN there. Run the other way round, every v2 cell still saw BUILD_VULKAN=1 and would -# build shaderc/glslc from source for a build that then disables Vulkan entirely: wasted time on -# a good day, and an extra way to fail on a bad one. Provisioning must see the FINAL state. -. "${S}/05_write_toolchain.sh" # deps dir + cross-compilation toolchain files -. "${S}/06_build_libraries.sh" # build third-party libraries (sources deps/*) -. "${S}/07_build_ffmpeg.sh" # download, configure, and build FFmpeg -. "${S}/08_stage_artifacts.sh" # stage per-platform artifacts, fix library paths -. "${S}/09_verify_build.sh" # static verification gate -. "${S}/10_write_legal.sh" # legal/ (licenses + source offer) + build-info diff --git a/scripts/ci/gen-manifest-test.sh b/scripts/ci/gen-manifest-test.sh deleted file mode 100644 index e4fc393..0000000 --- a/scripts/ci/gen-manifest-test.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env bash -# Unit test for the release checksum-manifest generator. Stubs the GitHub API call and the -# per-asset download so the generator runs with no network, no gh, and no jq. -set -uo pipefail -HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - -pass=0; fail=0 -check() { #