forked from marfrit/marfrit-packages
Compare commits
5 Commits
4820e53b18
...
06023bcf9d
| Author | SHA1 | Date | |
|---|---|---|---|
| 06023bcf9d | |||
| 7542989f2b | |||
| 9e9447502e | |||
| eb1782e86f | |||
| a168342fa8 |
@@ -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() {
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
# Maintainer: Markus Fritsche <mfritsche@reauktion.de>
|
||||
#
|
||||
# linux-ampere-fourier — CoolPi GenBook (RK3588) kernel from the
|
||||
# marfrit-iterated linux-rk3588-marfrit branch (pinned commit).
|
||||
# linux-ampere-fourier — CoolPi GenBook (RK3588) kernel built from the
|
||||
# kernel-agent fleet/ampere.yaml manifest applied to mainline v7.0-rc3.
|
||||
#
|
||||
# Baseline carries the marfrit RK3588 delta on top of mainline v7.0-rc3:
|
||||
# 10 Markus commits (board DTS + Kconfig + suspend/wakeup + bluetooth)
|
||||
# plus 8 upstream cherry-picks (Shawn Lin's pcie3 phy series, Collabora
|
||||
# clk/dts/dw-dp fixes, Sebastian Reichel's Rock 5 ITX hdmirx). The 6
|
||||
# board-relevant patches are scope-tagged in marfrit/kernel-agent under
|
||||
# patches/{soc,module,board}/ — see fleet/ampere.yaml manifest.
|
||||
# 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
|
||||
@@ -21,9 +28,9 @@
|
||||
|
||||
pkgbase=linux-ampere-fourier
|
||||
pkgname=("$pkgbase" "$pkgbase-headers")
|
||||
pkgver=7.0rc3.kafr1
|
||||
pkgver=7.0rc3.kafr2
|
||||
pkgrel=1
|
||||
pkgdesc='CoolPi GenBook kernel (linux-rk3588-marfrit @ f8f3ad9 + RK3588 cherry-picks + GenBook DTS)'
|
||||
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)
|
||||
@@ -34,13 +41,24 @@ makedepends=(
|
||||
)
|
||||
options=('!strip')
|
||||
|
||||
# Pinned tip of marfrit/linux-rk3588-marfrit. 18 commits ahead of v7.0-rc3:
|
||||
# 10 by Markus Fritsche (board/SoC/module/Bluetooth/Kconfig)
|
||||
# 4 by Shawn Lin (phy: rockchip-snps-pcie3 stability series)
|
||||
# 2 by Cristian Ciocaltea (clk + dw-dp bridge — Collabora track)
|
||||
# 1 by Sebastian Reichel (Rock 5 ITX hdmirx — not used by ampere)
|
||||
# 1 by Pedro Alves (CLK_SET_RATE_PARENT VOP2 fix)
|
||||
_commit=f8f3ad934433bd7e1207d9b0b37e817a692b7ee9
|
||||
# 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
|
||||
|
||||
@@ -19,8 +19,11 @@
|
||||
set -euo pipefail
|
||||
|
||||
TREE="${LINUX_RK3588_MARFRIT_TREE:-${HOME}/src/linux-rockchip}"
|
||||
COMMIT=f8f3ad934433bd7e1207d9b0b37e817a692b7ee9
|
||||
SHA256_EXPECTED=b4eca11e883fe6f7f306d8751c3efa3afed9cc3465c74a3320de1b7204f5f330
|
||||
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"
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@
|
||||
# Source of truth: git.reauktion.de/marfrit/lmcp
|
||||
|
||||
pkgname=lmcp
|
||||
pkgver=1.1.1
|
||||
pkgver=1.2.1
|
||||
pkgrel=1
|
||||
pkgdesc="Lightweight MCP (Model Context Protocol) server in pure Lua"
|
||||
arch=('any')
|
||||
@@ -14,7 +14,7 @@ depends=('lua' 'lua-socket')
|
||||
# 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=('80c2e815aa61a2d3baab051c51cd247bdefa9dd03d72c4867b99c49b6eae9cb9')
|
||||
sha256sums=('bf9cce1a84c66b1b74c5aec923c5960d60ae33c221afc8d47ce0d74b8f7ee609')
|
||||
|
||||
package() {
|
||||
cd "${pkgname}"
|
||||
|
||||
Vendored
+3
-3
@@ -7,10 +7,10 @@
|
||||
# package (Architecture: all, depends on lua + lua-socket).
|
||||
set -euo pipefail
|
||||
|
||||
PKGVER=1.1.1
|
||||
UPSTREAM_TAG=v1.1.1
|
||||
PKGVER=1.2.1
|
||||
UPSTREAM_TAG=v1.2.1
|
||||
PKGREL=1
|
||||
LMCP_TARBALL_SHA256=80c2e815aa61a2d3baab051c51cd247bdefa9dd03d72c4867b99c49b6eae9cb9
|
||||
LMCP_TARBALL_SHA256=bf9cce1a84c66b1b74c5aec923c5960d60ae33c221afc8d47ce0d74b8f7ee609
|
||||
HERE=$(dirname "$(readlink -f "$0")")
|
||||
|
||||
# Reproducible build: pin all file mtimes + ar member timestamps to a fixed
|
||||
|
||||
Vendored
+21
@@ -1,3 +1,24 @@
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user