Files
punktfunk/crates/pf-encode/Cargo.toml
T
enricobuehler 9a36ea2132 refactor(host/W6.2): extract the video encode backends into the pf-encode crate
encode.rs + encode/* (NVENC, VAAPI, native AMF, AMF/QSV ffmpeg, direct-SDK
NVENC/CUDA, raw Vulkan-Video, PyroWave, openh264) move into crates/pf-encode
behind one Encoder trait + open_video selector (plan §W6). The crate speaks the
shared frame vocabulary (pf-frame: CapturedFrame/PixelFormat + the DXGI identity
D3d11Frame/make_device) and pf-zerocopy (CUDA context/buffers), and NEVER
pf-capture — the capture→encode edge is one-way (ZeroCopyPolicy, prior commit).

Dep moves: the heavy encoder deps (ffmpeg-next, the NVENC SDK, openh264,
pyrowave-sys) move from the host to pf-encode; the host's
nvenc/amf-qsv/vulkan-encode/pyrowave features now FORWARD to pf-encode/*. The
host keeps a mod-encode shim (pub use pf_encode) so every crate::encode::* path
(negotiator + GameStream/native/mgmt planes) is unchanged.

resolve_render_adapter_luid moves from the host's windows/win_adapter.rs into
pf-gpu (both pf-encode and pf-capture need it as a peer of GPU selection); its 5
call sites (encode amf/nvenc, capture idd_push/synthetic_nv12, vdisplay manager)
rewire to pf_gpu::resolve_render_adapter_luid and win_adapter.rs is deleted.
pf-frame's make_device gains a # Safety section (public-unsafe-fn lint, latent
since the pf-frame carve — a full-workspace -D warnings clippy catches it).

Verified: Linux clippy -D warnings (pf-encode + host nvenc,vulkan-encode,pyrowave
--all-targets) + 13/13 pf-encode + 299/299 host tests; Windows clippy -D warnings
(pf-encode nvenc,amf-qsv --all-targets + host nvenc,amf-qsv --all-targets)
Finished exit 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 10:42:51 +02:00

75 lines
3.4 KiB
TOML

# Hardware/software video encode (plan §7 / §W6): the per-vendor backends (NVENC, VAAPI, AMF, QSV,
# Vulkan-Video, PyroWave, openh264) behind one `Encoder` trait + `open_video` selector, extracted
# from the host so it depends on the shared frame vocabulary (pf-frame) rather than living inside
# the orchestrator. Speaks pf-frame (CapturedFrame/PixelFormat/dxgi identity) and pf-zerocopy
# (CUDA), never pf-capture — the capture→encode edge is one-way (plan §2.4).
[package]
name = "pf-encode"
version = "0.12.0"
edition = "2021"
rust-version.workspace = true
license = "MIT OR Apache-2.0"
description = "punktfunk host video encode: NVENC/VAAPI/AMF/QSV/Vulkan-Video/PyroWave/openh264 backends behind one Encoder trait."
publish = false
[dependencies]
punktfunk-core = { path = "../punktfunk-core", features = ["quic"] }
pf-frame = { path = "../pf-frame" }
pf-gpu = { path = "../pf-gpu" }
pf-host-config = { path = "../pf-host-config" }
pf-zerocopy = { path = "../pf-zerocopy" }
anyhow = "1"
tracing = "0.1"
[dev-dependencies]
# A test writer for the NVENC backend's unit tests (`with_test_writer().try_init()`).
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
[target.'cfg(any(target_os = "linux", target_os = "windows"))'.dependencies]
# Software H.264 (openh264, BSD-2) — the GPU-less encode path on both platforms.
openh264 = "0.9"
[target.'cfg(target_os = "linux")'.dependencies]
# libavcodec (NVENC libav + VAAPI backends). `ffmpeg-sys-next` auto-detects the FFmpeg version.
ffmpeg-next = "8"
libc = "0.2"
# Vulkan bindings for the raw Vulkan-Video encode + PyroWave compute backends (feature-gated below;
# the dep stays unconditional to mirror the host's Linux target — unused-but-declared is harmless).
ash = "0.38"
# `libnvidia-encode.so.1` is dlopen'd at runtime for the direct-SDK NVENC/CUDA backend.
libloading = "0.8"
# Direct-SDK NVENC (raw `sys::nvEncodeAPI` types; entry points resolved at runtime). `ci-check` =
# vendored bindings, no CUDA toolkit at build.
nvidia-video-codec-sdk = { version = "0.4", features = ["ci-check"], optional = true }
# PyroWave (opt-in wired-LAN wavelet codec) — vendored codec + bindgen'd C API, only under `pyrowave`.
pyrowave-sys = { path = "../pyrowave-sys", optional = true }
[target.'cfg(target_os = "windows")'.dependencies]
# NVENC (direct SDK, D3D11 input) + the shared D3D11/DXGI vocabulary via pf-frame.
nvidia-video-codec-sdk = { version = "0.4", features = ["ci-check"], optional = true }
# AMD (AMF) + Intel (QSV) hardware encode via libavcodec (behind `amf-qsv`; link-imports FFmpeg).
ffmpeg-next = { version = "8", optional = true }
# `libnvidia-encode`/`nvEncodeAPI64.dll` resolved at runtime; the NVENC status→cause table dlopen.
libloading = "0.8"
windows = { version = "0.62", features = [
"Win32_Foundation",
"Win32_Graphics_Direct3D",
"Win32_Graphics_Direct3D11",
"Win32_Graphics_Dxgi",
"Win32_Graphics_Dxgi_Common",
"Win32_Storage_FileSystem",
"Win32_System_LibraryLoader",
"Win32_System_Threading",
] }
[features]
default = []
# NVENC hardware encode (Linux CUDA + Windows D3D11); entry points resolved at runtime.
nvenc = ["dep:nvidia-video-codec-sdk"]
# AMD (AMF) + Intel (QSV) hardware encode on Windows via libavcodec.
amf-qsv = ["dep:ffmpeg-next"]
# Raw Vulkan-Video HEVC/AV1 encode on Linux (reuses the `ash` bindings; no new dep).
vulkan-encode = []
# PyroWave — the opt-in wired-LAN intra-only wavelet codec (Linux encode backend).
pyrowave = ["dep:pyrowave-sys"]