#!/bin/bash # Build daedalus-v4l2__arm64.deb (userspace daemon + test tools). # # Mirrors arch/daedalus-v4l2 (Arch Linux build). The companion DKMS # package (debian/daedalus-v4l2-dkms) carries the kernel module # separately so apt/dpkg can split kernel-version-tied and userspace # upgrade cadence. # # Sibling Arch package: ../../arch/daedalus-v4l2/PKGBUILD # Sibling DKMS package: ../daedalus-v4l2-dkms/build-deb.sh # Upstream repo: https://git.reauktion.de/reauktion/daedalus-v4l2 set -euo pipefail # 6e6dfa1 = picks up daedalus-v4l2 PR #16 — daemon now dlopens # the Kwiboo fourier fork's libavcodec.so.62 / libavformat.so.62 / # libavutil.so.60 at /opt/fourier instead of Debian-stock soname # 61/61/59. First step on the daedalus-fourier substitution arc # (daedalus-v4l2#11): routes the daemon through the libavcodec # source tree we own in marfrit-packages. Headers + .pc files # come from ffmpeg-v4l2-request-fourier (installed by the CI # workflow before this script runs; see PKG_CONFIG_PATH below). UPSTREAM_COMMIT=1d8f5af1646c7c09b75e07be0c2763b37ea367e6 PKGVER=0.1.0+r43+g1d8f5af PKGREL=1 # reset for new upstream pin (1d8f5af — pause-time tiny-bitstream filter, closes #17) # daedalus-fourier pin. d87239d = marfrit/daedalus-fourier PR #1 merge # (install rules + pkg-config, enables this consumer to find_package # + link). Bump in lockstep with the upstream daemon when daedalus- # fourier's API or installed shaders are changed by a new consumer. DAEDALUS_FOURIER_COMMIT=d87239d8172307d9a1b93c95cbed116d175b85cc HERE=$(dirname "$(readlink -f "$0")") # Reproducible build. 2026-05-18 23:00 UTC — Phase 8.13 close. export SOURCE_DATE_EPOCH=1779231600 work=$(mktemp -d) trap "rm -rf $work" EXIT # --- daedalus-fourier: fetch + build + install to per-build prefix --- # # Static-linked into the daemon, so the temp prefix is only for the # duration of this build script. Requires libvulkan-dev + glslang-tools # on the runner (already needed for the daedalus-fourier benches). FOURIER_PREFIX=$work/fourier-prefix mkdir -p "$FOURIER_PREFIX" cd "$work" curl --connect-timeout 10 --max-time 600 --retry 3 --retry-delay 5 -sSLfo daedalus-fourier.tar.gz \ "https://git.reauktion.de/marfrit/daedalus-fourier/archive/${DAEDALUS_FOURIER_COMMIT}.tar.gz" tar xzf daedalus-fourier.tar.gz cd daedalus-fourier cmake -B build -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX="$FOURIER_PREFIX" cmake --build build --target daedalus_core cmake --install build # --- daedalus-v4l2: fetch + build daemon against installed daedalus-fourier --- cd "$work" curl --connect-timeout 10 --max-time 600 --retry 3 --retry-delay 5 -sSLfo daedalus-v4l2.tar.gz \ "https://git.reauktion.de/reauktion/daedalus-v4l2/archive/${UPSTREAM_COMMIT}.tar.gz" tar xzf daedalus-v4l2.tar.gz SRCDIR=daedalus-v4l2 # Build daemon (CMake) — point pkg-config at the daedalus-fourier # temp prefix so pkg_check_modules(DAEDALUS_FOURIER …) resolves to it. cd "$SRCDIR/daemon" PKG_CONFIG_PATH="$FOURIER_PREFIX/lib/pkgconfig:/opt/fourier/lib/pkgconfig" \ cmake -B build -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr cmake --build build # Build test tools (in-tree Makefile) cd "$work/$SRCDIR/tools" make # Stage ROOT="$work/pkgroot" mkdir -p "$ROOT/DEBIAN" \ "$ROOT/usr/bin" \ "$ROOT/usr/libexec/daedalus-v4l2" \ "$ROOT/usr/include" \ "$ROOT/usr/share/doc/daedalus-v4l2" \ "$ROOT/lib/systemd/system" \ "$ROOT/usr/lib/modules-load.d" install -m 755 "$work/$SRCDIR/daemon/build/daedalus_v4l2_daemon" \ "$ROOT/usr/bin/daedalus_v4l2_daemon" install -m 755 "$work/$SRCDIR/tools/test_chardev_pingpong" \ "$ROOT/usr/libexec/daedalus-v4l2/test_chardev_pingpong" install -m 755 "$work/$SRCDIR/tools/test_m2m_decode" \ "$ROOT/usr/libexec/daedalus-v4l2/test_m2m_decode" install -m 755 "$work/$SRCDIR/tools/test_m2m_stream" \ "$ROOT/usr/libexec/daedalus-v4l2/test_m2m_stream" install -m 644 "$work/$SRCDIR/include/daedalus_v4l2_proto.h" \ "$ROOT/usr/include/daedalus_v4l2_proto.h" # systemd unit + module autoload — without these the daemon never # starts and the libva/VAAPI consumer's REQ_DECODE has nobody on # the other end of /dev/daedalus-v4l2. install -m 644 "$work/$SRCDIR/packaging/systemd/daedalus-v4l2.service" \ "$ROOT/lib/systemd/system/daedalus-v4l2.service" install -m 644 "$work/$SRCDIR/packaging/systemd/daedalus-v4l2.modules-load" \ "$ROOT/usr/lib/modules-load.d/daedalus-v4l2.conf" install -m 644 "$work/$SRCDIR/README.md" \ "$ROOT/usr/share/doc/daedalus-v4l2/README.md" for d in "$work/$SRCDIR/docs/"*.md; do install -m 644 "$d" "$ROOT/usr/share/doc/daedalus-v4l2/$(basename "$d")" done install -Dm644 "$HERE/debian/copyright" "$ROOT/usr/share/doc/daedalus-v4l2/copyright" install -Dm644 "$HERE/debian/changelog" "$ROOT/usr/share/doc/daedalus-v4l2/changelog.Debian" gzip -9 -n "$ROOT/usr/share/doc/daedalus-v4l2/changelog.Debian" # DEBIAN/postinst — enable service + reload modules-load.d so the # kernel module loads now if daedalus-v4l2-dkms is also installed. # Does NOT auto-start the service — that requires /dev/daedalus-v4l2 # to already exist (the ConditionPathExists= in the .service file) # which may not be true on the very first install before the user # reboots or manually modprobes. Operator decides when to start. cat > "$ROOT/DEBIAN/postinst" <<'POSTINST' #!/bin/sh set -e if [ "$1" = "configure" ]; then # Reload systemd so the new unit file is visible. if command -v systemctl >/dev/null 2>&1; then systemctl daemon-reload >/dev/null 2>&1 || true systemctl enable daedalus-v4l2.service >/dev/null 2>&1 || true fi # Trigger /usr/lib/modules-load.d/daedalus-v4l2.conf without a # reboot. Harmless if the module is already loaded; logs to # journal if it can't load (most common cause: dkms hasn't built # the module yet for the running kernel — see daedalus-v4l2-dkms # postinst for the loud-warning path). if command -v systemd-modules-load >/dev/null 2>&1; then systemd-modules-load >/dev/null 2>&1 || true fi # Auto-start if /dev/daedalus-v4l2 came up (i.e. module loaded # successfully). ConditionPathExists in the unit file means # `systemctl start` is a no-op if the device isn't there yet — # avoids spurious failures during apt install on a host where # daedalus-v4l2-dkms hasn't built yet. if [ -e /dev/daedalus-v4l2 ] && command -v systemctl >/dev/null 2>&1; then systemctl start daedalus-v4l2.service >/dev/null 2>&1 || true fi fi #DEBHELPER# POSTINST chmod 755 "$ROOT/DEBIAN/postinst" cat > "$ROOT/DEBIAN/prerm" <<'PRERM' #!/bin/sh set -e if [ "$1" = "remove" ] && command -v systemctl >/dev/null 2>&1; then systemctl stop daedalus-v4l2.service >/dev/null 2>&1 || true systemctl disable daedalus-v4l2.service >/dev/null 2>&1 || true fi #DEBHELPER# PRERM chmod 755 "$ROOT/DEBIAN/prerm" cat > "$ROOT/DEBIAN/postrm" <<'POSTRM' #!/bin/sh set -e if command -v systemctl >/dev/null 2>&1; then systemctl daemon-reload >/dev/null 2>&1 || true fi #DEBHELPER# POSTRM chmod 755 "$ROOT/DEBIAN/postrm" cat > "$ROOT/DEBIAN/control" <= 2:8.1+rfourier), libdrm2 Recommends: daedalus-v4l2-dkms Maintainer: Markus Fritsche Homepage: https://git.reauktion.de/reauktion/daedalus-v4l2 Description: Userspace daemon for the daedalus_v4l2 stateless decoder shim daedalus-v4l2 ships the userspace daemon that backs the daedalus_v4l2 out-of-tree V4L2 kernel module on Raspberry Pi 5 / CM5. Together they expose /dev/videoNN + /dev/mediaNN as a V4L2 stateless decoder for VP9, AV1, and H.264 — actual decoding happens in this single-threaded daemon via dlopen'd FFmpeg, with decoded NV12 / P010 frames shipped back through dmabuf. . Consumed end-to-end by libva-v4l2-request-fourier (>= 1.0.0+r376) so that 'ffmpeg -hwaccel vaapi' against vp9_small.ivf produces a byte-exact NV12 frame. . The kernel module ships separately in daedalus-v4l2-dkms; install both to actually serve V4L2 clients. EOF DEB_OUT="daedalus-v4l2_${PKGVER}-${PKGREL}_arm64.deb" dpkg-deb --root-owner-group --build "$ROOT" "$HERE/$DEB_OUT" echo "built: $HERE/$DEB_OUT"