diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a4a8d5336..5ce6cfb63 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,7 +36,7 @@ env: libharfbuzz-dev libepoxy-dev libegl-dev libgl-dev libgnutls28-dev libpipewire-0.3-dev libva-dev libvdpau-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev libxpresent-dev libxkbcommon-dev libpulse-dev libdbus-1-dev libdrm-dev - libgbm-dev libwayland-dev wayland-protocols liblcms2-dev libmujs-dev liblua5.2-dev + libdisplay-info-dev libgbm-dev libwayland-dev wayland-protocols liblcms2-dev libmujs-dev liblua5.2-dev ruby ruby-dev rubygems build-essential rpm libarchive-tools imagemagick libcurl4-openssl-dev jobs: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 575d9a3dc..a333277f6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -657,7 +657,7 @@ jobs: libasound2-dev libass-dev libfreetype-dev libfontconfig-dev libfribidi-dev \ libharfbuzz-dev libegl-dev libgl-dev libgnutls28-dev libpipewire-0.3-dev \ libva-dev libxkbcommon-dev libpulse-dev libdbus-1-dev libdrm-dev \ - libgbm-dev libwayland-dev wayland-protocols liblcms2-dev libmujs-dev \ + libdisplay-info-dev libgbm-dev libwayland-dev wayland-protocols liblcms2-dev libmujs-dev \ liblua5.2-dev rpm libarchive-tools imagemagick ruby-dev build-essential sudo gem install fpm --version 1.17.0 --no-document diff --git a/linux/packaging/build-libmpv.sh b/linux/packaging/build-libmpv.sh index 50f104de6..b511c5c01 100755 --- a/linux/packaging/build-libmpv.sh +++ b/linux/packaging/build-libmpv.sh @@ -38,6 +38,11 @@ PY FFMPEG_VERSION="$(manifest_value ffmpeg version)" FFMPEG_URL="$(manifest_value ffmpeg url)" FFMPEG_SHA256="$(manifest_value ffmpeg sha256)" +DAV1D_VERSION="$(manifest_value dav1d version)" +DAV1D_URL="$(manifest_value dav1d url)" +DAV1D_MIRROR="$(manifest_optional dav1d mirror)" +DAV1D_REF="$(manifest_value dav1d ref)" +DAV1D_COMMIT="$(manifest_value dav1d commit)" SHADERC_VERSION="$(manifest_value shaderc version)" SHADERC_URL="$(manifest_value shaderc url)" SHADERC_REF="$(manifest_value shaderc ref)" @@ -183,7 +188,37 @@ main() { echo "==> Install prefix: $prefix" echo "" - # ─── Step 1: ffmpeg (static libraries) ───────────────────────────────────── + # ─── Step 1: dav1d (static library) ──────────────────────────────────────── + # The bundled ffmpeg has no AV1 software decoder: its native av1 decoder is + # hardware-accelerated only, and no libaom/libdav1d is linked in. When hwdec + # is unavailable or cannot serve the source (an AV1 file on a GPU without AV1 + # decode), AV1 has no path at all - every packet fails, video hits EOF and + # the plane goes black while audio keeps playing. dav1d is the software + # floor under AV1, exactly as libass is for subtitles. It must come before + # ffmpeg, whose configure resolves --enable-libdav1d against dav1d's + # pkg-config file. + echo "==> Building dav1d $DAV1D_VERSION (static)..." + checkout_verified_ref \ + "$DAV1D_URL" "$DAV1D_REF" "$DAV1D_COMMIT" \ + "$srcdir/dav1d-v${DAV1D_VERSION}" "$DAV1D_MIRROR" + cd "dav1d-v${DAV1D_VERSION}" + + meson setup build \ + --prefix="$prefix" \ + --default-library=static \ + -Denable_tools=false \ + -Denable_tests=false \ + -Denable_examples=false \ + -Denable_docs=false + + ninja -C build -j"$jobs" + ninja -C build install + cd "$srcdir" + echo "" + echo "==> dav1d done." + echo "" + + # ─── Step 2: ffmpeg (static libraries) ───────────────────────────────────── echo "==> Building ffmpeg $FFMPEG_VERSION (static, decoder-only)..." download_verified "$FFMPEG_URL" "$FFMPEG_SHA256" "$srcdir/ffmpeg.tar.xz" tar -xJf "$srcdir/ffmpeg.tar.xz" @@ -208,6 +243,7 @@ main() { --enable-filter=aformat,aresample,format,null,scale \ --enable-gnutls \ --enable-vaapi \ + --enable-libdav1d \ --disable-vdpau \ --disable-debug \ --disable-stripping @@ -219,7 +255,7 @@ main() { echo "==> ffmpeg done." echo "" - # ─── Step 2: shaderc (static library) ─────────────────────────────────────── + # ─── Step 3: shaderc (static library) ─────────────────────────────────────── echo "==> Building shaderc $SHADERC_VERSION (static)..." checkout_verified_ref \ "$SHADERC_URL" "$SHADERC_REF" "$SHADERC_COMMIT" \ @@ -243,7 +279,7 @@ main() { echo "==> shaderc done." echo "" - # ─── Step 3: libplacebo (static library) ─────────────────────────────────── + # ─── Step 4: libplacebo (static library) ─────────────────────────────────── echo "==> Building libplacebo $LIBPLACEBO_VERSION (static)..." checkout_verified_ref \ "$LIBPLACEBO_URL" "$LIBPLACEBO_REF" "$LIBPLACEBO_COMMIT" \ @@ -266,7 +302,7 @@ main() { echo "==> libplacebo done." echo "" - # ─── Step 4: mpv (shared libmpv) ─────────────────────────────────────────── + # ─── Step 5: mpv (shared libmpv) ─────────────────────────────────────────── echo "==> Building mpv $MPV_VERSION (shared libmpv only)..." download_verified "$MPV_URL" "$MPV_SHA256" "$srcdir/mpv.tar.gz" tar -xzf "$srcdir/mpv.tar.gz" @@ -276,6 +312,14 @@ main() { # MPV_RENDER_PARAM_WL_DISPLAY so VAAPI can find the device instead of falling # back to software decoding. A libmpv built without Wayland cannot use that. # VDPAU goes with X11 - it has no Wayland backend at all. + # + # drm/vaapi-drm/egl are pinned enabled, not left on auto: mpv's `drm` feature + # silently drops to disabled when libdisplay-info is missing, and every VAAPI + # path that does not depend on a display server - vaapi-copy's standalone + # render-node device and the GL dmabuf interop - is derived from it. Shipping + # that build quietly lands every source on software decoding (the 2.13.0 + # Fedora report). Enabled means the configure fails when the pieces are + # absent instead of degrading in silence. meson setup build \ --prefix="$prefix" \ -Dlibmpv=true \ @@ -289,7 +333,11 @@ main() { -Dvulkan=disabled \ -Dd3d11=disabled \ -Dgl=enabled \ + -Degl=enabled \ + -Ddrm=enabled \ -Dvaapi=enabled \ + -Dvaapi-drm=enabled \ + -Dvaapi-wayland=enabled \ -Dalsa=enabled \ -Dpulse=enabled \ -Dpipewire=enabled \ diff --git a/linux/packaging/build-libmpv_test.sh b/linux/packaging/build-libmpv_test.sh index 23396daab..e67bc3273 100755 --- a/linux/packaging/build-libmpv_test.sh +++ b/linux/packaging/build-libmpv_test.sh @@ -100,6 +100,7 @@ mkdir -p "$stub_bin" "$stub_extra" "$records" "$temporary/tmp" # Deliberately unlike the pinned versions: every path below is derived from the # manifest, so a stub that matched by accident would prove nothing. ffmpeg_version="9.9.9" +dav1d_version="2.2.2" shaderc_version="6.6.6" libplacebo_version="7.7.7" mpv_version="8.8.8" @@ -172,6 +173,14 @@ git -C "$shaderc_repository" commit --quiet -m shaderc git -C "$shaderc_repository" tag release shaderc_commit="$(git -C "$shaderc_repository" rev-parse HEAD)" +dav1d_repository="$temporary/dav1d-source" +init_repository "$dav1d_repository" +printf 'stub dav1d\n' >"$dav1d_repository/meson.build" +git -C "$dav1d_repository" add meson.build +git -C "$dav1d_repository" commit --quiet -m dav1d +git -C "$dav1d_repository" tag release +dav1d_commit="$(git -C "$dav1d_repository" rev-parse HEAD)" + libplacebo_repository="$temporary/libplacebo-source" init_repository "$libplacebo_repository" printf 'stub libplacebo\n' >"$libplacebo_repository/meson.build" @@ -189,6 +198,12 @@ cat >"$manifest" < None: elif kind == "git": ref = value.get("ref") commit = value.get("commit") - if not isinstance(ref, str) or ref != f"v{version}": - errors.append(f"{label}.ref: must be v{version}") + # dav1d tags releases as bare versions ("1.5.4"); the other pinned + # Git inputs tag them "v{version}". Either way the ref is verified + # against the recorded commit, which is the actual pin. + expected_ref = version if name == "dav1d" else f"v{version}" + if not isinstance(ref, str) or ref != expected_ref: + errors.append(f"{label}.ref: must be {expected_ref}") if not isinstance(commit, str) or HEX_COMMIT.fullmatch(commit) is None: errors.append(f"{label}.commit: must be a lowercase full Git commit") else: @@ -139,6 +143,7 @@ def _validate_native(root: Path, errors: list[str]) -> None: "native-inputs.json", 'download_verified "$FFMPEG_URL" "$FFMPEG_SHA256"', 'download_verified "$MPV_URL" "$MPV_SHA256"', + '"$DAV1D_URL" "$DAV1D_REF" "$DAV1D_COMMIT"', '"$SHADERC_URL" "$SHADERC_REF" "$SHADERC_COMMIT"', '"$LIBPLACEBO_URL" "$LIBPLACEBO_REF" "$LIBPLACEBO_COMMIT"', 'git submodule update --init --recursive',