feat(host): PyroWave encoder — Phase 1 of the LAN low-latency codec plan

PyroWaveEncoder behind --features pyrowave + an explicit
PUNKTFUNK_ENCODER=pyrowave (loud EXPERIMENTAL warning: no client can
decode the stream until CODEC_PYROWAVE negotiation lands, plan Phase 2).

Design (plan §4.3): a private ash Vulkan-1.3 device shared with pyrowave
via pyrowave_create_device — DeviceHold pins the instance/device
create-infos the 0.4.0 API requires alive for the device's lifetime.
Capture dmabufs pass straight through on ANY vendor
(linux_zero_copy_is_vaapi → true for pyrowave; NVIDIA dmabuf→Vulkan
import validated by upstream's interop test on .21) with the same
per-buffer import cache as the Vulkan Video backend; the shared
rgb2yuv.comp BT.709-limited CSC writes R8+RG8 images pyrowave samples
directly (R/G view swizzles synthesize Cb/Cr — no NV12 copy). Encode
records into OUR command buffer (pyrowave_device_set_command_buffer), so
ingest + CSC + encode are one submission with a sub-ms fence wait; the
AU is exactly one pyrowave packet, keyframe=true on every frame.
reconfigure_bitrate is a free in-place budget change (Phase 3 pins the
session rate); reset() recreates only the pyrowave encoder object.

Shared ash leaf helpers (dmabuf import, image/memory utils) extracted
from vulkan_video.rs into encode/linux/vk_util.rs — vulkan-encode
builds unchanged.

Validated on .21 (RTX 5070 Ti): pyrowave_smoke green — encodes CPU
fills through the full open→CSC→GPU-encode→packetize path, decodes
every AU with upstream's own decoder, checks BT.709 plane means ±3;
rate retarget + rebuild covered. clippy clean, 308 host tests green
with the feature on.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-15 00:58:02 +02:00
parent 4c3b11445c
commit 767f028bdf
6 changed files with 1326 additions and 178 deletions
+8
View File
@@ -80,6 +80,9 @@ log = "0.4"
# crate vendors libopus (cmake-built from source — no system lib, no vcpkg), so it builds on Windows
# MSVC too (needs CMake + NASM, both on the box). Both platforms that have an audio-capture backend.
[target.'cfg(any(target_os = "linux", target_os = "windows"))'.dependencies]
# PyroWave (opt-in wired-LAN wavelet codec) — vendored codec + bindgen'd C API, only compiled
# under `--features pyrowave`. Stub-empty on other targets, so the cfg here is belt-and-braces.
pyrowave-sys = { path = "../pyrowave-sys", optional = true }
opus = "0.3"
# Software H.264 encoder — the GPU-less encode path on both Linux and Windows (and a fallback when no
# hardware encoder is available). The default `source` feature statically compiles OpenH264 (BSD-2) —
@@ -265,6 +268,11 @@ amf-qsv = ["dep:ffmpeg-next"]
# bindings already carried for the dmabuf zero-copy bridge). Runtime-gated further by
# PUNKTFUNK_VULKAN_ENCODE (opt-in for now). Build the AMD/Intel RFI host with `--features vulkan-encode`.
vulkan-encode = []
# PyroWave — the opt-in wired-LAN intra-only wavelet codec (design/pyrowave-codec-plan.md).
# Builds the vendored codec from source (crates/pyrowave-sys, CMake + bindgen; Linux/Windows).
# OFF by default; runtime-gated further behind an explicit PUNKTFUNK_ENCODER=pyrowave.
# EXPERIMENTAL until CODEC_PYROWAVE negotiation lands (plan Phase 2).
pyrowave = ["dep:pyrowave-sys"]
# Build-time icon/version-info embedding (build.rs; Windows dev/CI hosts only — Linux packaging
# builds of this crate never execute the winresource block).