4b5bca93a05a659bd692be1ac8749e0d8d88ac29
8
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
35c61fee64 |
chore(client): the windows-rs pin moves a month forward, onto the SDK-metadata bindings
The July 2026 windows-rs brings a reconciler keyed-child-order fix (#4728), widget validation (#4727), a DPI collision fix (#4751), icon elements (#4736), multi-window support (#4730) and scroll virtualization (#4710) — the re-render fixes the Windows client has been working around at the architecture level. All three pinned deps (windows-reactor, windows, windows-reactor-setup) move together so windows-core stays unified across the swap-chain hand-off, and pf-client-core moves with them. The bulk of the diff is #4689: windows/windows-sys now generate straight from the Windows SDK, so the `Win32_*` namespace features became one feature per SDK header (winuser, dxgi, d3d11, …), the PascalCase namespace modules became header-named modules, struct-returning COM methods take explicit out-params and return HRESULT, Win32 functions return their raw BOOL/HANDLE instead of Result, and flag constants are plain integers. Both crates' Win32 code is rewritten to that shape; behaviour is unchanged on every path. Riding along, all already stale before the bump: the README and the three Windows workflows stop claiming windows-reactor's build.rs needs CARGO_WORKSPACE_DIR (that build.rs no longer exists — staging moved to windows-reactor-setup via OUT_DIR); the README layout section stops describing modules that moved into the session binary long ago and gains the manual smoke checklist; the notices generator learns the SPDX for crates that ship license files without a `license` field, which turns windows-reactor-setup's UNKNOWN into MIT OR Apache-2.0; and the crate records its real rust-version (1.96) instead of inheriting the workspace's 1.82. Verified: cargo check/clippy/fmt clean on punktfunk-client-windows, pf-client-core and punktfunk-client-session; both bins build; --discover finds the LAN hosts; the GUI shell comes up (WinAppSDK bootstrap intact under the new reactor-setup). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
8a5a5edc37 |
fix(small crates): the proof lint now covers every first-party crate but one
Six crates were still unguarded, and all six are OURS — none vendored: pf-console-ui, pf-gpu, punktfunk-tray, clients/windows, tools/display-disturb, wdk-probe. Two of them ship (the tray and the Windows client), so "small" was about item count, not exposure. Five are closed here. Only 17 of their 75 unsafe items actually lacked a proof — pf-gpu, punktfunk-tray and display-disturb were already fully documented and needed nothing but the deny, which is the good case: the convention was being followed, just not enforced. The 17 that were missing are the usual Win32/COM shapes, and two were worth stating properly. `clients/windows`'s `GetCurrentPackageFullName` is called with `len = 0` and no buffer — that is the documented identity PROBE, which writes nothing, and reading it as a normal query would be a mistake. `pf-console-ui`'s two `destroy_image_view` calls are the load-bearing ones: the comment above one already argued that in-flight sampling of that slot ended two presents ago (the ring alternates and the presenter waits its fence before each record), which is exactly the kind of reasoning a `// SAFETY:` should carry and it was sitting there unlabelled. Also fixes a real Windows-only clippy error this uncovered: `pf-gpu` had a `#[cfg(target_os = "windows")]` fn AFTER its `mod tests`, tripping `items_after_test_module`. It never fired on Linux (the item does not exist there) and no CI job clippies pf-gpu on Windows, so it sat unseen. Moved above the test module. Remaining: `wdk-probe` (26 items) alone, and only because it needs the WDK to build — .47 cannot, so nothing here can verify a deny on it. Verified: Linux .21 fmt + both CI clippy steps rc=0; Windows .47 the four Windows-relevant crates at `-D warnings` rc=0. |
||
|
|
1d587a259e |
fix(client/d3d11va): green bar at the bottom — clamp the blit to the frame
ci / web (push) Successful in 47s
ci / docs-site (push) Successful in 1m8s
apple / swift (push) Successful in 1m18s
decky / build-publish (push) Successful in 23s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 10s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 13s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 9s
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 6m49s
ci / bench (push) Successful in 7m2s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 12s
docker / build-push (ci, ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 5m4s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 11s
apple / screenshots (push) Successful in 6m12s
deb / build-publish (push) Successful in 9m49s
android / android (push) Successful in 13m29s
windows-msix / package (x64, C:\Users\Public\ffmpeg, , x86_64-pc-windows-msvc, C:\t) (push) Successful in 6m53s
docker / deploy-docs (push) Successful in 27s
flatpak / build-publish (push) Successful in 6m32s
deb / build-publish-host (push) Successful in 13m26s
arch / build-publish (push) Successful in 17m13s
windows / build (aarch64-pc-windows-msvc) (push) Successful in 8m0s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 14m10s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 21m2s
ci / rust (push) Successful in 28m51s
windows / build (x86_64-pc-windows-msvc) (push) Successful in 9m0s
The decode surface is DXVA-aligned (height rounded up to the profile's
alignment, 128 for HEVC/AV1), so it is taller than the frame: a 2400-line
stream decodes into a 2432-line texture. VideoProcessorBlt was called with
no stream source rect, so it blitted the WHOLE surface — the uninitialized
padding rows (NV12 Y=0,U=V=0, which converts to vivid green) landed at the
bottom of the output and the picture was squashed to fit. Set the source
rect to the real frame.
Pre-existing on this backend, but
|
||
|
|
ef5808254a |
refactor(windows): remove the legacy in-process builtin stream path
The real Windows client is the spawned punktfunk-session Vulkan binary (pf-client-core); the in-process builtin GUI stream — reachable only via PUNKTFUNK_BUILTIN_STREAM=1 — was dead weight kept alive by nothing and a recurring source of wasted effort. Remove it: delete present/render/input/ audio.rs and the builtin remainder of session/video.rs, rip all the builtin wiring (app/mod, connect, stream), and make connect always spawn. Preserve the two shipped keepers that happened to live in those files by relocating them to a new probe.rs: run_speed_probe (the per-host network speed test used by the Settings speed page and --headless --speed-test) and decodable_codecs (the codec-capability advert on the probe connect). Trim gpu.rs to just the Settings adapter picker (adapter_names + helpers). --headless now supports only --speed-test — the in-process decode/frame-counter went with the pump. Drops the now-orphaned deps opus, wasapi, crossbeam-channel, anyhow; keeps ffmpeg-next (probe::decodable_codecs still needs it). Net 4432 deletions. Statically verified (module wiring, imports, orphaned symbols/deps all clean); the type-level compile runs on the windows-amd64 CI runner, which has the toolchain this non-Windows host lacks. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
9d6798b8e0 |
feat(clients/windows): GPU picker, disconnect shortcut, richer stream HUD
- Settings gains a GPU selector (shown only on multi-GPU boxes): the picked DXGI adapter drives decode + present, persisted as Settings.adapter and applied at the next stream - gpu.rs now caches the shared device keyed by the resolved preference (env PUNKTFUNK_ADAPTER > Settings > the window's monitor's adapter) so a change needs no app restart. - Ctrl+Alt+Shift+D disconnects the session (consumed locally, captured or released): the hook releases capture and trips the session stop flag, plumbed through the stream-page handoff; the pump winds down and the UI navigates back to the host list. - Stream HUD extended: codec chip (HEVC/H.264/AV1), display-side line from the render thread (presents/s + capture-to-decoded vs capture-to-on-glass p50), session line (host name, duration, network-lost frames, skipped backlog frames), and both shortcut hints incl. the new disconnect. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
1f5a2e4920 |
feat(clients/windows): all-vendor video pipeline rewrite + app icon + hosts-page tiles
Decode+present rewrite (first real pixels on glass for this client): - Decode: FFmpeg D3D11VA on NVIDIA/AMD/Intel. get_format now only returns AV_PIX_FMT_D3D11 and lets libavcodec build the decode pool from hw_device_ctx (hand-built frames contexts failed three different ways: NVIDIA rejects DECODER|SHADER_RESOURCE arrays, BindFlags=0 fails texture creation, Intel rejects non-128-aligned HEVC surfaces at the first SubmitDecoderBuffers). A DXVA profile probe before the hwdevice commits hardware-vs-software up front instead of burning the opening IDR; extra_hw_frames covers the frames the client holds. - Present: the decoded slice is copied with ONE display-size-boxed CopySubresourceRegion (a planar slice is a single subresource in D3D11; the old two-copy D3D12-style code silently no-opped - the black screen) into a sampleable NV12/P010 texture, per-plane SRVs + YUV->RGB shaders. - New dedicated render thread (render.rs): presenting is decoupled from the XAML thread; frame-latency-waitable swapchain + SetMaximumFrameLatency(1), newest-wins drain after the wait, crossbeam frame channel with pts for a capture->presented p50 log. - HiDPI: pixel-sized buffers + SetMatrixTransform(96/dpi) - was blurry at 125/150 % scaling. - Software fallback now feeds the same shaders (swscale -> NV12/P010 planes -> two dynamic plane textures); ps_rgba/X2BGR10 path deleted, hw/sw colour math identical. - Adapter selection for hybrid boxes: PUNKTFUNK_ADAPTER > the window's monitor's adapter > default; PUNKTFUNK_D3D_DEBUG=1 debug layer. - Session pump: request_keyframe at start and on hw->sw demotion (infinite GOP would otherwise sit on a black screen). Validated live on the Arc Pro + RTX 3500 Ada laptop against the local Windows host: 60 fps D3D11VA on both vendors, software path, GUI on glass. Also: embedded app icon (build.rs winresource + WM_SETICON, MSIX Square44x44 targetsize assets, pack-msix stages them) and the hosts-page tile rework (tap-to-connect tiles with sibling overflow menu - fixes forget-also-connects - in-tile rename editor, add-host modal via root state). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
d364a4ee7c |
fix(windows-client): clear clippy -D warnings on MSVC
The cfg(windows) code can't be lint-checked on the Linux dev box, so three -D warnings slipped through (caught by windows.yml; the FFI + shaders compiled fine): - gpu.rs: SetMultithreadProtected returns a must-use BOOL -> `let _ =`. - video.rs: drop the unused GpuFrame::ten_bit field (present keys off `hdr`; the value is still computed locally for the first-frame log). - present.rs: GpuView::frame is an RAII keep-alive (its Drop returns the decoder surface to the pool), never read -> #[allow(dead_code)]. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
ead3f8a306 |
feat(windows-client): D3D11VA zero-copy hw decode + HDR10 present + GUI polish
The client was pure software HEVC decode + CPU swscale->RGBA + a full-frame
dynamic-texture upload every frame -- the reason performance was poor on a GPU
box (the GPU sat idle while the CPU churned). This adds a hardware path, HDR,
and a GUI pass.
Performance -- D3D11VA zero-copy:
- gpu.rs (new): one D3D11 device (hardware + VIDEO_SUPPORT, WARP fallback,
multithread-protected) shared by decoder and presenter via a Send/Sync
OnceLock. Sharing is mandatory -- a decoded texture is only bindable on the
device that created it. windows-rs COM interfaces are !Send/!Sync, so the
unsafe impl is sound only under the multithread protection + disjoint
decode(video ctx)/present(immediate ctx) split.
- video.rs: D3d11vaDecoder (raw FFI mirroring the Linux VAAPI module). The
COM-typed AVD3D11VA{Device,Frames}Context are declared here (stable FFmpeg
ABI) to avoid ffmpeg-sys binding the d3d11 headers; get_format builds a frames
ctx with BindFlags=SHADER_RESOURCE so the NV12/P010 array slices are
sampleable. av_frame_clone guard keeps each surface out of the reuse pool
until the presenter drops it. Software decode stays as the fallback
(DecoderPref Auto/Hardware/Software; auto falls back on init/decode error).
- present.rs: shared device; per-plane SRVs over the array slice
(NV12->R8/R8G8, P010->R16/R16G16) + three pixel shaders (RGBA passthrough,
NV12/BT.709, P010/BT.2020-PQ). present() now takes the frame by value so the
GPU surface survives re-presents.
HDR:
- Detected in-band (transfer == SMPTE2084), same signal as the other clients.
Swapchain flips to R10G10B10A2 + ST.2084 + HDR10 metadata. New Settings toggle
gates advertising VIDEO_CAP_10BIT|HDR; host still gates 10-bit behind its own
PUNKTFUNK_10BIT + actual-HDR-content checks.
GUI (windows-reactor):
- Host cards with accent-monogram avatars + colored status pills, InfoBar for
errors/pairing hints, ToggleSwitch settings (+ HDR, decoder, bitrate), button
icons, a richer connecting screen, and a stream HUD with GPU/CPU-decode + HDR
status chips.
Not yet on-glass validated: the Linux dev box can't compile the cfg(windows)
code (ffmpeg/windows crates unfetched; WARP has no hw decode) -- only
cargo fmt checks it here. API shapes verified against the windows-rs/reactor
source and the YUV->RGB coefficients checked by hand, but D3D11VA + shaders +
the GUI need a real build (Windows CI / build VM) and on-glass test on the RTX
box. The host-side HDR encode path is unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|