Move shared-memory ownership, LGMP session handling, queue access, and
DMA setup behind a transport interface. The LGMP backend preserves the
existing zero-copy frame and DMA paths while owning its lgmp:* options.
Expose the initialized EGL context through a versioned renderer interop
record for future accelerated decode backends. Add an LGMP-independent,
deterministic test transport for graphics-pipeline validation.
Move LGMP queue tunables into LGMPConfig.h and keep compatibility
aliases in KVMFR.h. Promote color-transform, SDR white-level, and
damage-limit definitions to transport-neutral common types so non-LGMP
transports do not depend on the KVMFR wire format.
Model playback latency from the device period, arrival jitter, source
packet phase, and resampler delay. Treat audio:latencyOffset as an
explicit addition to this minimum and align the first device pull to
the next packet deadline. This starts playback near its steady-state
target without unnecessary prefill or startup underruns. Use a
512-frame default period as a practical low-latency baseline.
Replace the startup clock hold with a one-sided proportional
acquisition controller, then hand off to source/device rate
feed-forward and a slow phase loop. Calibrate the logical device
timeline at handoff, discard correction that opposes the current
error, and slew-limit rate changes. This prevents startup drain,
integral wind-up, overshoot, and long convergence while preserving
clock-drift compensation.
Allow audio backends to expose a real-time resampler and use
PipeWire's adaptive resampler when version 1.4 or newer supports it.
Retain libsamplerate as the fallback and add audio:resampler to select
the implementation. Wait for PipeWire stream setup to complete and
propagate rate-control failures cleanly.
Track PipeWire input-consumption and output-equivalent clocks
separately. The input clock measures ring latency while the output
clock drives feed-forward using the ratio that governed each request.
This removes delayed self-feedback that made adaptive resampling
oscillate between the correction limits.
Reduce audio:debug output to useful latency, clock, jitter, and xrun
values, and scale the playback graph from the startup estimate. Update
the option names and documentation for the new latency model.
Avoid querying playback timing on every graph cycle. Refresh backend
latency only when audio diagnostics request it, and defer callback
errors for reporting from non-realtime contexts.
Move microphone delivery to a bounded SPSC queue drained by a sender
thread. This keeps PureSpice locking and socket writes out of the
PipeWire capture callback while bounding overload behavior.
Validate and recycle capture buffers before enqueueing their contents.
These changes improve deadline margin when using small period sizes.
Bound playback writes and synchronization slews to the physical ring
storage, preventing overwritten samples from being treated as valid PCM.
Trigger clock resynchronization when output must be dropped.
Wait for enough startup audio to cover backend demand and a complete
source packet. Generate silence if playback begins early instead of
rewinding the reader into stale ring storage.
Honor PipeWire playback frame requests and fully initialize empty chunks.
This keeps playback reliable when using small device period sizes.
Drive playback timing from audio sample positions instead of packet
arrival cadence. Use SPICE multimedia timestamps to anchor streams,
detect discontinuities, and estimate the long-term source rate. Ignore
their coarse phase corrections when steering the playback buffer.
Measure the device clock independently and wait for it to stabilize
before enabling a bounded, slew-limited phase controller. Align startup
buffering from logical producer and consumer positions so backend
startup reserves do not become persistent latency.
Size the buffer from the backend period, measured delivery jitter, and
resampler delay. Update PipeWire and PulseAudio to report their actual
startup requirements and presentation latency. Default to a 10 ms
device period with 4 ms of additional buffering, and make detailed
synchronization diagnostics opt-in through audio:debug.
This reduces startup and steady-state latency while compensating for
physical and virtual device clock drift without reacting to transport
jitter or SPICE timestamp quantization.
Validate mastering primaries and luminance independently so one
unsupported component does not discard the other.
Trust content chromaticities when extended target volumes are supported,
and report the exact values and reason when metadata must be omitted.
The virtual display transports HDR pixels rather than emitting light.
Advertise approximately 10,000 nits for both peak and frame-average
luminance, and leave the physical black level unspecified.
This prevents Windows from mapping HDR into an arbitrary virtual
display limit before the frame reaches the real host display.
Monitor-default HDR metadata describes the virtual display rather than
the captured content. Do not expose it through KVMFR or use it to select
downstream processing limits.
Only publish explicit NEW frame metadata and otherwise use the complete
PQ range internally.
Convert HDR scRGB input to normalized linear Rec.2020 before CAS, then
convert the filtered result back to scRGB. Use the content metadata to
select an appropriate normalization peak while leaving SDR unchanged.
This follows AMD's documented recommendation for applying CAS to HDR
content and prevents HDR highlights from being clamped and dimmed.
PQ sources excluded every external filter from the post-process chain.
Decode PQ/BT.2020 into FP16 linear scRGB before active effects and pass
the resulting transfer state to the desktop shader.
Keep the raw PQ path when no effect is active. This avoids adding a
conversion pass or per-frame latency to the common case.
Describe PQ pixels with the protocol-defined primary luminance range and
keep mastering luminance in the target volume. Track extended target-volume
support and omit unsupported metadata instead of creating an invalid image
description.
Keep the reference white associated with the active PQ description until
a replacement is ready. If asynchronous description creation fails, the
renderer now retains the complete previous HDR state instead of combining
new white-level values with stale compositor metadata.
Convert FP16 scRGB captures to BT.2020 PQ before storing them in the
10-bit wire format. Preserve linear-light downsampling, publish the real
SDR white level and display metadata, and advance the format version when
those properties change.