forked from marfrit/marfrit-packages
Compare commits
44 Commits
main
...
1bd11eaf27
| Author | SHA1 | Date | |
|---|---|---|---|
| 1bd11eaf27 | |||
| 4776dc01d2 | |||
| f3dd1c1886 | |||
| add049f0bd | |||
| 249e8461bb | |||
| 3293cd6542 | |||
| 6de7268b49 | |||
| dbae9832b6 | |||
| b248aa2ac8 | |||
| 06023bcf9d | |||
| 7542989f2b | |||
| 9e9447502e | |||
| eb1782e86f | |||
| a168342fa8 | |||
| 4820e53b18 | |||
| 248bef5503 | |||
| 8a49ac6061 | |||
| 4764f5f37f | |||
| dcb1da2f59 | |||
| 238c5cee7e | |||
| 70c943e948 | |||
| d6c4260eb8 | |||
| 1fed626900 | |||
| 0b2393cecc | |||
| 697413103d | |||
| b648276122 | |||
| 2e2c9b6361 | |||
| 0d311d61b4 | |||
| efc1bfd66a | |||
| 154fa2f14a | |||
| 2af63ce988 | |||
| e9bc6ebd27 | |||
| 201e671d61 | |||
| d63d1cef72 | |||
| 108c725c58 | |||
| 75dadb2925 | |||
| fedcc4a357 | |||
| 860ebf2df5 | |||
| 109858eae5 | |||
| 9041c1bf51 | |||
| f41e9a117b | |||
| 2f78136479 | |||
| 62a594ab59 | |||
| 81cc050bf3 |
@@ -375,7 +375,7 @@ jobs:
|
||||
run: rm -f /root/repo_pass /root/.ssh/id_ed25519
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# ffmpeg-v4l2-request-git (aarch64 only) — FFmpeg with V4L2 Request API
|
||||
# ffmpeg-v4l2-request-fourier (aarch64 only) — FFmpeg with V4L2 Request API
|
||||
# hwaccel for Rockchip / Allwinner stateless decoders. Used by the Fourier
|
||||
# umbrella (ohm, fresnel, ampere). Long-running build, so failures don't
|
||||
# block downstream debian jobs.
|
||||
@@ -416,11 +416,11 @@ jobs:
|
||||
chmod 600 /root/.ssh/id_ed25519
|
||||
ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null
|
||||
|
||||
- name: makepkg ffmpeg-v4l2-request-git
|
||||
- name: makepkg ffmpeg-v4l2-request-fourier
|
||||
run: |
|
||||
set -e
|
||||
rm -rf /tmp/build-ffmpeg-v4l2
|
||||
cp -r arch/ffmpeg-v4l2-request-git /tmp/build-ffmpeg-v4l2
|
||||
cp -r arch/ffmpeg-v4l2-request-fourier /tmp/build-ffmpeg-v4l2
|
||||
chown -R builder:builder /tmp/build-ffmpeg-v4l2
|
||||
cd /tmp/build-ffmpeg-v4l2
|
||||
# Parallelise wide; distcc-avahi distributes compiles across the
|
||||
@@ -429,7 +429,7 @@ jobs:
|
||||
makepkg --nocheck --noconfirm --syncdeps --cleanbuild
|
||||
ls -la *.pkg.tar.* | grep -v "\.sig$"
|
||||
|
||||
- name: sign ffmpeg-v4l2-request-git
|
||||
- name: sign ffmpeg-v4l2-request-fourier
|
||||
run: |
|
||||
set -e
|
||||
cd /tmp/build-ffmpeg-v4l2
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
# Maintainer: Markus Fritsche <fritsche.markus@gmail.com>
|
||||
#
|
||||
# daedalus-v4l2-dkms — DKMS package for the daedalus_v4l2 out-of-tree
|
||||
# kernel module (V4L2 stateless decoder shim for Pi 5 / CM5).
|
||||
#
|
||||
# Pair to daedalus-v4l2 (userspace daemon). When loaded, the module
|
||||
# registers /dev/videoNN (V4L2 m2m) + /dev/mediaNN (media controller) +
|
||||
# /dev/daedalus-v4l2 (chardev to the userspace daemon). Userspace
|
||||
# clients drive the V4L2 m2m + request API path; the daemon does the
|
||||
# actual FFmpeg-backed decode on /dev/daedalus-v4l2.
|
||||
#
|
||||
# Project: https://git.reauktion.de/reauktion/daedalus-v4l2
|
||||
# Sibling userspace package: daedalus-v4l2
|
||||
# Sibling consumer: libva-v4l2-request-fourier
|
||||
|
||||
pkgname=daedalus-v4l2-dkms
|
||||
_module=daedalus_v4l2
|
||||
|
||||
# Same pin as arch/daedalus-v4l2 — keep kernel module + daemon
|
||||
# bit-versioned together so the chardev wire protocol stays in sync.
|
||||
_commit=f55b2cdab8a8c0bc04e8c1bb1d0b6ca85e7d96d2
|
||||
|
||||
pkgver=0.1.0.r16.f55b2cd
|
||||
pkgrel=1
|
||||
pkgdesc="V4L2 stateless decoder shim kernel module (DKMS) — Pi 5 / CM5"
|
||||
arch=('any')
|
||||
url="https://git.reauktion.de/reauktion/daedalus-v4l2"
|
||||
license=('GPL-2.0-or-later')
|
||||
depends=('dkms')
|
||||
makedepends=('git')
|
||||
install="${pkgname}.install"
|
||||
|
||||
source=("git+https://git.reauktion.de/reauktion/daedalus-v4l2.git#commit=${_commit}"
|
||||
"dkms.conf"
|
||||
"${pkgname}.install")
|
||||
sha256sums=('SKIP'
|
||||
'SKIP'
|
||||
'SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/daedalus-v4l2"
|
||||
printf '0.1.0.r%s.%s' \
|
||||
"$(git rev-list --count HEAD)" \
|
||||
"$(git rev-parse --short=7 HEAD)"
|
||||
}
|
||||
|
||||
package() {
|
||||
local _src="${pkgdir}/usr/src/${_module}-${pkgver}"
|
||||
|
||||
install -dm755 "${_src}"
|
||||
|
||||
# Install the kernel/ subdir and embed the shared proto header in
|
||||
# the same tree. The in-tree Makefile uses
|
||||
# `ccflags-y += -I$(src)/../include` (assuming the parent
|
||||
# daedalus-v4l2 layout); for DKMS we flatten by copying the header
|
||||
# into kernel/include/ and patching the Makefile to point there.
|
||||
cp -r "${srcdir}/daedalus-v4l2/kernel/." "${_src}/"
|
||||
install -Dm644 "${srcdir}/daedalus-v4l2/include/daedalus_v4l2_proto.h" \
|
||||
"${_src}/include/daedalus_v4l2_proto.h"
|
||||
sed -i 's|-I\$(src)/\.\./include|-I$(src)/include|' "${_src}/Makefile"
|
||||
|
||||
# dkms.conf at the root of the source tree (DKMS convention).
|
||||
# Substitute #MODULE_VERSION# placeholder with the actual pkgver
|
||||
# so dkms install/uninstall match what's on disk.
|
||||
install -Dm644 "${srcdir}/dkms.conf" "${_src}/dkms.conf"
|
||||
sed -i "s/#MODULE_VERSION#/${pkgver}/" "${_src}/dkms.conf"
|
||||
|
||||
# License
|
||||
install -Dm644 "${srcdir}/daedalus-v4l2/kernel/daedalus_v4l2_main.c" \
|
||||
"${pkgdir}/usr/share/licenses/${pkgname}/SPDX-HEADER"
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
# post-install / post-upgrade hook for daedalus-v4l2-dkms.
|
||||
#
|
||||
# pacman + the dkms-helpers alpm hook will already attempt
|
||||
# `dkms install` on its own. This script's job is to emit a
|
||||
# loud, actionable warning when the module didn't actually
|
||||
# build for the running kernel — most commonly because the
|
||||
# kernel headers package isn't installed yet.
|
||||
#
|
||||
# Without this you get a silent failure: the package looks
|
||||
# installed but `modprobe daedalus_v4l2` returns ENOENT.
|
||||
|
||||
_check_dkms_built() {
|
||||
local name=daedalus_v4l2
|
||||
local ver=$1
|
||||
local kernelver=$(uname -r)
|
||||
|
||||
if ! command -v dkms >/dev/null 2>&1; then
|
||||
return 1 # the hard-dep should have caught this
|
||||
fi
|
||||
|
||||
local status
|
||||
status=$(dkms status -m "$name" -v "$ver" -k "$kernelver" 2>/dev/null || true)
|
||||
if printf '%s\n' "$status" | grep -q -E 'installed|loaded'; then
|
||||
return 0 # all good
|
||||
fi
|
||||
|
||||
cat >&2 <<EOF
|
||||
==> daedalus-v4l2-dkms: DKMS build did NOT land for kernel $kernelver.
|
||||
==> dkms status -m $name -v $ver -k $kernelver:
|
||||
==> $(printf '%s' "$status" | head -1)
|
||||
==>
|
||||
==> Most likely cause: kernel headers package is missing.
|
||||
==> Arch / ALARM: pacman -S linux-rpi-headers (or linux-rpi5-headers)
|
||||
==> Raspberry Pi OS: apt install linux-headers-rpi-2712
|
||||
==>
|
||||
==> After installing headers, finish the install with:
|
||||
==> sudo dkms autoinstall $name/$ver
|
||||
==> sudo modprobe daedalus_v4l2
|
||||
==>
|
||||
==> Until then daedalus_v4l2 will NOT be loadable and the
|
||||
==> userspace daedalus-v4l2 daemon will have nothing to talk to.
|
||||
EOF
|
||||
return 1
|
||||
}
|
||||
|
||||
post_install() {
|
||||
_check_dkms_built "$1" || true
|
||||
}
|
||||
|
||||
post_upgrade() {
|
||||
# New version pinned by the bump may have built fine, but if
|
||||
# a kernel-headers package was uninstalled / pruned since the
|
||||
# last upgrade we'd silently regress. Re-check.
|
||||
_check_dkms_built "$1" || true
|
||||
}
|
||||
|
||||
pre_remove() {
|
||||
# The dkms alpm hook handles dkms remove on its own; nothing
|
||||
# we need to add here.
|
||||
:
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
# DKMS configuration for daedalus_v4l2 — V4L2 stateless decoder shim.
|
||||
#
|
||||
# Built against /lib/modules/$kernelver/build with the in-tree Makefile.
|
||||
# The Makefile uses `obj-m := daedalus_v4l2.o` and links
|
||||
# daedalus_v4l2_main.o + daedalus_v4l2_chardev.o into the final .ko.
|
||||
|
||||
PACKAGE_NAME="daedalus_v4l2"
|
||||
PACKAGE_VERSION="#MODULE_VERSION#"
|
||||
|
||||
# Single module produced by the Makefile.
|
||||
BUILT_MODULE_NAME[0]="daedalus_v4l2"
|
||||
DEST_MODULE_LOCATION[0]="/updates"
|
||||
|
||||
# Use the package's own Makefile — it already does
|
||||
# `$(MAKE) -C $(KERNELDIR) M=$(PWD) modules`.
|
||||
MAKE[0]="make KERNELDIR=/lib/modules/${kernelver}/build all"
|
||||
CLEAN="make KERNELDIR=/lib/modules/${kernelver}/build clean"
|
||||
|
||||
AUTOINSTALL="yes"
|
||||
@@ -0,0 +1,105 @@
|
||||
# Maintainer: Markus Fritsche <fritsche.markus@gmail.com>
|
||||
#
|
||||
# daedalus-v4l2 — userspace daemon + V4L2 m2m test tools.
|
||||
#
|
||||
# Pair to daedalus-v4l2-dkms (kernel module). Together they expose
|
||||
# /dev/videoNN + /dev/mediaNN as a V4L2 stateless decoder shim on Pi 5 /
|
||||
# CM5, decoding VP9 / AV1 / H.264 via dlopen'd FFmpeg in a single-
|
||||
# threaded daemon and shipping decoded NV12 / P010 back through dmabuf.
|
||||
# Consumed end-to-end by libva-v4l2-request-fourier (>= 1.0.0.r376) so
|
||||
# `ffmpeg -hwaccel vaapi` against vp9_small.ivf produces byte-exact NV12.
|
||||
#
|
||||
# Project: https://git.reauktion.de/reauktion/daedalus-v4l2
|
||||
# Sibling kernel package: daedalus-v4l2-dkms
|
||||
# Sibling consumer: libva-v4l2-request-fourier
|
||||
|
||||
pkgname=daedalus-v4l2
|
||||
_upstreampkg=daedalus-v4l2
|
||||
|
||||
# Pin the daedalus-v4l2 tip. f55b2cd = "Phase 8.13: byte-exact end-to-
|
||||
# end via libva (consumer target hit)" — first commit where the full
|
||||
# ffmpeg -hwaccel vaapi → libva → /dev/video0 → daemon path lands a
|
||||
# pixel-correct decoded frame back in ffmpeg. Promote to a later pin
|
||||
# only after a future phase closes cleanly.
|
||||
_commit=f55b2cdab8a8c0bc04e8c1bb1d0b6ca85e7d96d2
|
||||
|
||||
# 0.1.0 (pre-1.0) + commit count + short sha. Bump the .Y on each
|
||||
# Phase 8.x close. pkgver() recomputes at build time.
|
||||
pkgver=0.1.0.r16.f55b2cd
|
||||
pkgrel=1
|
||||
pkgdesc="Userspace daemon for the daedalus-v4l2 V4L2 stateless decoder shim (VP9/AV1/H.264 on Pi 5 / CM5)"
|
||||
arch=('aarch64')
|
||||
url="https://git.reauktion.de/reauktion/daedalus-v4l2"
|
||||
license=('BSD-2-Clause' 'GPL-2.0-or-later')
|
||||
# Daemon dlopens libavformat.so.61 / libavcodec.so.61 / libavutil.so.59
|
||||
# at runtime (Option γ — see daemon/src/ffmpeg_loader.h). ffmpeg
|
||||
# provides those; we don't link them.
|
||||
depends=('ffmpeg' 'libdrm')
|
||||
# Headers from libav*-dev needed at compile time for type-safe function
|
||||
# pointer signatures; pkg-config locates them.
|
||||
makedepends=('cmake' 'ninja' 'pkgconf' 'git' 'ffmpeg')
|
||||
optdepends=('daedalus-v4l2-dkms: kernel module providing /dev/video0 + /dev/daedalus-v4l2'
|
||||
'libva-v4l2-request-fourier: VA-API consumer routing through this daemon')
|
||||
|
||||
source=("git+https://git.reauktion.de/reauktion/daedalus-v4l2.git#commit=${_commit}")
|
||||
sha256sums=('SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/${_upstreampkg}"
|
||||
printf '0.1.0.r%s.%s' \
|
||||
"$(git rev-list --count HEAD)" \
|
||||
"$(git rev-parse --short=7 HEAD)"
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${_upstreampkg}/daemon"
|
||||
cmake -B build -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr
|
||||
cmake --build build
|
||||
|
||||
cd "${srcdir}/${_upstreampkg}/tools"
|
||||
make
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${_upstreampkg}"
|
||||
|
||||
# Daemon binary
|
||||
install -Dm755 daemon/build/daedalus_v4l2_daemon \
|
||||
"${pkgdir}/usr/bin/daedalus_v4l2_daemon"
|
||||
|
||||
# Test tools (under /usr/libexec to keep them out of the default PATH
|
||||
# — they're for verification, not daily use).
|
||||
install -Dm755 tools/test_chardev_pingpong \
|
||||
"${pkgdir}/usr/libexec/daedalus-v4l2/test_chardev_pingpong"
|
||||
install -Dm755 tools/test_m2m_decode \
|
||||
"${pkgdir}/usr/libexec/daedalus-v4l2/test_m2m_decode"
|
||||
install -Dm755 tools/test_m2m_stream \
|
||||
"${pkgdir}/usr/libexec/daedalus-v4l2/test_m2m_stream"
|
||||
|
||||
# Shared wire-protocol header (kernel ↔ daemon); useful for
|
||||
# third-party clients of the chardev.
|
||||
install -Dm644 include/daedalus_v4l2_proto.h \
|
||||
"${pkgdir}/usr/include/daedalus_v4l2_proto.h"
|
||||
|
||||
# Documentation
|
||||
install -Dm644 README.md \
|
||||
"${pkgdir}/usr/share/doc/${pkgname}/README.md"
|
||||
for d in docs/*.md; do
|
||||
install -Dm644 "$d" "${pkgdir}/usr/share/doc/${pkgname}/$(basename "$d")"
|
||||
done
|
||||
|
||||
# Licenses: BSD-2-Clause for daemon/tools, GPL for the kernel proto
|
||||
# header; the SPDX headers in src/ are the canonical declaration but
|
||||
# ship a short note here for package-manager-driven license queries.
|
||||
install -dm755 "${pkgdir}/usr/share/licenses/${pkgname}"
|
||||
cat > "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE" <<'EOF'
|
||||
daedalus-v4l2 userspace components are BSD-2-Clause licensed.
|
||||
The shared kernel↔daemon wire protocol header
|
||||
(/usr/include/daedalus_v4l2_proto.h) is GPL-2.0-or-later WITH
|
||||
Linux-syscall-note for kernel-side compatibility. See SPDX
|
||||
headers on individual source files for the canonical
|
||||
per-file declaration.
|
||||
EOF
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
From 0cd6e669735e453ec8772f111065bbb2f70a5bc6 Mon Sep 17 00:00:00 2001
|
||||
From: Markus Fritsche <mfritsche@reauktion.de>
|
||||
Date: Mon, 18 May 2026 07:27:10 +0000
|
||||
Subject: [PATCH] avutil/hwcontext_v4l2request: unpack NV15 to P010 in
|
||||
transfer_data_from
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
V4L2_PIX_FMT_NV15 (RK3399/RK3588 rkvdec 10-bit 4:2:0 capture) is mapped to
|
||||
sw_format = AV_PIX_FMT_YUV420P10 in v4l2request_capture_pixelformats[]. The
|
||||
existing transfer_get_formats explicitly blanked the format list for that
|
||||
sw_format, so 'ffmpeg -hwaccel v4l2request -vf hwdownload,format=p010le' on
|
||||
a Hi10P / Main10 input failed at filter init with EINVAL before reaching
|
||||
the actual decode (which itself succeeds — 2 frames decoded cleanly).
|
||||
|
||||
Expose AV_PIX_FMT_P010 as the transfer target for NV15-backed surfaces and
|
||||
unpack the packed 10-bit samples into the standard high-bits-of-16 layout
|
||||
inside transfer_data_from. Luma and chroma share the same packing format
|
||||
(5 bytes per 4 samples, little endian); chroma plane is W × H/2 samples
|
||||
for 4:2:0.
|
||||
|
||||
The other 'needs custom unpack' sw_formats (YUV420P / Allwinner NV12_32L32
|
||||
tiled and YUV422P10 / rkvdec NV20) keep the original ENOSYS path because
|
||||
they need different unpack code that isn't covered by this patch.
|
||||
|
||||
Closes marfrit/marfrit-packages#21.
|
||||
---
|
||||
libavutil/hwcontext_v4l2request.c | 111 +++++++++++++++++++++++++++++-
|
||||
1 file changed, 110 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libavutil/hwcontext_v4l2request.c b/libavutil/hwcontext_v4l2request.c
|
||||
index b6633d9081..3842160dfb 100644
|
||||
--- a/libavutil/hwcontext_v4l2request.c
|
||||
+++ b/libavutil/hwcontext_v4l2request.c
|
||||
@@ -1073,6 +1073,56 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Unpack one NV15-packed 10-bit plane (5 bytes per 4 samples, little endian)
|
||||
+ * into a P010-style plane (10 bits in the high bits of a 16-bit container).
|
||||
+ * `dst_stride` is in bytes; `src_stride` is bytes per row of NV15 data.
|
||||
+ */
|
||||
+static void v4l2request_nv15_unpack_plane_to_p010(const uint8_t *src,
|
||||
+ uint16_t *dst,
|
||||
+ unsigned width,
|
||||
+ unsigned height,
|
||||
+ unsigned src_stride,
|
||||
+ unsigned dst_stride)
|
||||
+{
|
||||
+ for (unsigned y = 0; y < height; y++) {
|
||||
+ const uint8_t *s = src + y * src_stride;
|
||||
+ uint16_t *d = (uint16_t *)((uint8_t *)dst + y * dst_stride);
|
||||
+ unsigned x;
|
||||
+
|
||||
+ for (x = 0; x + 4 <= width; x += 4) {
|
||||
+ uint16_t a = (uint16_t)s[0] | ((uint16_t)(s[1] & 0x03) << 8);
|
||||
+ uint16_t b = ((uint16_t)s[1] >> 2) | ((uint16_t)(s[2] & 0x0F) << 6);
|
||||
+ uint16_t c = ((uint16_t)s[2] >> 4) | ((uint16_t)(s[3] & 0x3F) << 4);
|
||||
+ uint16_t e = ((uint16_t)s[3] >> 6) | ((uint16_t)s[4] << 2);
|
||||
+
|
||||
+ d[0] = (uint16_t)(a << 6);
|
||||
+ d[1] = (uint16_t)(b << 6);
|
||||
+ d[2] = (uint16_t)(c << 6);
|
||||
+ d[3] = (uint16_t)(e << 6);
|
||||
+
|
||||
+ d += 4;
|
||||
+ s += 5;
|
||||
+ }
|
||||
+
|
||||
+ if (x < width) {
|
||||
+ unsigned rem = width - x;
|
||||
+ uint16_t pix[4] = { 0, 0, 0, 0 };
|
||||
+
|
||||
+ pix[0] = (uint16_t)s[0] | ((uint16_t)(s[1] & 0x03) << 8);
|
||||
+ if (rem >= 2)
|
||||
+ pix[1] = ((uint16_t)s[1] >> 2) | ((uint16_t)(s[2] & 0x0F) << 6);
|
||||
+ if (rem >= 3)
|
||||
+ pix[2] = ((uint16_t)s[2] >> 4) | ((uint16_t)(s[3] & 0x3F) << 4);
|
||||
+ if (rem >= 4)
|
||||
+ pix[3] = ((uint16_t)s[3] >> 6) | ((uint16_t)s[4] << 2);
|
||||
+
|
||||
+ for (unsigned j = 0; j < rem; j++)
|
||||
+ d[j] = (uint16_t)(pix[j] << 6);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int v4l2request_transfer_get_formats(AVHWFramesContext *hwfc,
|
||||
enum AVHWFrameTransferDirection dir,
|
||||
enum AVPixelFormat **formats)
|
||||
@@ -1082,6 +1132,22 @@ static int v4l2request_transfer_get_formats(AVHWFramesContext *hwfc,
|
||||
if (dir == AV_HWFRAME_TRANSFER_DIRECTION_TO)
|
||||
return AVERROR(ENOSYS);
|
||||
|
||||
+ /*
|
||||
+ * NV15-backed surfaces (sw_format = YUV420P10) are exposed as P010 to
|
||||
+ * downstream filters: the unpack below converts the packed 10-bit
|
||||
+ * samples into the standard high-bits-of-16 layout. Hi10P / Main10
|
||||
+ * VAAPI/v4l2-request decode reaches userspace through this path.
|
||||
+ */
|
||||
+ if (hwfc->sw_format == AV_PIX_FMT_YUV420P10) {
|
||||
+ fmts = av_malloc_array(2, sizeof(*fmts));
|
||||
+ if (!fmts)
|
||||
+ return AVERROR(ENOMEM);
|
||||
+ fmts[0] = AV_PIX_FMT_P010;
|
||||
+ fmts[1] = AV_PIX_FMT_NONE;
|
||||
+ *formats = fmts;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
fmts = av_malloc_array(2, sizeof(*fmts));
|
||||
if (!fmts)
|
||||
return AVERROR(ENOMEM);
|
||||
@@ -1089,8 +1155,13 @@ static int v4l2request_transfer_get_formats(AVHWFramesContext *hwfc,
|
||||
fmts[0] = hwfc->sw_format;
|
||||
fmts[1] = AV_PIX_FMT_NONE;
|
||||
|
||||
+ /*
|
||||
+ * Tiled-NV12-32L32 (Allwinner) and NV20 (rkvdec 4:2:2 10-bit) still need
|
||||
+ * dedicated unpacks before hwdownload can consume them; leave them as
|
||||
+ * "no transfer formats" so the filter graph reports the limitation
|
||||
+ * rather than silently producing garbage.
|
||||
+ */
|
||||
if (hwfc->sw_format == AV_PIX_FMT_YUV420P ||
|
||||
- hwfc->sw_format == AV_PIX_FMT_YUV420P10 ||
|
||||
hwfc->sw_format == AV_PIX_FMT_YUV422P10)
|
||||
fmts[0] = AV_PIX_FMT_NONE;
|
||||
|
||||
@@ -1110,6 +1181,44 @@ static int v4l2request_transfer_data_from(AVHWFramesContext *hwfc,
|
||||
map = av_frame_alloc();
|
||||
if (!map)
|
||||
return AVERROR(ENOMEM);
|
||||
+
|
||||
+ /*
|
||||
+ * For NV15→P010, map the raw NV15 bytes (sw_format) and unpack into
|
||||
+ * dst's P010 storage. Otherwise fall through to the original byte-copy
|
||||
+ * path used for 1:1 sw_format matches (NV12, NV16, AFBC handled by DRM).
|
||||
+ */
|
||||
+ if (hwfc->sw_format == AV_PIX_FMT_YUV420P10) {
|
||||
+ /*
|
||||
+ * Only P010 is advertised by transfer_get_formats for this sw_format;
|
||||
+ * a caller that bypasses get_formats and asks for anything else would
|
||||
+ * silently corrupt output via av_frame_copy on NV15-packed bytes.
|
||||
+ * Reject explicitly.
|
||||
+ */
|
||||
+ if (dst->format != AV_PIX_FMT_P010) {
|
||||
+ ret = AVERROR(ENOSYS);
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ map->format = hwfc->sw_format;
|
||||
+ ret = v4l2request_map_frame(hwfc, map, src);
|
||||
+ if (ret)
|
||||
+ goto fail;
|
||||
+
|
||||
+ v4l2request_nv15_unpack_plane_to_p010(map->data[0],
|
||||
+ (uint16_t *)dst->data[0],
|
||||
+ dst->width, dst->height,
|
||||
+ map->linesize[0],
|
||||
+ dst->linesize[0]);
|
||||
+ /* NV15 chroma plane is W × H/2 samples (4:2:0, UV interleaved). */
|
||||
+ v4l2request_nv15_unpack_plane_to_p010(map->data[1],
|
||||
+ (uint16_t *)dst->data[1],
|
||||
+ dst->width, dst->height / 2,
|
||||
+ map->linesize[1],
|
||||
+ dst->linesize[1]);
|
||||
+ ret = 0;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
map->format = dst->format;
|
||||
|
||||
ret = v4l2request_map_frame(hwfc, map, src);
|
||||
--
|
||||
2.47.3
|
||||
|
||||
@@ -24,7 +24,7 @@ _srcname=FFmpeg
|
||||
_version='8.1'
|
||||
_commit='b57fbbe50c9b2656fad86a1a7eeabfd2b2a50935' # v4l2-request-n8.1 tip 2026-04-24
|
||||
pkgver=8.1.r123329.b57fbbe
|
||||
pkgrel=4
|
||||
pkgrel=5
|
||||
epoch=2
|
||||
pkgdesc='FFmpeg with V4L2 Request API hwaccel (Rockchip / Allwinner stateless decode)'
|
||||
arch=('aarch64')
|
||||
@@ -78,8 +78,9 @@ provides=(
|
||||
conflicts=(ffmpeg)
|
||||
replaces=(ffmpeg ffmpeg-v4l2-request-git)
|
||||
source=("git+https://github.com/Kwiboo/FFmpeg.git#commit=${_commit}"
|
||||
'0001-libudev-bypass-fallback.patch')
|
||||
sha256sums=('SKIP' 'SKIP')
|
||||
'0001-libudev-bypass-fallback.patch'
|
||||
'0002-nv15-to-p010-unpack.patch')
|
||||
sha256sums=('SKIP' 'SKIP' 'SKIP')
|
||||
|
||||
pkgver() {
|
||||
cd "${_srcname}"
|
||||
@@ -91,6 +92,7 @@ pkgver() {
|
||||
prepare() {
|
||||
cd "${_srcname}"
|
||||
patch -Np1 -i "${srcdir}/0001-libudev-bypass-fallback.patch"
|
||||
patch -Np1 -i "${srcdir}/0002-nv15-to-p010-unpack.patch"
|
||||
}
|
||||
|
||||
build() {
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
pkgname=firefox-fourier
|
||||
pkgver=150.0.1
|
||||
pkgrel=1
|
||||
pkgrel=5
|
||||
pkgdesc='Firefox with V4L2 stateless HW video decode unlocked for mainline Linux Rockchip'
|
||||
arch=('aarch64' 'x86_64')
|
||||
url='https://www.mozilla.org/firefox'
|
||||
@@ -87,8 +87,12 @@ source=(
|
||||
'0002-libwrapper-hwdevice-ctx-create.patch'
|
||||
'0003-ffmpegvideo-v4l2-request-route.patch'
|
||||
'0004-prefs-v4l2-request.patch'
|
||||
'0005-rdd-sandbox-v4l2-media-ctl.patch'
|
||||
# Vendor-default prefs that gate the patched VAAPI path on RK3399 —
|
||||
# widget.dmabuf.force-enabled etc. See marfrit-packages#8 for evidence.
|
||||
'rockchip-fourier-defaults.js'
|
||||
)
|
||||
sha256sums=('SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP')
|
||||
sha256sums=('SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP')
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/firefox-${pkgver}"
|
||||
@@ -103,6 +107,7 @@ prepare() {
|
||||
patch -Np1 -i "${srcdir}/0002-libwrapper-hwdevice-ctx-create.patch"
|
||||
patch -Np1 -i "${srcdir}/0003-ffmpegvideo-v4l2-request-route.patch"
|
||||
patch -Np1 -i "${srcdir}/0004-prefs-v4l2-request.patch"
|
||||
patch -Np1 -i "${srcdir}/0005-rdd-sandbox-v4l2-media-ctl.patch"
|
||||
|
||||
cp "${srcdir}/mozconfig" .mozconfig
|
||||
}
|
||||
@@ -160,4 +165,19 @@ export MOZ_X11_EGL="${MOZ_X11_EGL:-1}"
|
||||
exec /usr/lib/firefox-fourier/firefox-fourier "$@"
|
||||
LAUNCHER
|
||||
chmod 0755 "${pkgdir}/usr/bin/firefox-fourier"
|
||||
|
||||
# Vendor-default prefs (RK3399 HW-decode unlock) — closes #8.
|
||||
# Lower precedence than user prefs / about:config; loaded by Firefox
|
||||
# at startup from the package install dir. The 0004 patch covers
|
||||
# media.ffmpeg.v4l2-request.enabled; this file covers the three
|
||||
# additional prefs that gate the path to the patched code.
|
||||
# Vendor-prefs install path: /usr/lib/firefox-fourier/defaults/preferences/
|
||||
# (Mozilla's canonical scan dir for third-party default-pref drops.) The
|
||||
# browser/defaults/preferences/ alternative looked promising but is NOT a
|
||||
# vendor-prefs scan location in Firefox 150 — empirically confirmed on
|
||||
# fresnel: file shipped there, VAAPI never engaged. Same file under
|
||||
# defaults/preferences/ → MOZ_LOG showed `Requesting pixel format
|
||||
# VAAPI_VLD` + dmabuf surfaces locking end-to-end.
|
||||
install -Dm644 "${srcdir}/rockchip-fourier-defaults.js" \
|
||||
"${pkgdir}/usr/lib/firefox-fourier/defaults/preferences/rockchip-fourier-defaults.js"
|
||||
}
|
||||
|
||||
+295
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+28
@@ -0,0 +1,28 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Alex Hochheiden <ahochheiden@mozilla.com>
|
||||
Date: Wed, 1 Apr 2026 18:11:37 +0000
|
||||
Subject: [PATCH] Bug 2023597 - Use `wasm32-wasip1` target for clang >= 22.1
|
||||
r=firefox-build-system-reviewers,sergesanspaille
|
||||
|
||||
https://github.com/llvm/llvm-project/pull/165345
|
||||
https://releases.llvm.org/22.1.0/tools/clang/docs/ReleaseNotes.html
|
||||
|
||||
Differential Revision: https://phabricator.services.mozilla.com/D291023
|
||||
---
|
||||
build/moz.configure/toolchain.configure | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/build/moz.configure/toolchain.configure b/build/moz.configure/toolchain.configure
|
||||
index a37ed610cc43..c7d0c8bdf75c 100644
|
||||
--- a/build/moz.configure/toolchain.configure
|
||||
+++ b/build/moz.configure/toolchain.configure
|
||||
@@ -695,6 +695,9 @@ def check_compiler(configure_cache, compiler, language, target, android_version)
|
||||
# This makes clang define __ANDROID_API__ and use versioned library
|
||||
# directories from the NDK.
|
||||
toolchain = "%s%d" % (target.toolchain, android_version)
|
||||
+ elif target.kernel == "WASI" and info.type == "clang" and info.version >= Version("22.1"):
|
||||
+ # The wasm32-wasi target was renamed to wasm32-wasip1 in LLVM 22.1.
|
||||
+ toolchain = "wasm32-wasip1"
|
||||
else:
|
||||
toolchain = target.toolchain
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
// firefox-fourier — RK3399 V4L2-stateless HW-decode default prefs.
|
||||
//
|
||||
// The patch series (0001..0004) builds the VAAPI / V4L2-request routing
|
||||
// path through libavcodec, but the resulting code path is gated by three
|
||||
// other prefs that are 'false' upstream because the relevant probes don't
|
||||
// fire on panfrost EGL or trip the Intel-tuned cost heuristic. Without
|
||||
// these, firefox-fourier silently SW-decodes on a fresh profile despite
|
||||
// having all the unlock patches applied.
|
||||
//
|
||||
// Filed via marfrit/marfrit-packages#8 — see that issue for MOZ_LOG
|
||||
// evidence on fresnel (Pinebook Pro / RK3399).
|
||||
//
|
||||
// These are *vendor* defaults: lower precedence than user.js and
|
||||
// about:config user prefs. Power users who want to disable HW decode for
|
||||
// debugging can flip them in user prefs without touching this file.
|
||||
|
||||
pref("widget.dmabuf.force-enabled", true);
|
||||
pref("media.hardware-video-decoding.force-enabled", true);
|
||||
pref("media.ffvpx-hw.enabled", true);
|
||||
@@ -2,7 +2,7 @@
|
||||
# Upstream maintainers: Felix Yan, Antonio Rojas
|
||||
# Contributor: Andrea Scarpino <andrea@archlinux.org>
|
||||
#
|
||||
# kwin-fourier — KWin 6.6.4 with the V4L2-stateless implicit-sync
|
||||
# kwin-fourier — KWin 6.6.5 with the V4L2-stateless implicit-sync
|
||||
# transaction wait bypass. Hypothesis: KWin's
|
||||
# `Transaction::watchDmaBuf` calls DMA_BUF_IOCTL_EXPORT_SYNC_FILE on
|
||||
# every plane of every imported dmabuf and parks the transaction on a
|
||||
@@ -21,9 +21,9 @@
|
||||
# ../chromium-fourier/KWIN_PIVOT.md for the full diagnosis thread.
|
||||
|
||||
pkgname=kwin-fourier
|
||||
pkgver=6.6.4
|
||||
pkgver=6.6.5
|
||||
_dirver=$(echo $pkgver | cut -d. -f1-3)
|
||||
pkgrel=3
|
||||
pkgrel=1
|
||||
_upname=kwin
|
||||
epoch=1
|
||||
arch=(aarch64 x86_64)
|
||||
@@ -103,7 +103,7 @@ conflicts=(kwin)
|
||||
replaces=(kwin)
|
||||
source=(https://download.kde.org/stable/plasma/$_dirver/$_upname-$pkgver.tar.xz{,.sig}
|
||||
0001-transaction-bypass-watchDmaBuf-fence-wait.patch)
|
||||
sha256sums=('3f9439760580a977d018daf4b35b62e5a1700def7b21c8dfbfc789d21378d7ad'
|
||||
sha256sums=('6c187ce7a5506090b438ef900103836fa0537674dde8b31e5b497ef321643cb4'
|
||||
'SKIP'
|
||||
'SKIP')
|
||||
validpgpkeys=('E0A3EB202F8E57528E13E72FD7574483BB57B18D' # Jonathan Esk-Riddell <jr@jriddell.org>
|
||||
|
||||
@@ -6,8 +6,11 @@
|
||||
# tracks the campaign fork's git history directly, so iteration sweeps
|
||||
# (DEBUG removal, follow-up bugfixes) land in a clean linear log.
|
||||
#
|
||||
# Campaign: ~/src/libva-multiplanar/ (eight closed iterations as of
|
||||
# 2026-05-06; iter8 close is the production tip pinned below).
|
||||
# Campaign: ~/src/libva-multiplanar/ (iter8 close 2026-05-06) plus
|
||||
# ~/src/fresnel-fourier/ which carried the fork to iter38b — multi-device
|
||||
# probe so a single libva session serves all 5 codecs (rkvdec H.264 +
|
||||
# HEVC + VP9, hantro MPEG-2 + VP8) plus a bounds-check fix for
|
||||
# MAX_PROFILES. Pinned below.
|
||||
# Fork repo: https://git.reauktion.de/marfrit/libva-v4l2-request-fourier
|
||||
# Bootlin upstream: https://github.com/bootlin/libva-v4l2-request
|
||||
#
|
||||
@@ -20,16 +23,25 @@
|
||||
pkgname=libva-v4l2-request-fourier
|
||||
_upstreampkg=libva-v4l2-request
|
||||
|
||||
# Pin the fork tip. 65969da = "iter8 Phase 4: tests/run_perf_binding_cell.sh"
|
||||
# — last commit on master before fresnel-fourier work started layering
|
||||
# MPEG-2 rewrites on top of it (2026-05-08). The libva-multiplanar campaign
|
||||
# closed iter8 at this commit; promote to a later pin only after a future
|
||||
# iteration closes cleanly.
|
||||
_commit=65969da3ee901442a8ca4e1f7f9697d5461d368a
|
||||
# Pin the fork tip. de27e95 = "v4l2: log error_idx + failing ctrl id
|
||||
# on S_EXT_CTRLS failure" — Phase 8.13 diagnostic that surfaced the
|
||||
# real root cause of the libva→daedalus_v4l2 request-completion
|
||||
# timeout (turned out the EINVAL libva was logging was a harmless
|
||||
# H264/HEVC probe; actual VP9 stateless control SET worked all along).
|
||||
#
|
||||
# Prior pin (7ac934e) was iter38b — fresnel-fourier multi-device probe
|
||||
# + MAX_PROFILES bounds-check fix. de27e95 adds the daedalus_v4l2
|
||||
# probe slot (b5b3acf), the meson option gate (2146341), and the
|
||||
# S_EXT_CTRLS diagnostic (de27e95 itself). Backward-compatible on
|
||||
# rkvdec / hantro / cedrus / rpi-hevc-dec hosts — daedalus probe is
|
||||
# off by default unless the kernel module is present.
|
||||
_commit=de27e95571b67ef34619c23a12db4698f9b3454e
|
||||
|
||||
# Project version from meson.build (1.0.0) + commit count + short sha,
|
||||
# matching the ffmpeg-v4l2-request-fourier convention.
|
||||
pkgver=1.0.0.r280.65969da
|
||||
# matching the ffmpeg-v4l2-request-fourier convention. Recomputed at
|
||||
# build time by pkgver() below; the static value here is a placeholder
|
||||
# so AUR-style consumers see something coherent before src/ exists.
|
||||
pkgver=1.0.0.r376.de27e95
|
||||
pkgrel=1
|
||||
pkgdesc="VA-API backend for V4L2 stateless decoders (multiplanar fork — fourier umbrella)"
|
||||
arch=('aarch64')
|
||||
@@ -55,7 +67,15 @@ build() {
|
||||
cd "${srcdir}/${_upstreampkg}-fourier"
|
||||
# meson_options.txt only exposes 'kernel_headers' — leave it empty to
|
||||
# use system /usr/include kernel UAPI headers. No per-codec toggles.
|
||||
arch-meson build --buildtype=release
|
||||
#
|
||||
# b_lto=false: override arch-meson's wrapper default of `-D b_lto=true`,
|
||||
# which the makepkg.conf OPTIONS=(..., !lto, ...) line does NOT actually
|
||||
# override (arch-meson hard-codes b_lto=true). The hand-built reproducer
|
||||
# from issue #17 shows: LTO/ICF kernel-folds per-codec helpers and HEVC's
|
||||
# multi-control-struct chain (SPS+PPS+DECODE_PARAMS+SLICE_PARAMS) gets a
|
||||
# wrong helper-instance pulled in at vaEndPicture → segfault. The 4 other
|
||||
# codecs (single-control-struct) tolerate the folding by accident.
|
||||
arch-meson build --buildtype=release -Db_lto=false
|
||||
meson compile -C build
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
# Maintainer: Markus Fritsche <fritsche.markus@gmail.com>
|
||||
# Campaign: ohm_gl_fix Phase 6 Step 1
|
||||
#
|
||||
# DEPRECATED (2026-05-16): superseded by ../libva-v4l2-request-fourier/
|
||||
# which tracks the campaign fork's git history directly and adds the
|
||||
# iter38 multi-device probe (single libva session for rkvdec H.264/HEVC/VP9
|
||||
# + hantro MPEG-2/VP8). The successor declares
|
||||
# replaces=('libva-v4l2-request-ohm-gl-fix'), so installing it removes
|
||||
# this package automatically. See README.md for the full deprecation note.
|
||||
#
|
||||
# Forks libva-v4l2-request to add hantro-vpu multiplanar + modern
|
||||
# stateless UAPI support. Conflicts/replaces stock libva-v4l2-request.
|
||||
#
|
||||
@@ -11,7 +18,7 @@ pkgname=libva-v4l2-request-ohm-gl-fix
|
||||
_upstreampkg=libva-v4l2-request
|
||||
pkgver=1.0.0.r0.ga3c2476
|
||||
pkgrel=2
|
||||
pkgdesc="VA-API backend for V4L2 stateless decoders, hantro-vpu multiplanar fork"
|
||||
pkgdesc="DEPRECATED — use libva-v4l2-request-fourier. VA-API backend for V4L2 stateless decoders, hantro-vpu multiplanar fork"
|
||||
arch=('aarch64')
|
||||
url="https://github.com/bootlin/libva-v4l2-request"
|
||||
license=('LGPL2.1' 'MIT')
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
# libva-v4l2-request-ohm-gl-fix
|
||||
|
||||
> ## ⚠ DEPRECATED — use [`libva-v4l2-request-fourier`](../libva-v4l2-request-fourier/) instead
|
||||
>
|
||||
> This package is the **predecessor experimental** build (tarball pin
|
||||
> + 18 stacked patches) and is no longer maintained as of 2026-05-16.
|
||||
> Its successor `libva-v4l2-request-fourier` tracks the campaign fork's
|
||||
> git history directly
|
||||
> ([git.reauktion.de/marfrit/libva-v4l2-request-fourier](https://git.reauktion.de/marfrit/libva-v4l2-request-fourier))
|
||||
> so iteration sweeps (DEBUG removal, follow-up bugfixes) land in a clean
|
||||
> linear log, and adds the iter38 multi-device probe that lets a single
|
||||
> libva session serve rkvdec H.264/HEVC/VP9 + hantro MPEG-2/VP8 without
|
||||
> needing `LIBVA_V4L2_REQUEST_VIDEO_PATH` overrides.
|
||||
>
|
||||
> `libva-v4l2-request-fourier` declares
|
||||
> `replaces=('libva-v4l2-request-ohm-gl-fix')`, so installing it will
|
||||
> remove this package automatically. Kept in-tree as historical reference
|
||||
> for the ohm_gl_fix Phase 6 audit trail.
|
||||
|
||||
---
|
||||
|
||||
Bootlin's libva-v4l2-request VA-API backend, with hantro-vpu
|
||||
multi-planar + chromium-149-era stateless H.264 patches developed
|
||||
in the [ohm_gl_fix campaign](../../../ohm_gl_fix/) Phase 6 Step 1
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
# Maintainer: Markus Fritsche <mfritsche@reauktion.de>
|
||||
#
|
||||
# linux-ampere-fourier — CoolPi GenBook (RK3588) kernel built from the
|
||||
# kernel-agent fleet/ampere.yaml manifest applied to mainline v7.0-rc3.
|
||||
#
|
||||
# kafr2 baseline (2026-05-18): mainline v7.0-rc3 + the 10 scope-tagged
|
||||
# kernel-agent patches under patches/{soc,module,board,driver}/:
|
||||
# - 1 soc/rk3588 pwm15 pinctrl
|
||||
# - 6 board/coolpi-cm5-genbook DTS patches (pwm-fan, RK806 power-off,
|
||||
# speaker, USB-C PD, lid switch + USB3 PHY, microphone)
|
||||
# - 3 driver/media VP9-on-VDPU381 patches (Sarma's v8 series, imported
|
||||
# via marfrit/kernel-agent#12 closure and PR #24)
|
||||
#
|
||||
# Drops the prior f8f3ad9 baseline ("18 commits ahead") because that tip
|
||||
# black-screens ampere — kernel-agent's ka-promote produces this 10-patch
|
||||
# minimal set from fleet/ampere.yaml. End-to-end VP9 + AV1 (av1-vpu-dec
|
||||
# is mainline-7.0) decode verified bit-exact via kdirect on the
|
||||
# hand-built tip 48a8c78 before this package iteration was cut.
|
||||
#
|
||||
# Coexists with the user's other extlinux labels in
|
||||
# /boot/firmware/extlinux/extlinux.conf; never edits them. Adds a
|
||||
# managed `linux-ampere-fourier` label (the user sets `default` manually
|
||||
# after verifying boot).
|
||||
#
|
||||
# Bootloader path: /boot/firmware/ (vfat on mmcblk0p1). Kernel +
|
||||
# initramfs + DTB land there directly. Reverting = boot a different
|
||||
# extlinux label (e.g. arch_mainline, ubuntu_mainline).
|
||||
|
||||
pkgbase=linux-ampere-fourier
|
||||
pkgname=("$pkgbase" "$pkgbase-headers")
|
||||
pkgver=7.0rc3.kafr2
|
||||
pkgrel=1
|
||||
pkgdesc='CoolPi GenBook kernel (v7.0-rc3 + kernel-agent fleet/ampere.yaml — 6 board patches + 3 VP9-VDPU381 + 1 pwm15)'
|
||||
arch=(aarch64)
|
||||
url='https://git.reauktion.de/marfrit/kernel-agent'
|
||||
license=(GPL-2.0-only)
|
||||
makedepends=(
|
||||
bc cpio gettext kmod libelf pahole perl python tar xz
|
||||
ccache
|
||||
uboot-tools dtc
|
||||
)
|
||||
options=('!strip')
|
||||
|
||||
# Pinned tip of the kernel-agent-managed source tree for ampere.
|
||||
# 10 commits ahead of v7.0-rc3, exactly mirroring fleet/ampere.yaml's
|
||||
# manifest under apply order:
|
||||
# - c57d069 soc/rk3588: pwm15 pinctrl entries
|
||||
# - 05a915c board/genbook: pwm-fan with thermal cooling
|
||||
# - d007b90 module/coolpi-cm5: RK806 system-power-controller
|
||||
# - 3722eab board/genbook: speaker via audio-graph-card
|
||||
# - 3e42ab6 board/genbook: USB-C PD via FUSB302
|
||||
# - 7c241f2 board/genbook: lid switch + USB3 PHY lane
|
||||
# - dd545fa board/genbook: wire internal microphone
|
||||
# - 9ddcae5 driver/media: rkvdec-vp9 helper rename (Sarma)
|
||||
# - c5063d9 driver/media: rkvdec move vp9 to common (Sarma)
|
||||
# - 48a8c78 driver/media: rkvdec VP9 for VDPU381 (Sarma)
|
||||
#
|
||||
# This is the same tree state ka-promote ampere produces as cumulative.patch
|
||||
# (see marfrit/kernel-agent build/ampere/v7.0-rc3/manifest.lock for the
|
||||
# b2sum + per-patch sha256s).
|
||||
_commit=48a8c785de7f5320513052a64e544c6310d7b273
|
||||
|
||||
source=(
|
||||
# Local tarball produced by ./prebuild.sh from a local clone of the
|
||||
# linux-rk3588-marfrit branch. Not fetched from a URL because the
|
||||
# boltzmann working clone is shallow (gitea push rejects) and the
|
||||
# 260MB tarball isn't committed to marfrit-packages. Run prebuild.sh
|
||||
# before makepkg; see README in this dir.
|
||||
"linux-rk3588-marfrit-${_commit:0:7}.tar.gz"
|
||||
'config' # snapshot of running ampere kernel's /proc/config.gz (7.0.0-rc3-ARCH+)
|
||||
'linux-ampere-fourier.preset'
|
||||
'extlinux-add.hook'
|
||||
'extlinux-add.sh'
|
||||
)
|
||||
sha256sums=('SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP')
|
||||
|
||||
# kernelrelease becomes <Makefile-VERSION>.<PATCH>.<SUBLEVEL><EXTRAVERSION><LOCALVERSION>
|
||||
# i.e. 7.0.0-rc3-ampere-fourier. Module dir + EXTRAVERSION suffix keep
|
||||
# this disjoint from the hand-managed /boot/firmware/Image-7.0.0-rc3-ARCH+
|
||||
# that's currently on the host.
|
||||
_kernver=7.0.0-rc3-ampere-fourier
|
||||
_srcdir=linux-rk3588-marfrit
|
||||
|
||||
prepare() {
|
||||
cd "${_srcdir}"
|
||||
|
||||
echo ":: writing config"
|
||||
cp "${srcdir}/config" .config
|
||||
|
||||
# LOCALVERSION suffix to differentiate from upstream-stock builds.
|
||||
scripts/config --set-str LOCALVERSION "-ampere-fourier"
|
||||
scripts/config -d LOCALVERSION_AUTO
|
||||
|
||||
echo ":: olddefconfig (accept new symbols sensibly)"
|
||||
make olddefconfig
|
||||
|
||||
make -s kernelrelease > version
|
||||
echo ":: kernel release: $(<version)"
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${_srcdir}"
|
||||
unset LDFLAGS
|
||||
# Native build only — no distcc per kernel-agent policy
|
||||
# (feedback_kernel_agent_no_distcc.md). ccache stays.
|
||||
export CC="ccache gcc"
|
||||
export HOSTCC="ccache gcc"
|
||||
make ${MAKEFLAGS:--j$(nproc)} Image modules dtbs
|
||||
}
|
||||
|
||||
_package() {
|
||||
pkgdesc='CoolPi GenBook overclocked kernel (ampere-fourier baseline)'
|
||||
depends=(coreutils kmod mkinitcpio uboot-tools)
|
||||
optdepends=('linux-firmware: firmware images needed for some devices')
|
||||
backup=("etc/mkinitcpio.d/${pkgbase}.preset")
|
||||
|
||||
cd "${_srcdir}"
|
||||
local _kver
|
||||
_kver=$(<version)
|
||||
|
||||
# Kernel image into the vfat firmware partition (where extlinux looks).
|
||||
install -Dm644 arch/arm64/boot/Image \
|
||||
"${pkgdir}/boot/firmware/Image-ampere-fourier"
|
||||
|
||||
# Single DTB for the GenBook target — install directly under
|
||||
# /boot/firmware/ (no subdir, matches existing host convention).
|
||||
install -Dm644 arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dtb \
|
||||
"${pkgdir}/boot/firmware/rk3588-coolpi-cm5-genbook.dtb-ampere-fourier"
|
||||
|
||||
ZSTD_CLEVEL=19 make INSTALL_MOD_PATH="${pkgdir}/usr" \
|
||||
INSTALL_MOD_STRIP=1 modules_install
|
||||
rm -f "${pkgdir}/usr/lib/modules/${_kver}/"{source,build}
|
||||
|
||||
install -Dm644 "${srcdir}/${pkgbase}.preset" \
|
||||
"${pkgdir}/etc/mkinitcpio.d/${pkgbase}.preset"
|
||||
|
||||
install -Dm755 "${srcdir}/extlinux-add.hook" \
|
||||
"${pkgdir}/usr/share/libalpm/hooks/95-${pkgbase}-extlinux.hook"
|
||||
install -Dm755 "${srcdir}/extlinux-add.sh" \
|
||||
"${pkgdir}/usr/share/libalpm/scripts/${pkgbase}-extlinux"
|
||||
}
|
||||
|
||||
_package-headers() {
|
||||
pkgdesc='Headers and scripts for the linux-ampere-fourier kernel'
|
||||
depends=(pahole)
|
||||
|
||||
cd "${_srcdir}"
|
||||
local _kver _builddir
|
||||
_kver=$(<version)
|
||||
_builddir="${pkgdir}/usr/lib/modules/${_kver}/build"
|
||||
|
||||
install -Dt "${_builddir}" -m644 .config Makefile Module.symvers System.map vmlinux version
|
||||
install -Dt "${_builddir}/kernel" -m644 kernel/Makefile
|
||||
|
||||
cp -a scripts "${_builddir}"
|
||||
install -Dt "${_builddir}/arch/arm64" -m644 arch/arm64/Makefile
|
||||
cp -a arch/arm64/include "${_builddir}/arch/arm64/"
|
||||
cp -a include "${_builddir}/"
|
||||
|
||||
find . -name 'Kbuild' -exec install -Dm644 {} "${_builddir}/{}" \;
|
||||
find . -name 'Kconfig*' -exec install -Dm644 {} "${_builddir}/{}" \;
|
||||
|
||||
install -d "${pkgdir}/usr/src"
|
||||
ln -sr "${_builddir}" "${pkgdir}/usr/src/${pkgbase}"
|
||||
}
|
||||
|
||||
eval "package_${pkgbase}() { _package; }"
|
||||
eval "package_${pkgbase}-headers() { _package-headers; }"
|
||||
@@ -0,0 +1,70 @@
|
||||
# linux-ampere-fourier
|
||||
|
||||
Kernel package for ampere (CoolPi GenBook RK3588). Baselined on
|
||||
`marfrit/linux-rk3588-marfrit @ f8f3ad9` (mainline v7.0-rc3 + 18
|
||||
RK3588-fleet-relevant commits — 10 Markus, 8 upstream cherry-picks).
|
||||
|
||||
See `marfrit/kernel-agent/fleet/ampere.yaml` for the manifest +
|
||||
`marfrit/kernel-agent/patches/{soc,module,board}/...` for the
|
||||
scope-tagged board patches in the baseline.
|
||||
|
||||
## Build
|
||||
|
||||
The kernel source isn't on Gitea — boltzmann's working clone is
|
||||
shallow (Gitea refuses shallow pushes) and a 260MB tarball doesn't
|
||||
belong in `marfrit-packages`. Stage the source locally from a
|
||||
clone of the `linux-rk3588-marfrit` branch:
|
||||
|
||||
```sh
|
||||
cd arch/linux-ampere-fourier
|
||||
./prebuild.sh # produces linux-rk3588-marfrit-f8f3ad9.tar.gz
|
||||
makepkg -s --noconfirm # native aarch64 build; no distcc
|
||||
```
|
||||
|
||||
`prebuild.sh` looks at `$LINUX_RK3588_MARFRIT_TREE` (default
|
||||
`~/src/linux-rockchip`) for the kernel working tree. The tip commit
|
||||
must be reachable in that clone — fetch the `linux-rk3588-marfrit`
|
||||
branch first if you cloned from elsewhere.
|
||||
|
||||
## Build hosts
|
||||
|
||||
Native aarch64 only (per kernel-agent `feedback_kernel_agent_no_distcc.md`).
|
||||
Either ampere itself (8C/2.4GHz, 32GB, native arch) or boltzmann
|
||||
(Rock 5 ITX+, same uarch). fermi as fallback.
|
||||
|
||||
## Install
|
||||
|
||||
Adds a managed label to `/boot/firmware/extlinux/extlinux.conf`:
|
||||
|
||||
```
|
||||
label linux-ampere-fourier
|
||||
menu label linux-ampere-fourier (managed)
|
||||
kernel /Image-ampere-fourier
|
||||
initrd /initramfs-ampere-fourier.img
|
||||
fdt /rk3588-coolpi-cm5-genbook.dtb-ampere-fourier
|
||||
append <inherited from arch_mainline>
|
||||
```
|
||||
|
||||
Default label is NOT changed. After verifying boot of the managed
|
||||
label at the u-boot menu, you flip `default` manually. Reverting =
|
||||
boot a different label (e.g. `arch_mainline`, `ubuntu_mainline`).
|
||||
|
||||
## Boot path
|
||||
|
||||
ampere uses `/boot/firmware/` (vfat on mmcblk0p1, ~1G), distinct
|
||||
from fresnel's `/boot/` on root partition. The PKGBUILD installs
|
||||
Image, initramfs, and DTB directly under `/boot/firmware/`. No
|
||||
DTB subdir — single board target.
|
||||
|
||||
## Open follow-ups (per kernel-agent issue #6)
|
||||
|
||||
- **Ask 2** (VP9 enablement on RK3588 rkvdec) — not addressed in this
|
||||
iteration. Separate session.
|
||||
- **Ask 3** (AV1 decoder integration) — backend libva work, not kernel.
|
||||
- Hosting the source tarball publicly so `prebuild.sh` isn't needed —
|
||||
candidate: Gitea release asset, or `packages.reauktion.de/sources/`.
|
||||
- Splitting the 12 non-board cherry-pick commits in the baseline
|
||||
(4 Shawn Lin phy, 2 Cristian Ciocaltea, etc.) into scope-tagged
|
||||
patches in kernel-agent — currently they ride along inside the
|
||||
pinned baseline rather than being explicit `includes:` in the
|
||||
manifest.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
[Trigger]
|
||||
Operation = Install
|
||||
Operation = Upgrade
|
||||
Operation = Remove
|
||||
Type = Path
|
||||
Target = boot/firmware/Image-ampere-fourier
|
||||
Target = boot/firmware/rk3588-coolpi-cm5-genbook.dtb-ampere-fourier
|
||||
Target = boot/firmware/initramfs-ampere-fourier.img
|
||||
|
||||
[Action]
|
||||
Description = Updating extlinux entry for linux-ampere-fourier
|
||||
When = PostTransaction
|
||||
Exec = /usr/share/libalpm/scripts/linux-ampere-fourier-extlinux
|
||||
@@ -0,0 +1,62 @@
|
||||
#!/bin/sh
|
||||
# Add / update / remove the linux-ampere-fourier entry in
|
||||
# /boot/firmware/extlinux/extlinux.conf. Idempotent. Coexists with
|
||||
# the hand-managed labels in that file; never edits them. Default
|
||||
# label is NOT touched — user picks at u-boot menu.
|
||||
#
|
||||
# ampere boots from a vfat partition (mmcblk0p1) mounted at
|
||||
# /boot/firmware/, distinct from fresnel's /boot/ on root.
|
||||
|
||||
set -eu
|
||||
|
||||
CONF="/boot/firmware/extlinux/extlinux.conf"
|
||||
TAG_BEGIN="# >>> linux-ampere-fourier (managed) >>>"
|
||||
TAG_END="# <<< linux-ampere-fourier (managed) <<<"
|
||||
|
||||
# Copy APPEND from the user's `arch_mainline` label so the managed
|
||||
# entry inherits the same root= and console= settings the host's
|
||||
# bootloader already trusts. Falls back to a CoolPi GenBook default
|
||||
# if no arch_mainline label exists (first-time install on a fresh
|
||||
# bootloader config).
|
||||
EXISTING_APPEND=$(awk '
|
||||
/^[[:space:]]*label[[:space:]]+arch_mainline[[:space:]]*$/ { found=1; next }
|
||||
found && /^[[:space:]]*append[[:space:]]/ {
|
||||
sub(/^[[:space:]]*append[[:space:]]+/, "")
|
||||
print
|
||||
exit
|
||||
}
|
||||
/^[[:space:]]*label[[:space:]]/ { found=0 }
|
||||
' "$CONF" 2>/dev/null || true)
|
||||
|
||||
APPEND="${EXISTING_APPEND:-root=LABEL=arch rw rootwait rootfstype=btrfs rootflags=subvol=@,ssd,discard=async console=ttyS2,1500000 console=tty1 consoleblank=0 loglevel=7 cma=256M coherent_pool=2M}"
|
||||
|
||||
ENTRY=$(cat <<EOF
|
||||
${TAG_BEGIN}
|
||||
label linux-ampere-fourier
|
||||
menu label linux-ampere-fourier (managed)
|
||||
kernel /Image-ampere-fourier
|
||||
initrd /initramfs-ampere-fourier.img
|
||||
fdt /rk3588-coolpi-cm5-genbook.dtb-ampere-fourier
|
||||
append ${APPEND}
|
||||
${TAG_END}
|
||||
EOF
|
||||
)
|
||||
|
||||
# Strip any prior managed block, then append fresh
|
||||
TMP=$(mktemp)
|
||||
awk -v b="$TAG_BEGIN" -v e="$TAG_END" '
|
||||
$0==b{skip=1; next}
|
||||
$0==e{skip=0; next}
|
||||
!skip{print}
|
||||
' "$CONF" > "$TMP"
|
||||
|
||||
# Post-Remove: kernel files absent → don't re-add the entry
|
||||
if [ -f "/boot/firmware/Image-ampere-fourier" ] \
|
||||
&& [ -f "/boot/firmware/rk3588-coolpi-cm5-genbook.dtb-ampere-fourier" ]; then
|
||||
printf '%s\n' "$ENTRY" >> "$TMP"
|
||||
echo "linux-ampere-fourier: extlinux entry updated"
|
||||
else
|
||||
echo "linux-ampere-fourier: kernel files absent, entry removed"
|
||||
fi
|
||||
|
||||
mv "$TMP" "$CONF"
|
||||
@@ -0,0 +1,13 @@
|
||||
# mkinitcpio preset for linux-ampere-fourier
|
||||
#
|
||||
# ampere boots from /boot/firmware/ (vfat partition on mmcblk0p1). The
|
||||
# initramfs lands there too so extlinux can pick it up. Only one PRESET
|
||||
# because /boot/firmware is ~1G total — no room for a fallback image
|
||||
# alongside the primary.
|
||||
|
||||
ALL_kver="/boot/firmware/Image-ampere-fourier"
|
||||
ALL_microcode=()
|
||||
|
||||
PRESETS=('default')
|
||||
|
||||
default_image="/boot/firmware/initramfs-ampere-fourier.img"
|
||||
Executable
+68
@@ -0,0 +1,68 @@
|
||||
#!/bin/bash
|
||||
# prebuild — stage the kernel source tarball this PKGBUILD expects.
|
||||
#
|
||||
# linux-ampere-fourier's source is a snapshot of marfrit/linux-rk3588-marfrit
|
||||
# @ f8f3ad9 (260MB), too big to commit to marfrit-packages and currently
|
||||
# unpushable to Gitea (boltzmann's working clone is shallow; gitea push
|
||||
# refuses shallow updates). Hosting the tarball outside Gitea would need
|
||||
# infrastructure setup that's not in scope for the first iteration.
|
||||
#
|
||||
# So: produce the tarball locally from the kernel working tree just
|
||||
# before makepkg runs. Idempotent — if an existing tarball matches the
|
||||
# expected sha256 we skip the archive step.
|
||||
#
|
||||
# Run from this directory: cd arch/linux-ampere-fourier && ./prebuild.sh
|
||||
# Override the kernel-tree location: LINUX_RK3588_MARFRIT_TREE=/path ./prebuild.sh
|
||||
#
|
||||
# Default tree location matches the boltzmann/ampere convention from
|
||||
# kernel-agent issue #6: $HOME/src/linux-rockchip.
|
||||
set -euo pipefail
|
||||
|
||||
TREE="${LINUX_RK3588_MARFRIT_TREE:-${HOME}/src/linux-rockchip}"
|
||||
COMMIT=48a8c785de7f5320513052a64e544c6310d7b273
|
||||
# Generated tarball sha varies with gzip version — script warns-not-fails.
|
||||
# Leave EXPECTED empty for fresh kafr2 builds; first successful build can
|
||||
# pin a canonical sha here if a reproducibility audit needs it.
|
||||
SHA256_EXPECTED=
|
||||
|
||||
HERE="$(cd "$(dirname "$0")" && pwd)"
|
||||
OUTPUT="${HERE}/linux-rk3588-marfrit-${COMMIT:0:7}.tar.gz"
|
||||
|
||||
if [ -f "$OUTPUT" ]; then
|
||||
have=$(sha256sum "$OUTPUT" | cut -d' ' -f1)
|
||||
if [ "$have" = "$SHA256_EXPECTED" ]; then
|
||||
echo "prebuild: $OUTPUT already exists with correct sha256"
|
||||
exit 0
|
||||
else
|
||||
echo "prebuild: existing $OUTPUT sha mismatch (have=$have, want=$SHA256_EXPECTED) — regenerating" >&2
|
||||
rm -f "$OUTPUT"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -d "$TREE/.git" ]; then
|
||||
echo "prebuild: kernel tree not at $TREE" >&2
|
||||
echo " set LINUX_RK3588_MARFRIT_TREE=/path/to/linux-rockchip and retry" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
cd "$TREE"
|
||||
|
||||
if ! git cat-file -e "$COMMIT" 2>/dev/null; then
|
||||
echo "prebuild: commit $COMMIT not found in $TREE" >&2
|
||||
echo " fetch the linux-rk3588-marfrit branch first:" >&2
|
||||
echo " git fetch <remote> linux-rk3588-marfrit" >&2
|
||||
exit 3
|
||||
fi
|
||||
|
||||
echo "prebuild: generating archive from $TREE @ $COMMIT..."
|
||||
git archive --format=tar.gz --prefix=linux-rk3588-marfrit/ "$COMMIT" -o "$OUTPUT"
|
||||
|
||||
# git archive emits a deterministic tar stream but gzip compression may
|
||||
# vary by version. The sha256 check is informational; warn-don't-fail.
|
||||
have=$(sha256sum "$OUTPUT" | cut -d' ' -f1)
|
||||
if [ "$have" != "$SHA256_EXPECTED" ]; then
|
||||
echo "prebuild: WARNING $OUTPUT sha=$have (canonical=$SHA256_EXPECTED)" >&2
|
||||
echo " probably a gzip-version difference; tar payload should be identical" >&2
|
||||
fi
|
||||
|
||||
echo "prebuild: wrote $OUTPUT ($(du -h "$OUTPUT" | cut -f1), sha=$have)"
|
||||
+356
@@ -0,0 +1,356 @@
|
||||
From a202de1646d4c8f8ee2ebc2e4c100b621975754a Mon Sep 17 00:00:00 2001
|
||||
In-Reply-To: <20260429195306.239666-1-mfritsche@reauktion.de>
|
||||
References: <20260429195306.239666-1-mfritsche@reauktion.de>
|
||||
From: Markus Fritsche <mfritsche@reauktion.de>
|
||||
Date: Sat, 9 May 2026 16:16:07 +0200
|
||||
Subject: [PATCH RFC v2] media: videobuf2: add opt-in dma_resv producer fence
|
||||
helper
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
V4L2 producers historically don't propagate buffer-state-done into
|
||||
the dmabuf's dma_resv exclusive fence. Userspace consumers that
|
||||
import V4L2-produced dmabufs and wait on the dmabuf's implicit-sync
|
||||
fence (poll(POLLIN), DMA_BUF_IOCTL_EXPORT_SYNC_FILE,
|
||||
EGL_LINUX_DMA_BUF_EXT) currently see either zero fences or a stub
|
||||
fence from dma_fence_get_stub(). This is correct by accident for the
|
||||
common DQBUF-then-import case but represents a contract gap that
|
||||
breaks Wayland compositors importing CAPTURE buffers from a stateless
|
||||
H.264 decoder under continuous playback on implicit-sync GPU stacks
|
||||
(observed on RK3566 + hantro VPU + Mali-G52 panfrost; manifests as
|
||||
green frames -- BT.709 limited-range YUV(0,0,0) -> RGB(0,77,0) -- when
|
||||
the GPU samples the dmabuf before the producer's decode completes).
|
||||
|
||||
Add an opt-in API gated by both a per-driver runtime flag
|
||||
(vb2_queue::supports_release_fences) and a Kconfig
|
||||
(CONFIG_VIDEOBUF2_RELEASE_FENCES, default n) that lets producers
|
||||
populate a real dma_resv exclusive write fence on the dmabufs they
|
||||
export. Drivers call vb2_buffer_attach_release_fence(vb) at a
|
||||
finite-time-fenced point in their pipeline (typically m2m
|
||||
device_run, just before the HW kick); vb2_buffer_done() signals and
|
||||
puts the fence as part of its state transition.
|
||||
|
||||
The publish and signal paths are wrapped in
|
||||
dma_fence_begin_signalling() / dma_fence_end_signalling() so
|
||||
PROVE_LOCKING can validate that nothing taken in those critical
|
||||
sections deadlocks against the signal path. dma_resv_lock is
|
||||
sleepable but not taken on the signal path, so taking it inside the
|
||||
publish critical section is safe under lockdep.
|
||||
|
||||
Skips planes whose vb2_plane.dbuf is NULL -- buffers never exported
|
||||
via VIDIOC_EXPBUF (or imported via V4L2_MEMORY_DMABUF) have no
|
||||
dmabuf for userspace to wait on.
|
||||
|
||||
Drivers that don't opt in pay nothing: the helper is a no-op stub
|
||||
when CONFIG_VIDEOBUF2_RELEASE_FENCES=n, and an early-return check
|
||||
of supports_release_fences when =y but the flag is unset.
|
||||
|
||||
Validated on RK3566 PineTab2 with PROVE_LOCKING enabled: 30s of
|
||||
bbb_1080p30 H.264 stateless decode + zero-copy panfrost EGL import
|
||||
via dmabuf-wayland (mpv 0.41 + KWin 6.6.4 + Mesa panfrost 26.0.5)
|
||||
produces 31,816 dma_fence init/signal pairs across 5,724 vb2 buffer
|
||||
cycles with zero lockdep splats from videobuf2 / dma_resv code paths.
|
||||
|
||||
Subsequent patches in this series opt the hantro and rockchip-rga
|
||||
drivers in.
|
||||
|
||||
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
|
||||
Cc: Christian König <christian.koenig@amd.com>
|
||||
Cc: Nicolas Dufresne <nicolas@ndufresne.ca>
|
||||
Cc: Sumit Semwal <sumit.semwal@linaro.org>
|
||||
Cc: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
Cc: Tomasz Figa <tfiga@chromium.org>
|
||||
Cc: linux-media@vger.kernel.org
|
||||
Cc: dri-devel@lists.freedesktop.org
|
||||
Cc: linaro-mm-sig@lists.linaro.org
|
||||
Signed-off-by: Markus Fritsche <mfritsche@reauktion.de>
|
||||
---
|
||||
drivers/media/common/videobuf2/Kconfig | 29 ++++
|
||||
.../media/common/videobuf2/videobuf2-core.c | 135 ++++++++++++++++++
|
||||
include/media/videobuf2-core.h | 51 +++++++
|
||||
3 files changed, 215 insertions(+)
|
||||
|
||||
diff --git a/drivers/media/common/videobuf2/Kconfig b/drivers/media/common/videobuf2/Kconfig
|
||||
index d2223a12c..bbfa26984 100644
|
||||
--- a/drivers/media/common/videobuf2/Kconfig
|
||||
+++ b/drivers/media/common/videobuf2/Kconfig
|
||||
@@ -30,3 +30,32 @@ config VIDEOBUF2_DMA_SG
|
||||
config VIDEOBUF2_DVB
|
||||
tristate
|
||||
select VIDEOBUF2_CORE
|
||||
+
|
||||
+config VIDEOBUF2_RELEASE_FENCES
|
||||
+ bool "videobuf2: opt-in dma_resv producer fences for V4L2 dmabuf exports"
|
||||
+ depends on VIDEOBUF2_CORE
|
||||
+ depends on DMA_SHARED_BUFFER
|
||||
+ default n
|
||||
+ help
|
||||
+ Enables an opt-in API that lets vb2 producers populate a dma_resv
|
||||
+ exclusive write fence on the dmabufs they export to userspace.
|
||||
+ The fence is signalled when the buffer transitions to
|
||||
+ VB2_BUF_STATE_DONE.
|
||||
+
|
||||
+ This gives userspace consumers that import V4L2-produced dmabufs
|
||||
+ and wait on the dmabuf's implicit-sync fence (poll(POLLIN),
|
||||
+ DMA_BUF_IOCTL_EXPORT_SYNC_FILE, EGL_LINUX_DMA_BUF_EXT) a real
|
||||
+ producer fence to wait on, instead of a stub fence from
|
||||
+ dma_fence_get_stub() that the dma_buf core substitutes when
|
||||
+ dma_resv is empty.
|
||||
+
|
||||
+ Drivers individually opt in by setting
|
||||
+ vb2_queue::supports_release_fences = true and calling
|
||||
+ vb2_buffer_attach_release_fence() at the right point in their
|
||||
+ pipeline (typically m2m device_run, just before HW kick).
|
||||
+
|
||||
+ Distributors leave this off unless targeting Wayland/EGL
|
||||
+ consumers of V4L2 stateless decoder output on
|
||||
+ implicit-sync-only GPU stacks (e.g. mainline panfrost).
|
||||
+
|
||||
+ If unsure, say N.
|
||||
diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c
|
||||
index adf668b21..85d7fddbd 100644
|
||||
--- a/drivers/media/common/videobuf2/videobuf2-core.c
|
||||
+++ b/drivers/media/common/videobuf2/videobuf2-core.c
|
||||
@@ -26,6 +26,12 @@
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/kthread.h>
|
||||
|
||||
+#ifdef CONFIG_VIDEOBUF2_RELEASE_FENCES
|
||||
+#include <linux/dma-fence.h>
|
||||
+#include <linux/dma-resv.h>
|
||||
+#include <linux/dma-buf.h>
|
||||
+#endif
|
||||
+
|
||||
#include <media/videobuf2-core.h>
|
||||
#include <media/v4l2-mc.h>
|
||||
|
||||
@@ -1173,6 +1179,120 @@ void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vb2_plane_cookie);
|
||||
|
||||
+#ifdef CONFIG_VIDEOBUF2_RELEASE_FENCES
|
||||
+/*
|
||||
+ * dma_resv release-fence integration.
|
||||
+ *
|
||||
+ * Optional, opt-in path that lets producers publish a real
|
||||
+ * dma_fence on their CAPTURE-side dmabufs so userspace consumers
|
||||
+ * (compositors, EGL importers) get spec-clean implicit-sync
|
||||
+ * semantics instead of the dma_buf core's stub fence. Drivers
|
||||
+ * call vb2_buffer_attach_release_fence() at a finite-time-fenced
|
||||
+ * point (typically m2m device_run) and the fence is signalled by
|
||||
+ * vb2_buffer_done(). Gated at runtime by
|
||||
+ * vb2_queue::supports_release_fences and at compile time by
|
||||
+ * CONFIG_VIDEOBUF2_RELEASE_FENCES.
|
||||
+ */
|
||||
+
|
||||
+static const char *vb2_dma_resv_get_driver_name(struct dma_fence *fence)
|
||||
+{
|
||||
+ return "videobuf2";
|
||||
+}
|
||||
+
|
||||
+static const char *vb2_dma_resv_get_timeline_name(struct dma_fence *fence)
|
||||
+{
|
||||
+ return "vb2-release-fence";
|
||||
+}
|
||||
+
|
||||
+static const struct dma_fence_ops vb2_dma_resv_fence_ops = {
|
||||
+ .get_driver_name = vb2_dma_resv_get_driver_name,
|
||||
+ .get_timeline_name = vb2_dma_resv_get_timeline_name,
|
||||
+};
|
||||
+
|
||||
+int vb2_buffer_attach_release_fence(struct vb2_buffer *vb)
|
||||
+{
|
||||
+ struct vb2_queue *q = vb->vb2_queue;
|
||||
+ struct dma_fence *fence;
|
||||
+ unsigned int plane;
|
||||
+ bool cookie;
|
||||
+
|
||||
+ if (!q->supports_release_fences)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (WARN_ON(vb->release_fence))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ fence = kzalloc(sizeof(*fence), GFP_KERNEL);
|
||||
+ if (!fence)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ dma_fence_init(fence, &vb2_dma_resv_fence_ops, &q->dma_resv_fence_lock,
|
||||
+ q->dma_resv_fence_context,
|
||||
+ atomic64_inc_return(&q->dma_resv_fence_seqno));
|
||||
+
|
||||
+ /*
|
||||
+ * Annotate the publish-side critical section. Per
|
||||
+ * Documentation/driver-api/dma-buf.rst, lockdep validates
|
||||
+ * that nothing taken in this region can deadlock against
|
||||
+ * the signal path in vb2_buffer_signal_release_fence().
|
||||
+ * dma_resv_lock is sleepable but is not taken on the signal
|
||||
+ * path, so taking it inside the critical section is safe.
|
||||
+ */
|
||||
+ cookie = dma_fence_begin_signalling();
|
||||
+ for (plane = 0; plane < vb->num_planes; plane++) {
|
||||
+ struct dma_buf *dbuf = vb->planes[plane].dbuf;
|
||||
+
|
||||
+ if (!dbuf)
|
||||
+ continue;
|
||||
+
|
||||
+ dma_resv_lock(dbuf->resv, NULL);
|
||||
+ dma_resv_add_fence(dbuf->resv, fence, DMA_RESV_USAGE_WRITE);
|
||||
+ dma_resv_unlock(dbuf->resv);
|
||||
+ }
|
||||
+ dma_fence_end_signalling(cookie);
|
||||
+
|
||||
+ /* One reference for the eventual signal in vb2_buffer_done. */
|
||||
+ vb->release_fence = dma_fence_get(fence);
|
||||
+
|
||||
+ /* The dma_resv held its own reference per plane. Drop ours. */
|
||||
+ dma_fence_put(fence);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(vb2_buffer_attach_release_fence);
|
||||
+
|
||||
+static void vb2_buffer_signal_release_fence(struct vb2_buffer *vb,
|
||||
+ enum vb2_buffer_state state)
|
||||
+{
|
||||
+ struct dma_fence *fence = vb->release_fence;
|
||||
+ bool cookie;
|
||||
+
|
||||
+ if (!fence)
|
||||
+ return;
|
||||
+
|
||||
+ cookie = dma_fence_begin_signalling();
|
||||
+ if (state == VB2_BUF_STATE_ERROR)
|
||||
+ dma_fence_set_error(fence, -EIO);
|
||||
+ dma_fence_signal(fence);
|
||||
+ dma_fence_end_signalling(cookie);
|
||||
+
|
||||
+ dma_fence_put(fence);
|
||||
+ vb->release_fence = NULL;
|
||||
+}
|
||||
+#else /* !CONFIG_VIDEOBUF2_RELEASE_FENCES */
|
||||
+
|
||||
+int vb2_buffer_attach_release_fence(struct vb2_buffer *vb)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(vb2_buffer_attach_release_fence);
|
||||
+
|
||||
+static inline void vb2_buffer_signal_release_fence(struct vb2_buffer *vb,
|
||||
+ enum vb2_buffer_state state)
|
||||
+{
|
||||
+}
|
||||
+#endif /* CONFIG_VIDEOBUF2_RELEASE_FENCES */
|
||||
+
|
||||
void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)
|
||||
{
|
||||
struct vb2_queue *q = vb->vb2_queue;
|
||||
@@ -1199,6 +1319,9 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)
|
||||
if (state != VB2_BUF_STATE_QUEUED)
|
||||
__vb2_buf_mem_finish(vb);
|
||||
|
||||
+ if (state != VB2_BUF_STATE_QUEUED)
|
||||
+ vb2_buffer_signal_release_fence(vb, state);
|
||||
+
|
||||
spin_lock_irqsave(&q->done_lock, flags);
|
||||
if (state == VB2_BUF_STATE_QUEUED) {
|
||||
vb->state = VB2_BUF_STATE_QUEUED;
|
||||
@@ -2651,6 +2774,18 @@ int vb2_core_queue_init(struct vb2_queue *q)
|
||||
mutex_init(&q->mmap_lock);
|
||||
init_waitqueue_head(&q->done_wq);
|
||||
|
||||
+#ifdef CONFIG_VIDEOBUF2_RELEASE_FENCES
|
||||
+ /*
|
||||
+ * Per-queue dma_resv release-fence context. Drivers that
|
||||
+ * opt in via supports_release_fences and call
|
||||
+ * vb2_buffer_attach_release_fence() use these to allocate
|
||||
+ * fences on a single per-queue timeline.
|
||||
+ */
|
||||
+ q->dma_resv_fence_context = dma_fence_context_alloc(1);
|
||||
+ atomic64_set(&q->dma_resv_fence_seqno, 0);
|
||||
+ spin_lock_init(&q->dma_resv_fence_lock);
|
||||
+#endif
|
||||
+
|
||||
q->memory = VB2_MEMORY_UNKNOWN;
|
||||
|
||||
if (q->buf_struct_size == 0)
|
||||
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
|
||||
index 4424d481d..766ff2194 100644
|
||||
--- a/include/media/videobuf2-core.h
|
||||
+++ b/include/media/videobuf2-core.h
|
||||
@@ -288,6 +288,16 @@ struct vb2_buffer {
|
||||
unsigned int skip_cache_sync_on_finish:1;
|
||||
|
||||
struct vb2_plane planes[VB2_MAX_PLANES];
|
||||
+#ifdef CONFIG_VIDEOBUF2_RELEASE_FENCES
|
||||
+ /*
|
||||
+ * Producer release fence published on each plane's
|
||||
+ * dmabuf->resv when the driver opts in via
|
||||
+ * vb2_buffer_attach_release_fence(). Signalled and put by
|
||||
+ * vb2_buffer_done() on transition to DONE/ERROR. NULL when
|
||||
+ * the driver did not opt in for this buffer.
|
||||
+ */
|
||||
+ struct dma_fence *release_fence;
|
||||
+#endif
|
||||
struct list_head queued_entry;
|
||||
struct list_head done_entry;
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
@@ -648,6 +658,19 @@ struct vb2_queue {
|
||||
spinlock_t done_lock;
|
||||
wait_queue_head_t done_wq;
|
||||
|
||||
+#ifdef CONFIG_VIDEOBUF2_RELEASE_FENCES
|
||||
+ /*
|
||||
+ * dma_resv release-fence context. Drivers that set
|
||||
+ * supports_release_fences and call
|
||||
+ * vb2_buffer_attach_release_fence() use these to allocate
|
||||
+ * fences on a per-queue timeline.
|
||||
+ */
|
||||
+ u64 dma_resv_fence_context;
|
||||
+ atomic64_t dma_resv_fence_seqno;
|
||||
+ spinlock_t dma_resv_fence_lock;
|
||||
+#endif
|
||||
+
|
||||
+ unsigned int supports_release_fences:1;
|
||||
unsigned int streaming:1;
|
||||
unsigned int start_streaming_called:1;
|
||||
unsigned int error:1;
|
||||
@@ -735,6 +758,34 @@ void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no);
|
||||
*/
|
||||
void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state);
|
||||
|
||||
+/**
|
||||
+ * vb2_buffer_attach_release_fence() - opt-in dma_resv release fence.
|
||||
+ * @vb: the buffer being committed to the producer.
|
||||
+ *
|
||||
+ * Drivers that have set vb2_queue::supports_release_fences may call
|
||||
+ * this from any sleepable context where they have committed to
|
||||
+ * running the operation in finite time -- typically m2m
|
||||
+ * device_run(), just before the HW kick. The helper allocates a
|
||||
+ * dma_fence on the queue's per-queue timeline, attaches it as
|
||||
+ * DMA_RESV_USAGE_WRITE on each plane's dmabuf->resv, and stashes
|
||||
+ * it in vb->release_fence. vb2_buffer_done() signals and puts the
|
||||
+ * fence as part of the buffer's state transition.
|
||||
+ *
|
||||
+ * Skips planes whose vb2_plane.dbuf is NULL -- buffers never
|
||||
+ * exported via VIDIOC_EXPBUF (or imported via V4L2_MEMORY_DMABUF)
|
||||
+ * have no dmabuf for userspace to wait on.
|
||||
+ *
|
||||
+ * No-op when vb2_queue::supports_release_fences is not set
|
||||
+ * (regardless of CONFIG_VIDEOBUF2_RELEASE_FENCES). When
|
||||
+ * CONFIG_VIDEOBUF2_RELEASE_FENCES=n, this is a stub that returns 0.
|
||||
+ *
|
||||
+ * Returns 0 on success or when the no-op stub is in effect,
|
||||
+ * negative errno on allocation failure when fence publishing was
|
||||
+ * attempted. Best-effort: drivers should ignore the return value
|
||||
+ * unless they want diagnostics.
|
||||
+ */
|
||||
+int vb2_buffer_attach_release_fence(struct vb2_buffer *vb);
|
||||
+
|
||||
/**
|
||||
* vb2_discard_done() - discard all buffers marked as DONE.
|
||||
* @q: pointer to &struct vb2_queue with videobuf2 queue.
|
||||
--
|
||||
2.53.0
|
||||
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
From 1844c263bde8dd244d7db46f8c508e7c70da459c Mon Sep 17 00:00:00 2001
|
||||
In-Reply-To: <20260429195306.239666-1-mfritsche@reauktion.de>
|
||||
References: <20260429195306.239666-1-mfritsche@reauktion.de>
|
||||
From: Markus Fritsche <mfritsche@reauktion.de>
|
||||
Date: Sat, 9 May 2026 16:24:01 +0200
|
||||
Subject: [PATCH RFC v2] media: hantro: attach dma_resv release fence at
|
||||
device_run
|
||||
|
||||
Opt the hantro driver into the new vb2 release-fence helper so its
|
||||
CAPTURE-side dmabufs carry a real producer fence that wayland
|
||||
compositors and other implicit-sync consumers can wait on, instead
|
||||
of the dma_buf core's stub fence.
|
||||
|
||||
Attach point is m2m device_run, immediately after
|
||||
v4l2_m2m_buf_copy_metadata() and before ctx->codec_ops->run().
|
||||
Per Nicolas Dufresne's v1 review (lore.kernel.org/linux-media/
|
||||
3d8deeb15581b754e4c061d4c4a13657aa08bc3c.camel@ndufresne.ca/),
|
||||
this satisfies the dma_fence finite-time contract: the m2m core
|
||||
has committed to running the job by this point, codec_ops->run
|
||||
either kicks the HW (decode-complete signals the fence via
|
||||
vb2_buffer_done) or fails immediately (job_finish with
|
||||
VB2_BUF_STATE_ERROR signals with -EIO). PM and clocks are already
|
||||
up by this point, so no allocation context restrictions.
|
||||
|
||||
The CAPTURE queue is opted in with supports_release_fences=true at
|
||||
queue_init.
|
||||
|
||||
Userspace consumers that import hantro CAPTURE dmabufs and wait on
|
||||
their implicit-sync fence (Wayland zwp_linux_dmabuf_v1 +
|
||||
panfrost EGL_LINUX_DMA_BUF_EXT) now wait on a real fence
|
||||
representing the producer's actual completion, fixing green-frame
|
||||
corruption observed on RK3566 PineTab2 + Mali-G52 panfrost (the
|
||||
GPU was sampling zero pages because the dmabuf's implicit fence
|
||||
was the dma_buf core's pre-signalled stub).
|
||||
|
||||
Validated end-to-end on PineTab2 (RK3566 / hantro G1 / Mali-G52
|
||||
mainline panfrost): 30s of bbb_1080p30 H.264 stateless decode +
|
||||
zero-copy panfrost EGL import via dmabuf-wayland (mpv 0.41 +
|
||||
KWin 6.6.4 + Mesa panfrost 26.0.5) renders correctly with no
|
||||
green-frame corruption and no PROVE_LOCKING splats.
|
||||
|
||||
Cc: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
|
||||
Cc: Philipp Zabel <p.zabel@pengutronix.de>
|
||||
Cc: Nicolas Dufresne <nicolas@ndufresne.ca>
|
||||
Cc: linux-media@vger.kernel.org
|
||||
Cc: linux-rockchip@lists.infradead.org
|
||||
Signed-off-by: Markus Fritsche <mfritsche@reauktion.de>
|
||||
---
|
||||
.../media/platform/verisilicon/hantro_drv.c | 23 +++++++++++++++++++
|
||||
1 file changed, 23 insertions(+)
|
||||
|
||||
diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c
|
||||
index 2e81877f6..6a66c47ed 100644
|
||||
--- a/drivers/media/platform/verisilicon/hantro_drv.c
|
||||
+++ b/drivers/media/platform/verisilicon/hantro_drv.c
|
||||
@@ -186,6 +186,22 @@ static void device_run(void *priv)
|
||||
|
||||
v4l2_m2m_buf_copy_metadata(src, dst);
|
||||
|
||||
+ /*
|
||||
+ * Attach a producer fence on the CAPTURE-side dmabuf so userspace
|
||||
+ * importers (e.g. Wayland compositors) get spec-clean implicit-sync
|
||||
+ * semantics. Called from device_run rather than buf_queue: the
|
||||
+ * dma_fence finite-time contract requires that once a fence is
|
||||
+ * published, the producer must signal it in finite time. By the
|
||||
+ * time we reach device_run, the m2m core has committed to running
|
||||
+ * this job, and the next hop (codec_ops->run) either kicks the HW
|
||||
+ * (decode-complete signals the fence via vb2_buffer_done) or
|
||||
+ * fails immediately (job_finish with VB2_BUF_STATE_ERROR signals
|
||||
+ * the fence with -EIO). Either path resolves the fence in finite
|
||||
+ * time. Best-effort: a NOMEM here means we lose implicit-sync
|
||||
+ * precision for this frame, no functional regression.
|
||||
+ */
|
||||
+ (void)vb2_buffer_attach_release_fence(&dst->vb2_buf);
|
||||
+
|
||||
if (ctx->codec_ops->run(ctx))
|
||||
goto err_cancel_job;
|
||||
|
||||
@@ -249,6 +265,13 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
|
||||
dst_vq->lock = &ctx->dev->vpu_mutex;
|
||||
dst_vq->dev = ctx->dev->v4l2_dev.dev;
|
||||
|
||||
+ /*
|
||||
+ * Opt the CAPTURE queue into vb2 release-fence publishing.
|
||||
+ * No-op unless CONFIG_VIDEOBUF2_RELEASE_FENCES=y; runtime cost
|
||||
+ * is one extra fence allocation + dma_resv update per device_run.
|
||||
+ */
|
||||
+ dst_vq->supports_release_fences = true;
|
||||
+
|
||||
return vb2_queue_init(dst_vq);
|
||||
}
|
||||
|
||||
--
|
||||
2.53.0
|
||||
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
From 2c63a63bf65739763051dc4ce7ce2ffaf2d514c4 Mon Sep 17 00:00:00 2001
|
||||
In-Reply-To: <20260429195306.239666-1-mfritsche@reauktion.de>
|
||||
References: <20260429195306.239666-1-mfritsche@reauktion.de>
|
||||
From: Markus Fritsche <mfritsche@reauktion.de>
|
||||
Date: Sat, 9 May 2026 16:50:51 +0200
|
||||
Subject: [PATCH RFC v2] media: rockchip-rga: attach dma_resv release fence at
|
||||
device_run
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Opt the rockchip-rga driver into the new vb2 release-fence helper.
|
||||
|
||||
Same shape as the hantro patch: attach a producer fence on the
|
||||
CAPTURE-side dmabuf at m2m device_run, signalled by
|
||||
vb2_buffer_done() when RGA completes the m2m operation.
|
||||
|
||||
Differs from hantro in one mechanical detail: rga's device_run
|
||||
wraps the entire body in spin_lock_irqsave(&rga->ctrl_lock). Our
|
||||
helper calls dma_resv_lock(), which is sleepable, so the
|
||||
buffer-fetch + fence-attach sequence has to run above the spinlock.
|
||||
Restructure device_run so:
|
||||
|
||||
- v4l2_m2m_next_src_buf / next_dst_buf,
|
||||
- src->sequence increment,
|
||||
- vb2_buffer_attach_release_fence(&dst->vb2_buf)
|
||||
|
||||
run before spin_lock_irqsave; only the rga->curr assignment and
|
||||
rga_hw_start() (the actual HW kick) remain inside the spinlock.
|
||||
|
||||
This is safe under the m2m-job ownership model: by the time
|
||||
device_run is called, the m2m core has selected this context and
|
||||
serializes one device_run per context, so v4l2_m2m_next_*_buf
|
||||
returns stable pointers until the corresponding *_buf_remove in
|
||||
rga_isr. ctrl_lock was previously protecting per-device state
|
||||
(rga->curr) and the HW register access, neither of which depends on
|
||||
the buffer-fetch happening inside the lock.
|
||||
|
||||
The CAPTURE queue is opted in with supports_release_fences=true at
|
||||
queue_init.
|
||||
|
||||
Userspace consumers of RGA-produced dmabufs (image-processing
|
||||
pipelines, screen-rotation servers, gstreamer flows on Rockchip
|
||||
boards) get spec-clean implicit-sync semantics, matching what
|
||||
hantro does in the previous patch in this series.
|
||||
|
||||
Sven Püschel's ongoing "media: platform: rga: Add RGA3 support"
|
||||
v5 series (linux-rockchip 2026-04-28) restructures rga.c
|
||||
substantially. If that lands first, the device_run restructure
|
||||
here will need a rebase against the new shape; the locking story
|
||||
itself is invariant.
|
||||
|
||||
Cc: Jacob Chen <jacob-chen@iotwrt.com>
|
||||
Cc: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
|
||||
Cc: Sven Püschel <s.pueschel@pengutronix.de>
|
||||
Cc: Heiko Stuebner <heiko@sntech.de>
|
||||
Cc: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
Cc: linux-media@vger.kernel.org
|
||||
Cc: linux-rockchip@lists.infradead.org
|
||||
Signed-off-by: Markus Fritsche <mfritsche@reauktion.de>
|
||||
---
|
||||
drivers/media/platform/rockchip/rga/rga.c | 27 +++++++++++++++++++----
|
||||
1 file changed, 23 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c
|
||||
index fea63b94c..03030c7ea 100644
|
||||
--- a/drivers/media/platform/rockchip/rga/rga.c
|
||||
+++ b/drivers/media/platform/rockchip/rga/rga.c
|
||||
@@ -38,15 +38,28 @@ static void device_run(void *prv)
|
||||
struct vb2_v4l2_buffer *src, *dst;
|
||||
unsigned long flags;
|
||||
|
||||
- spin_lock_irqsave(&rga->ctrl_lock, flags);
|
||||
-
|
||||
- rga->curr = ctx;
|
||||
-
|
||||
+ /*
|
||||
+ * Fetch the next-job buffers and (best-effort) attach a producer
|
||||
+ * fence on CAPTURE before taking ctrl_lock below.
|
||||
+ * vb2_buffer_attach_release_fence() takes dma_resv_lock, which is
|
||||
+ * sleepable; ctrl_lock is taken with spin_lock_irqsave so any
|
||||
+ * sleepable call must happen above it. Buffer ownership is
|
||||
+ * already committed at this point: the m2m core has selected
|
||||
+ * this context for device_run and serializes one device_run per
|
||||
+ * context, so v4l2_m2m_next_*_buf returns stable pointers until
|
||||
+ * the corresponding *_buf_remove in rga_isr.
|
||||
+ */
|
||||
src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
|
||||
src->sequence = ctx->osequence++;
|
||||
|
||||
dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
|
||||
|
||||
+ (void)vb2_buffer_attach_release_fence(&dst->vb2_buf);
|
||||
+
|
||||
+ spin_lock_irqsave(&rga->ctrl_lock, flags);
|
||||
+
|
||||
+ rga->curr = ctx;
|
||||
+
|
||||
rga_hw_start(rga, vb_to_rga(src), vb_to_rga(dst));
|
||||
|
||||
spin_unlock_irqrestore(&rga->ctrl_lock, flags);
|
||||
@@ -123,6 +136,12 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
|
||||
dst_vq->lock = &ctx->rga->mutex;
|
||||
dst_vq->dev = ctx->rga->v4l2_dev.dev;
|
||||
|
||||
+ /*
|
||||
+ * Opt the CAPTURE queue into vb2 release-fence publishing.
|
||||
+ * Compile-time gated by CONFIG_VIDEOBUF2_RELEASE_FENCES.
|
||||
+ */
|
||||
+ dst_vq->supports_release_fences = true;
|
||||
+
|
||||
return vb2_queue_init(dst_vq);
|
||||
}
|
||||
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
pkgbase=linux-fresnel-fourier
|
||||
pkgname=("$pkgbase" "$pkgbase-headers")
|
||||
pkgver=7.0
|
||||
pkgrel=1
|
||||
pkgdesc='Pinebook Pro kernel (mmind/linux-rockchip v7.0 + OC OPP + PBP DTS tweaks)'
|
||||
pkgrel=14
|
||||
pkgdesc='Pinebook Pro kernel (mmind/linux-rockchip v7.0 + OC OPP + PBP DTS tweaks + vb2_dma_resv RFC v2)'
|
||||
arch=(aarch64)
|
||||
url='https://git.reauktion.de/marfrit/kernel-agent'
|
||||
license=(GPL-2.0-only)
|
||||
@@ -23,15 +23,20 @@ makedepends=(
|
||||
options=('!strip')
|
||||
source=(
|
||||
"https://git.kernel.org/torvalds/t/linux-${pkgver}.tar.gz"
|
||||
# board/pinebook-pro
|
||||
'0001-arm64-dts-rk3399-pinebook-pro-add-OC-OPP-tables-1704-2184.patch'
|
||||
'0002-arm64-dts-rk3399-pinebook-pro-enable-hdmi-sound.patch'
|
||||
'0003-arm64-dts-rk3399-pinebook-pro-spi1-max-freq-10MHz.patch'
|
||||
# subsystem/media/videobuf2/dma-resv-release-fence (RFC v2, in kernel-agent)
|
||||
'0004-media-videobuf2-add-opt-in-dma_resv-producer-fence-h.patch'
|
||||
'0005-media-hantro-attach-dma_resv-release-fence-at-device.patch'
|
||||
'0006-media-rockchip-rga-attach-dma_resv-release-fence-at-.patch'
|
||||
'config' # snapshot of fresnel /usr/lib/modules/6.19.10-1-eos-arm/build/.config
|
||||
'linux-fresnel-fourier.preset'
|
||||
'extlinux-add.hook'
|
||||
'extlinux-add.sh'
|
||||
)
|
||||
sha256sums=('SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP')
|
||||
sha256sums=('SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP')
|
||||
|
||||
_kernver=${pkgver}.0-fresnel-fourier
|
||||
_srcdir=linux-${pkgver}
|
||||
|
||||
+6
-3
@@ -3,15 +3,18 @@
|
||||
# Source of truth: git.reauktion.de/marfrit/lmcp
|
||||
|
||||
pkgname=lmcp
|
||||
pkgver=0.5.4
|
||||
pkgver=1.2.1
|
||||
pkgrel=1
|
||||
pkgdesc="Lightweight MCP (Model Context Protocol) server in pure Lua"
|
||||
arch=('any')
|
||||
url="https://git.reauktion.de/marfrit/lmcp"
|
||||
license=('MIT')
|
||||
depends=('lua' 'lua-socket')
|
||||
source=("${pkgname}-${pkgver}.tar.gz::https://git.reauktion.de/marfrit/lmcp/archive/v${pkgver}.tar.gz")
|
||||
sha256sums=('af72b8c1d88255456b75d2c53cd5c451a8923417e5498ef31858539397e09caf')
|
||||
# The _tag back-translation handles both clean releases (no '_') and
|
||||
# pre-release pkgvers (e.g. 1.2.0_rc1 → v1.2.0-rc1).
|
||||
_tag="v${pkgver//_/-}"
|
||||
source=("${pkgname}-${pkgver}.tar.gz::https://git.reauktion.de/marfrit/lmcp/archive/${_tag}.tar.gz")
|
||||
sha256sums=('bf9cce1a84c66b1b74c5aec923c5960d60ae33c221afc8d47ce0d74b8f7ee609')
|
||||
|
||||
package() {
|
||||
cd "${pkgname}"
|
||||
|
||||
@@ -21,14 +21,14 @@
|
||||
# pkgbase stays as qt6-base so $_pkgfn (= ${pkgbase/6-/} = "qtbase")
|
||||
# resolves correctly. The "-fourier" suffix lives only in the
|
||||
# directory name and the commit history; epoch=1 gives our local
|
||||
# build strict precedence over upstream pkgrel=2 until upstream lands
|
||||
# build strict precedence over upstream pkgrel=N until upstream lands
|
||||
# the GL_R8/ES3 fix and we can drop the epoch.
|
||||
pkgbase=qt6-base
|
||||
pkgname=(qt6-base-fourier
|
||||
qt6-xcb-private-headers-fourier)
|
||||
_pkgver=6.11.0
|
||||
_pkgver=6.11.1
|
||||
pkgver=${_pkgver/-/}
|
||||
pkgrel=3
|
||||
pkgrel=1
|
||||
epoch=1
|
||||
arch=(aarch64 x86_64)
|
||||
url='https://www.qt.io'
|
||||
@@ -42,7 +42,6 @@ depends=(brotli
|
||||
double-conversion
|
||||
fontconfig
|
||||
freetype2
|
||||
gcc-libs
|
||||
glib2
|
||||
glibc
|
||||
harfbuzz
|
||||
@@ -51,6 +50,7 @@ depends=(brotli
|
||||
libb2
|
||||
libcups
|
||||
libdrm
|
||||
libgcc
|
||||
libgl
|
||||
libice
|
||||
libinput
|
||||
@@ -58,6 +58,7 @@ depends=(brotli
|
||||
libpng
|
||||
libproxy
|
||||
libsm
|
||||
libstdc++
|
||||
liburing
|
||||
libx11
|
||||
libxcb
|
||||
@@ -115,7 +116,7 @@ source=(git+https://code.qt.io/qt/$_pkgfn#tag=v$_pkgver
|
||||
0001-qopengltextureglyphcache-pick-GL_R8-on-ES3.patch
|
||||
0002-qrhigles2-RED_OR_ALPHA8-pick-GL_R8-on-ES3.patch
|
||||
0003-qopengltextureuploader-pick-GL_R8-on-ES3.patch)
|
||||
sha256sums=('2223c075e95d86f8dbf6395b025a74d996c418f094453c903290e3c2663fbed2'
|
||||
sha256sums=('2eafe504fae873d20f206b5661e2e10506879455cb2d370f42c5bb72ccf7a8a1'
|
||||
'5411edbe215c24b30448fac69bd0ba7c882f545e8cf05027b2b6e2227abc5e78'
|
||||
'4b93f6a79039e676a56f9d6990a324a64a36f143916065973ded89adc621e094'
|
||||
'SKIP'
|
||||
@@ -126,9 +127,8 @@ prepare() {
|
||||
patch -d $_pkgfn -p1 < qt6-base-cflags.patch # Use system CFLAGS
|
||||
patch -d $_pkgfn -p1 < qt6-base-nostrip.patch # Don't strip binaries with qmake
|
||||
|
||||
# cherry-pick needs git author identity; git-cli refuses without it.
|
||||
git -C $_pkgfn -c user.email=fourier@build -c user.name='qt6-base-fourier build' \
|
||||
cherry-pick -n 8b54513cdcf62047376a5d27d784ad68a8f235bf # Fix qdbus crashes
|
||||
# 8b54513cdcf6 (qdbus crash fix) cherry-pick removed: landed upstream
|
||||
# in 6.11.1. Re-add if qdbus regressions re-surface.
|
||||
|
||||
# qt6-base-fourier — three small runtime-checks that pick GL_R8 over
|
||||
# GL_ALPHA when the live GL context is ES 3 or newer. See the
|
||||
@@ -165,7 +165,7 @@ build() {
|
||||
-DFEATURE_system_sqlite=ON \
|
||||
-DFEATURE_system_xcb_xinput=ON \
|
||||
-DFEATURE_no_direct_extern_access=$_no_direct_extern_access \
|
||||
-DFEATURE_sql_ibase=OFF \
|
||||
-DFEATURE_mimetype_database=OFF \
|
||||
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \
|
||||
-DCMAKE_MESSAGE_LOG_LEVEL=STATUS
|
||||
cmake --build build
|
||||
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
#!/bin/bash
|
||||
# Build daedalus-v4l2-dkms_<ver>_all.deb (kernel module via DKMS).
|
||||
#
|
||||
# Installs kernel/ source tree to /usr/src/daedalus_v4l2-${PKGVER}/
|
||||
# plus a dkms.conf. Postinst registers with DKMS (dkms add + build +
|
||||
# install). Prerm deregisters. Result: the daedalus_v4l2 module
|
||||
# auto-rebuilds against any installed kernel headers without users
|
||||
# needing to remember to dkms-add it.
|
||||
#
|
||||
# Architecture: all. The kernel module itself is per-kernel-version,
|
||||
# but the SOURCE package is arch-independent.
|
||||
#
|
||||
# Sibling Arch package: ../../arch/daedalus-v4l2-dkms/PKGBUILD
|
||||
# Sibling userspace package: ../daedalus-v4l2/build-deb.sh
|
||||
set -euo pipefail
|
||||
|
||||
UPSTREAM_COMMIT=f55b2cdab8a8c0bc04e8c1bb1d0b6ca85e7d96d2
|
||||
PKGVER=0.1.0+r16+gf55b2cd
|
||||
PKGREL=1
|
||||
MODULE_NAME=daedalus_v4l2
|
||||
|
||||
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
|
||||
|
||||
cd "$work"
|
||||
curl -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
|
||||
|
||||
ROOT="$work/pkgroot"
|
||||
SRCROOT="$ROOT/usr/src/${MODULE_NAME}-${PKGVER}"
|
||||
|
||||
mkdir -p "$SRCROOT/include" \
|
||||
"$ROOT/DEBIAN" \
|
||||
"$ROOT/usr/share/doc/daedalus-v4l2-dkms"
|
||||
|
||||
# Copy kernel/ source files to the DKMS source dir.
|
||||
cp -r "$work/$SRCDIR/kernel/." "$SRCROOT/"
|
||||
|
||||
# Embed the shared protocol header inline (rather than referencing
|
||||
# ../include/ which doesn't exist after DKMS extracts the tree).
|
||||
# Patch the Makefile to find it at $SRCROOT/include/ instead.
|
||||
install -m 644 "$work/$SRCDIR/include/daedalus_v4l2_proto.h" \
|
||||
"$SRCROOT/include/daedalus_v4l2_proto.h"
|
||||
sed -i 's|-I\$(src)/\.\./include|-I$(src)/include|' "$SRCROOT/Makefile"
|
||||
|
||||
# Generate dkms.conf with the actual version substituted.
|
||||
cat > "$SRCROOT/dkms.conf" <<EOF
|
||||
PACKAGE_NAME="${MODULE_NAME}"
|
||||
PACKAGE_VERSION="${PKGVER}"
|
||||
|
||||
BUILT_MODULE_NAME[0]="${MODULE_NAME}"
|
||||
DEST_MODULE_LOCATION[0]="/updates"
|
||||
|
||||
MAKE[0]="make KERNELDIR=/lib/modules/\${kernelver}/build all"
|
||||
CLEAN="make KERNELDIR=/lib/modules/\${kernelver}/build clean"
|
||||
|
||||
AUTOINSTALL="yes"
|
||||
EOF
|
||||
|
||||
# Doc
|
||||
install -m 644 "$work/$SRCDIR/README.md" \
|
||||
"$ROOT/usr/share/doc/daedalus-v4l2-dkms/README.md"
|
||||
install -Dm644 "$HERE/debian/copyright" "$ROOT/usr/share/doc/daedalus-v4l2-dkms/copyright"
|
||||
install -Dm644 "$HERE/debian/changelog" "$ROOT/usr/share/doc/daedalus-v4l2-dkms/changelog.Debian"
|
||||
gzip -9 -n "$ROOT/usr/share/doc/daedalus-v4l2-dkms/changelog.Debian"
|
||||
|
||||
# DKMS post-install / pre-remove hooks.
|
||||
cat > "$ROOT/DEBIAN/postinst" <<EOF
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
NAME=${MODULE_NAME}
|
||||
VERSION=${PKGVER}
|
||||
KERNELVER=\$(uname -r)
|
||||
|
||||
# Yellow + bold ANSI for the warning so it stands out in apt's
|
||||
# stream of "Setting up" lines. Disable colour on non-TTY.
|
||||
if [ -t 1 ]; then
|
||||
Y=\$(printf '\\033[1;33m'); R=\$(printf '\\033[0m')
|
||||
else
|
||||
Y=''; R=''
|
||||
fi
|
||||
|
||||
warn() {
|
||||
printf '%s==> daedalus-v4l2-dkms: %s%s\\n' "\$Y" "\$1" "\$R" >&2
|
||||
}
|
||||
|
||||
if [ "\$1" = "configure" ]; then
|
||||
if ! command -v dkms >/dev/null 2>&1; then
|
||||
warn "dkms not installed; module \$NAME/\$VERSION not registered."
|
||||
warn "Install 'dkms' then run: dkms add \$NAME/\$VERSION && dkms autoinstall"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
dkms add "\$NAME/\$VERSION" 2>/dev/null || true
|
||||
|
||||
# Don't let autoinstall failure mask the actual problem behind '|| true'.
|
||||
# Run it, capture the result, then verify post-condition.
|
||||
autoinstall_rc=0
|
||||
dkms autoinstall "\$NAME/\$VERSION" || autoinstall_rc=\$?
|
||||
|
||||
# Verify the module actually built + installed for the running kernel.
|
||||
status=\$(dkms status -m "\$NAME" -v "\$VERSION" -k "\$KERNELVER" 2>/dev/null || true)
|
||||
if ! printf '%s\\n' "\$status" | grep -q -E 'installed|loaded'; then
|
||||
warn ""
|
||||
warn "DKMS build did NOT land for kernel \$KERNELVER."
|
||||
warn " dkms status -m \$NAME -v \$VERSION -k \$KERNELVER:"
|
||||
warn " \$(printf '%s' "\$status" | head -1)"
|
||||
warn ""
|
||||
warn "Most likely cause: kernel headers package is missing."
|
||||
warn " Raspberry Pi OS / Pi 5: apt install linux-headers-rpi-2712"
|
||||
warn " Debian generic: apt install linux-headers-\$KERNELVER"
|
||||
warn ""
|
||||
warn "After installing headers, finish the install with:"
|
||||
warn " sudo dkms autoinstall \$NAME/\$VERSION"
|
||||
warn " sudo modprobe daedalus_v4l2"
|
||||
warn ""
|
||||
warn "Until then daedalus_v4l2 will NOT be loadable and the"
|
||||
warn "userspace daedalus-v4l2 daemon will have nothing to talk to."
|
||||
fi
|
||||
fi
|
||||
|
||||
#DEBHELPER#
|
||||
EOF
|
||||
chmod 755 "$ROOT/DEBIAN/postinst"
|
||||
|
||||
cat > "$ROOT/DEBIAN/prerm" <<EOF
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
NAME=${MODULE_NAME}
|
||||
VERSION=${PKGVER}
|
||||
|
||||
if [ "\$1" = "remove" ] && command -v dkms >/dev/null 2>&1; then
|
||||
dkms remove "\$NAME/\$VERSION" --all || true
|
||||
fi
|
||||
|
||||
#DEBHELPER#
|
||||
EOF
|
||||
chmod 755 "$ROOT/DEBIAN/prerm"
|
||||
|
||||
cat > "$ROOT/DEBIAN/control" <<EOF
|
||||
Package: daedalus-v4l2-dkms
|
||||
Version: ${PKGVER}-${PKGREL}
|
||||
Section: kernel
|
||||
Priority: optional
|
||||
Architecture: all
|
||||
Depends: dkms (>= 2.1.0.0)
|
||||
Recommends: daedalus-v4l2, linux-headers-generic | linux-headers
|
||||
Maintainer: Markus Fritsche <mfritsche@reauktion.de>
|
||||
Homepage: https://git.reauktion.de/reauktion/daedalus-v4l2
|
||||
Description: V4L2 stateless decoder shim kernel module (DKMS) — Pi 5 / CM5
|
||||
Out-of-tree V4L2 m2m kernel module for the daedalus-v4l2 stack on
|
||||
Raspberry Pi 5 / CM5. Registers /dev/videoNN (V4L2 stateless m2m
|
||||
decoder), /dev/mediaNN (media controller with request API), and
|
||||
/dev/daedalus-v4l2 (chardev bridge to the userspace daemon).
|
||||
.
|
||||
The actual decode happens in the userspace daemon shipped by the
|
||||
daedalus-v4l2 package — this module is just the kernel-side V4L2
|
||||
plumbing. Install both to actually serve VAAPI / V4L2 clients.
|
||||
.
|
||||
Built via DKMS against the running kernel's headers.
|
||||
EOF
|
||||
|
||||
DEB_OUT="daedalus-v4l2-dkms_${PKGVER}-${PKGREL}_all.deb"
|
||||
dpkg-deb --root-owner-group --build "$ROOT" "$HERE/$DEB_OUT"
|
||||
echo "built: $HERE/$DEB_OUT"
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
daedalus-v4l2-dkms (0.1.0+r16+gf55b2cd-1) bookworm trixie; urgency=medium
|
||||
|
||||
* Initial Debian DKMS packaging for the daedalus_v4l2 kernel module.
|
||||
* Pinned to f55b2cd (Phase 8.13 close): kernel-side framework
|
||||
integration (V4L2 m2m, dmabuf-export, media controller, request
|
||||
API, NV12 single-plane + NV12M + P010 CAPTURE) that closes the
|
||||
libva→/dev/video0→daemon round-trip with byte-exact pixels.
|
||||
* Auto-builds via DKMS against the running kernel's headers.
|
||||
* Companion userspace package: daedalus-v4l2 (daemon + tools).
|
||||
|
||||
-- Markus Fritsche <mfritsche@reauktion.de> Mon, 18 May 2026 23:00:00 +0000
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
Source: daedalus-v4l2-dkms
|
||||
Section: kernel
|
||||
Priority: optional
|
||||
Maintainer: Markus Fritsche <mfritsche@reauktion.de>
|
||||
Build-Depends: debhelper-compat (= 13)
|
||||
Standards-Version: 4.6.2
|
||||
Homepage: https://git.reauktion.de/reauktion/daedalus-v4l2
|
||||
|
||||
Package: daedalus-v4l2-dkms
|
||||
Architecture: all
|
||||
Depends: ${misc:Depends}, dkms (>= 2.1.0.0)
|
||||
Recommends: daedalus-v4l2,
|
||||
linux-headers-generic | linux-headers
|
||||
Description: V4L2 stateless decoder shim kernel module (DKMS) — Pi 5 / CM5
|
||||
Out-of-tree V4L2 m2m kernel module for the daedalus-v4l2 stack on
|
||||
Raspberry Pi 5 / CM5. Registers /dev/videoNN (V4L2 stateless m2m
|
||||
decoder), /dev/mediaNN (media controller with request API), and
|
||||
/dev/daedalus-v4l2 (chardev bridge to the userspace daemon).
|
||||
.
|
||||
The actual decode happens in the userspace daemon shipped by the
|
||||
daedalus-v4l2 package — this module is just the kernel-side V4L2
|
||||
plumbing. Install both to actually serve VAAPI / V4L2 clients.
|
||||
.
|
||||
Built via DKMS against the running kernel's headers.
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: daedalus-v4l2
|
||||
Upstream-Contact: Markus Fritsche <fritsche.markus@gmail.com>
|
||||
Source: https://git.reauktion.de/reauktion/daedalus-v4l2
|
||||
|
||||
Files: *
|
||||
Copyright: 2026 Markus Fritsche <fritsche.markus@gmail.com>
|
||||
License: GPL-2.0-or-later
|
||||
Comment:
|
||||
Kernel module (loadable into the Linux kernel) — GPL-2.0-or-later.
|
||||
The shared protocol header carries an additional Linux-syscall-note
|
||||
exception so userspace inclusion is BSD-clean.
|
||||
|
||||
License: GPL-2.0-or-later
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General Public
|
||||
License v2 can be found in `/usr/share/common-licenses/GPL-2'.
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
#!/bin/bash
|
||||
# Build daedalus-v4l2_<ver>_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
|
||||
|
||||
# Same pin as the Arch PKGBUILD. f55b2cd = "Phase 8.13: byte-exact
|
||||
# end-to-end via libva (consumer target hit)" — first commit where the
|
||||
# full ffmpeg -hwaccel vaapi → libva → /dev/video0 → daemon path lands
|
||||
# a pixel-correct decoded frame back in ffmpeg.
|
||||
UPSTREAM_COMMIT=f55b2cdab8a8c0bc04e8c1bb1d0b6ca85e7d96d2
|
||||
PKGVER=0.1.0+r16+gf55b2cd
|
||||
PKGREL=1
|
||||
|
||||
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
|
||||
|
||||
cd "$work"
|
||||
curl -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)
|
||||
cd "$SRCDIR/daemon"
|
||||
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"
|
||||
|
||||
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"
|
||||
|
||||
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"
|
||||
|
||||
cat > "$ROOT/DEBIAN/control" <<EOF
|
||||
Package: daedalus-v4l2
|
||||
Version: ${PKGVER}-${PKGREL}
|
||||
Section: video
|
||||
Priority: optional
|
||||
Architecture: arm64
|
||||
Depends: ffmpeg (>= 7.1), libdrm2
|
||||
Recommends: daedalus-v4l2-dkms
|
||||
Maintainer: Markus Fritsche <mfritsche@reauktion.de>
|
||||
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"
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
daedalus-v4l2 (0.1.0+r16+gf55b2cd-1) bookworm trixie; urgency=medium
|
||||
|
||||
* Initial Debian packaging for the daedalus-v4l2 userspace daemon.
|
||||
* Pinned to f55b2cd (Phase 8.13 close): first commit where the full
|
||||
ffmpeg -hwaccel vaapi → libva-v4l2-request-fourier → /dev/video0
|
||||
→ daemon path lands a pixel-correct decoded NV12 frame back in
|
||||
ffmpeg.
|
||||
* Codecs: VP9, AV1, H.264 (all via dlopen'd FFmpeg 7.1.3).
|
||||
* Capture formats: NV12M (2 plane), NV12 (1 plane, for libva),
|
||||
P010 (10-bit single plane).
|
||||
* Companion package: daedalus-v4l2-dkms (kernel module).
|
||||
|
||||
-- Markus Fritsche <mfritsche@reauktion.de> Mon, 18 May 2026 23:00:00 +0000
|
||||
Vendored
+34
@@ -0,0 +1,34 @@
|
||||
Source: daedalus-v4l2
|
||||
Section: video
|
||||
Priority: optional
|
||||
Maintainer: Markus Fritsche <mfritsche@reauktion.de>
|
||||
Build-Depends: debhelper-compat (= 13),
|
||||
cmake,
|
||||
ninja-build,
|
||||
pkg-config,
|
||||
libavformat-dev (>= 7.1),
|
||||
libavcodec-dev (>= 7.1),
|
||||
libavutil-dev (>= 7.1)
|
||||
Standards-Version: 4.6.2
|
||||
Homepage: https://git.reauktion.de/reauktion/daedalus-v4l2
|
||||
|
||||
Package: daedalus-v4l2
|
||||
Architecture: arm64
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends},
|
||||
ffmpeg (>= 7.1),
|
||||
libdrm2
|
||||
Recommends: daedalus-v4l2-dkms
|
||||
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.
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: daedalus-v4l2
|
||||
Upstream-Contact: Markus Fritsche <fritsche.markus@gmail.com>
|
||||
Source: https://git.reauktion.de/reauktion/daedalus-v4l2
|
||||
|
||||
Files: *
|
||||
Copyright: 2026 Markus Fritsche <fritsche.markus@gmail.com>
|
||||
License: BSD-2-Clause
|
||||
|
||||
Files: include/daedalus_v4l2_proto.h
|
||||
Copyright: 2026 Markus Fritsche <fritsche.markus@gmail.com>
|
||||
License: GPL-2.0-or-later WITH Linux-syscall-note
|
||||
Comment:
|
||||
Shared kernel↔daemon wire-protocol header. GPL-2.0-or-later (matches
|
||||
the kernel module that includes it) with the standard
|
||||
Linux-syscall-note exception so userspace inclusion is BSD-clean.
|
||||
|
||||
License: BSD-2-Clause
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
.
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES ARE DISCLAIMED.
|
||||
|
||||
License: GPL-2.0-or-later
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General Public
|
||||
License v2 can be found in `/usr/share/common-licenses/GPL-2'.
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
# Build libva-v4l2-request-fourier_<ver>_arm64.deb.
|
||||
#
|
||||
# Compiles the libva ICD from the marfrit/libva-v4l2-request-fourier
|
||||
# tip pinned in PKGVER below. Mirrors arch/libva-v4l2-request-fourier
|
||||
# (Arch Linux build). Output is a single arm64 .deb that ships the
|
||||
# VA-API driver as /usr/lib/aarch64-linux-gnu/dri/v4l2_request_drv_video.so.
|
||||
#
|
||||
# Sibling Arch package: ../../arch/libva-v4l2-request-fourier/PKGBUILD
|
||||
# Upstream fork: https://git.reauktion.de/marfrit/libva-v4l2-request-fourier
|
||||
set -euo pipefail
|
||||
|
||||
# Same pin as the Arch PKGBUILD. de27e95 = "v4l2: log error_idx +
|
||||
# failing ctrl id on S_EXT_CTRLS failure" (Phase 8.13 diagnostic).
|
||||
UPSTREAM_COMMIT=de27e95571b67ef34619c23a12db4698f9b3454e
|
||||
PKGVER=1.0.0+r376+gde27e95
|
||||
PKGREL=1
|
||||
|
||||
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
|
||||
|
||||
cd "$work"
|
||||
curl -sSLfo libva-fourier.tar.gz \
|
||||
"https://git.reauktion.de/marfrit/libva-v4l2-request-fourier/archive/${UPSTREAM_COMMIT}.tar.gz"
|
||||
tar xzf libva-fourier.tar.gz
|
||||
SRCDIR=$(echo libva-v4l2-request-fourier)
|
||||
|
||||
cd "$SRCDIR"
|
||||
meson setup build \
|
||||
--buildtype=release \
|
||||
--prefix=/usr \
|
||||
--libdir=lib/aarch64-linux-gnu \
|
||||
-Db_lto=false
|
||||
meson compile -C build
|
||||
|
||||
ROOT="$work/pkgroot"
|
||||
DESTDIR="$ROOT" meson install -C build
|
||||
|
||||
# Strip any non-package debug, then drop dependencies + control.
|
||||
install -Dm644 "$HERE/debian/copyright" "$ROOT/usr/share/doc/libva-v4l2-request-fourier/copyright"
|
||||
install -Dm644 "$HERE/debian/changelog" "$ROOT/usr/share/doc/libva-v4l2-request-fourier/changelog.Debian"
|
||||
gzip -9 -n "$ROOT/usr/share/doc/libva-v4l2-request-fourier/changelog.Debian"
|
||||
|
||||
mkdir -p "$ROOT/DEBIAN"
|
||||
cat > "$ROOT/DEBIAN/control" <<EOF
|
||||
Package: libva-v4l2-request-fourier
|
||||
Version: ${PKGVER}-${PKGREL}
|
||||
Section: libs
|
||||
Priority: optional
|
||||
Architecture: arm64
|
||||
Depends: libva2, libdrm2
|
||||
Conflicts: libva-v4l2-request
|
||||
Replaces: libva-v4l2-request
|
||||
Provides: libva-driver, libva-v4l2-request (= ${PKGVER}-${PKGREL})
|
||||
Maintainer: Markus Fritsche <mfritsche@reauktion.de>
|
||||
Homepage: https://git.reauktion.de/marfrit/libva-v4l2-request-fourier
|
||||
Description: VA-API backend for V4L2 stateless decoders (fourier fork)
|
||||
LibVA implementation for the Linux Video4Linux2 Request API, multiplanar
|
||||
fork of bootlin/libva-v4l2-request. Drives rkvdec / hantro / cedrus /
|
||||
rpi-hevc-dec / daedalus_v4l2 stateless decoders for H.264, HEVC, VP8,
|
||||
VP9, AV1, and MPEG-2.
|
||||
.
|
||||
Auto-detected by VAAPI consumers (ffmpeg -hwaccel vaapi, mpv --hwdec=vaapi,
|
||||
Firefox VAAPI accel) when LIBVA_DRIVER_NAME=v4l2_request is set.
|
||||
EOF
|
||||
|
||||
DEB_OUT="libva-v4l2-request-fourier_${PKGVER}-${PKGREL}_arm64.deb"
|
||||
dpkg-deb --root-owner-group --build "$ROOT" "$HERE/$DEB_OUT"
|
||||
echo "built: $HERE/$DEB_OUT"
|
||||
@@ -0,0 +1,15 @@
|
||||
libva-v4l2-request-fourier (1.0.0+r376+gde27e95-1) bookworm trixie; urgency=medium
|
||||
|
||||
* Initial Debian packaging (sibling to existing
|
||||
arch/libva-v4l2-request-fourier).
|
||||
* Pinned to fork tip de27e95: "v4l2: log error_idx + failing ctrl id
|
||||
on S_EXT_CTRLS failure" — Phase 8.13 diagnostic that surfaced the
|
||||
real root cause of the libva→daedalus_v4l2 request-completion
|
||||
timeout.
|
||||
* Includes daedalus_v4l2 probe slot (b5b3acf) and meson option gate
|
||||
(2146341) for the Pi 5 daemon-backed decoder shim.
|
||||
* Backward-compatible on rkvdec / hantro / cedrus / rpi-hevc-dec
|
||||
hosts — daedalus probe is off by default unless the kernel module
|
||||
is present.
|
||||
|
||||
-- Markus Fritsche <mfritsche@reauktion.de> Mon, 18 May 2026 23:00:00 +0000
|
||||
@@ -0,0 +1,27 @@
|
||||
Source: libva-v4l2-request-fourier
|
||||
Section: libs
|
||||
Priority: optional
|
||||
Maintainer: Markus Fritsche <mfritsche@reauktion.de>
|
||||
Build-Depends: debhelper-compat (= 13),
|
||||
libva-dev,
|
||||
libdrm-dev,
|
||||
meson (>= 0.43),
|
||||
ninja-build,
|
||||
pkg-config
|
||||
Standards-Version: 4.6.2
|
||||
Homepage: https://git.reauktion.de/marfrit/libva-v4l2-request-fourier
|
||||
|
||||
Package: libva-v4l2-request-fourier
|
||||
Architecture: arm64
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends}, libva2, libdrm2
|
||||
Conflicts: libva-v4l2-request
|
||||
Replaces: libva-v4l2-request
|
||||
Provides: libva-driver, libva-v4l2-request (= ${binary:Version})
|
||||
Description: VA-API backend for V4L2 stateless decoders (fourier fork)
|
||||
LibVA implementation for the Linux Video4Linux2 Request API, multiplanar
|
||||
fork of bootlin/libva-v4l2-request. Drives rkvdec / hantro / cedrus /
|
||||
rpi-hevc-dec / daedalus_v4l2 stateless decoders for H.264, HEVC, VP8,
|
||||
VP9, AV1, and MPEG-2.
|
||||
.
|
||||
Auto-detected by VAAPI consumers (ffmpeg -hwaccel vaapi, mpv --hwdec=vaapi,
|
||||
Firefox VAAPI accel) when LIBVA_DRIVER_NAME=v4l2_request is set.
|
||||
@@ -0,0 +1,38 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: libva-v4l2-request-fourier
|
||||
Upstream-Contact: Markus Fritsche <fritsche.markus@gmail.com>
|
||||
Source: https://git.reauktion.de/marfrit/libva-v4l2-request-fourier
|
||||
Comment:
|
||||
Fork of bootlin/libva-v4l2-request with multi-codec / multi-device
|
||||
enhancements for the fourier campaign (RK3399 / RK3588 / RK3566 / BCM2712).
|
||||
Per-file SPDX headers are the canonical declaration; this summary
|
||||
covers the aggregate.
|
||||
|
||||
Files: *
|
||||
Copyright: 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
|
||||
2018-2026 The libva-v4l2-request authors
|
||||
2024-2026 Markus Fritsche <fritsche.markus@gmail.com>
|
||||
License: LGPL-2.1+ or MIT
|
||||
|
||||
License: LGPL-2.1+
|
||||
This package is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
.
|
||||
On Debian systems, the complete text of the GNU Lesser General
|
||||
Public License v2.1 can be found in `/usr/share/common-licenses/LGPL-2.1'.
|
||||
|
||||
License: MIT
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject
|
||||
to the following conditions:
|
||||
.
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
|
||||
Vendored
+4
-3
@@ -7,9 +7,10 @@
|
||||
# package (Architecture: all, depends on lua + lua-socket).
|
||||
set -euo pipefail
|
||||
|
||||
PKGVER=0.5.4
|
||||
PKGVER=1.2.1
|
||||
UPSTREAM_TAG=v1.2.1
|
||||
PKGREL=1
|
||||
LMCP_TARBALL_SHA256=af72b8c1d88255456b75d2c53cd5c451a8923417e5498ef31858539397e09caf
|
||||
LMCP_TARBALL_SHA256=bf9cce1a84c66b1b74c5aec923c5960d60ae33c221afc8d47ce0d74b8f7ee609
|
||||
HERE=$(dirname "$(readlink -f "$0")")
|
||||
|
||||
# Reproducible build: pin all file mtimes + ar member timestamps to a fixed
|
||||
@@ -22,7 +23,7 @@ work=$(mktemp -d)
|
||||
trap "rm -rf $work" EXIT
|
||||
|
||||
cd "$work"
|
||||
curl -sSLfo lmcp.tar.gz "https://git.reauktion.de/marfrit/lmcp/archive/v${PKGVER}.tar.gz"
|
||||
curl -sSLfo lmcp.tar.gz "https://git.reauktion.de/marfrit/lmcp/archive/${UPSTREAM_TAG}.tar.gz"
|
||||
echo "$LMCP_TARBALL_SHA256 lmcp.tar.gz" | sha256sum -c
|
||||
tar xzf lmcp.tar.gz
|
||||
|
||||
|
||||
Vendored
+80
@@ -1,3 +1,83 @@
|
||||
lmcp (1.2.1-1) bookworm trixie; urgency=medium
|
||||
|
||||
* tools.d/ plugin scan (closes lmcp#22): server.lua now scans
|
||||
LMCP_TOOLS_DIR (default /opt/lmcp/tools.d on POSIX) for *.lua
|
||||
files and invokes each as a function receiving (server, run).
|
||||
Lets hosts ship local tool extensions alongside the packaged
|
||||
generics without forking server.lua. Existing single-file
|
||||
deployments without a tools.d/ directory: no behaviour change.
|
||||
* LMCP_HOST + LMCP_CONF env vars: packaged server.lua now threads
|
||||
these into lmcp.new(opts.host, opts.conf). Hosts that need
|
||||
single-interface binding (e.g. hertz on 192.168.88.18) or a
|
||||
conf-file-based bearer token (e.g. /opt/herding/etc/hertz-tools.conf)
|
||||
can drive the packaged entrypoint directly via systemd env
|
||||
instead of carrying a forked server.lua.
|
||||
* Together with the above, hertz, ampere, and any future host with
|
||||
custom tools can migrate from /opt/lmcp/server.lua forks to a
|
||||
plain plugin file + standard systemd env. apt upgrade then
|
||||
delivers all packaged improvements automatically.
|
||||
|
||||
-- Markus Fritsche <mfritsche@reauktion.de> Mon, 18 May 2026 01:30:00 +0000
|
||||
|
||||
lmcp (1.1.1-1) bookworm trixie; urgency=medium
|
||||
|
||||
* Bug fix: omit empty inputSchema.properties at tool registration.
|
||||
The json.lua empty-table-as-array gotcha (same one that bit
|
||||
`ping` in v1.0.0-rc1) was re-surfacing on tool inputSchemas
|
||||
declared with `properties = {}` — spec-strict MCP clients (Zod)
|
||||
rejected the tools/list with "expected: record, received: array".
|
||||
lmcp:tool() now normalises empty properties tables by dropping
|
||||
the key entirely (JSON Schema permits omitting `properties` on
|
||||
`type:object`, meaning "any object — no constraints").
|
||||
Discovered live on a hertz-tools deployment where two custom
|
||||
no-arg tools (lxc_list, network_status) tripped the Zod check
|
||||
and caused Claude Code to mark the entire MCP endpoint as
|
||||
disconnected.
|
||||
|
||||
-- Markus Fritsche <mfritsche@reauktion.de> Mon, 18 May 2026 00:55:00 +0000
|
||||
|
||||
lmcp (1.1.0-1) bookworm trixie; urgency=medium
|
||||
|
||||
* Concurrent handler dispatch (closes #20): tool handlers run in
|
||||
cooperative coroutines. server.lua:run()'s sleep_ms yields to
|
||||
the event loop instead of blocking. Slow shell commands no
|
||||
longer serialise other requests — fast ping during a slow
|
||||
`sleep N` returns in ~10ms (was ~N seconds).
|
||||
* Progress + cancellation notifications (closes #11): tool
|
||||
handler ctx gains progress(p, total?, message?) and cancelled().
|
||||
Client→server notifications/cancelled flips a flag the running
|
||||
handler sees within ~420ms (poll interval capped when ctx
|
||||
present). Cancelled requests get a JSON-RPC -32800 error
|
||||
response (spec wording is "SHOULD NOT respond" but the practical
|
||||
UX wins; see upstream issue for the FD-inheritance trade-off).
|
||||
* Windows MSI build sync (closes #18): windows/sync.sh script
|
||||
refreshes windows/pkg/{lmcp,server,json}.lua from root before
|
||||
WiX is invoked. Closes the drift trap that left the MSI ~6
|
||||
months behind master in April 2026.
|
||||
* Zero handler source-code changes; all existing tools (shell,
|
||||
fetch, web_search, hub remote_*) benefit from concurrency and
|
||||
auto-cancellation transparently via the run() helper.
|
||||
|
||||
-- Markus Fritsche <mfritsche@reauktion.de> Sun, 17 May 2026 19:45:00 +0000
|
||||
|
||||
lmcp (1.0.0~rc1-1) bookworm trixie; urgency=medium
|
||||
|
||||
* Full MCP 2025-06-18 surface (release candidate). Closes 14
|
||||
upstream issues. New primitives: Resources, Prompts, Completion,
|
||||
Logging, Sampling, Roots, fetch, web_search. Protocol: cursor
|
||||
pagination, structuredContent, _meta passthrough, tool annotations
|
||||
(readOnlyHint/destructiveHint/idempotentHint/openWorldHint).
|
||||
Transports: stdio (LMCP_TRANSPORT=stdio) for Claude Desktop / IDE
|
||||
clients; full Streamable HTTP rewrite with select()-based event
|
||||
loop, sessions (Mcp-Session-Id), persistent SSE, server-initiated
|
||||
requests, heartbeat, DELETE.
|
||||
* json.lua: UTF-16 surrogate-pair combination + json.empty_object
|
||||
sentinel for spec-correct {} emission (fixes ping's result:[]
|
||||
bug).
|
||||
* Backwards compatible with all existing sessionless-POST clients.
|
||||
|
||||
-- Markus Fritsche <mfritsche@reauktion.de> Sun, 17 May 2026 17:25:00 +0000
|
||||
|
||||
lmcp (0.5.4-1) bookworm trixie; urgency=medium
|
||||
|
||||
* Ship examples/lmcp.service systemd unit template alongside the
|
||||
|
||||
Reference in New Issue
Block a user