* feat(linux/xdgportal): implement reactive capture with duplicate detection
Replaces polling-based frame capture with event-driven approach using
condition variables for immediate notification when new frames arrive.
Changes:
- on_process: Notify snapshot() via condition variable on new buffer
- fill_img: Extract and pass through PipeWire seq/pts metadata
- snapshot: Block on condition variable with timeout; detect and skip
duplicate frames using seq/pts metadata to avoid redundant processing
- capture: Simplify catch-up logic to maintain timeline consistency
by advancing in delay intervals without resetting origin
This eliminates tight polling loops and reduces unnecessary frame
processing when compositor reuses buffers.
* feat(linux/xdgportal): optimize software path and fix modesetting crashes
This patch addresses a performance bottleneck in the software encoding
path and a race condition during PipeWire stream re-initialization.
1. Performance Optimization (Double-Buffering):
- Implemented a front/back buffer swapping strategy for the software
(MemPtr) path.
- Frame data is copied to a `back_buffer` without holding the
`frame_mutex`, then swapped with the `front_buffer` under a
short-lived lock.
- This prevents memory bandwidth contention and allows the encoder
and PipeWire threads to work in parallel without blocking.
2. Stability Fixes:
- Implemented `frame_mutex` protection across `on_process`, `fill_img`,
and `cleanup_stream` to prevent use-after-free and dangling pointers
during resolution changes.
- Enhanced `fill_img` to safely bail out if the stream is dead or
no new frame is ready.
- Added explicit state resets (`frame_ready = false`, `current_buffer = nullptr`)
to ensure the encoder thread ignores stale data during re-init.
Fixes intermittent segfaults during resolution changes and restores
performance on systems using software encoding.
* feat(linux/xdgportal): support x-nv-video[0].clientRefreshRateX100 for requesting fractional NTSC framerates
* fix(linux/xdgportal): improve dbus & pipewire teardown logic
* Close dbus proxy connection; fixes orphaned XDG notification icons after
mode changes or stream pauses via XDG icon interaction.
* Migrate shared pipewire destructor logic into cleanup_stream() to reduce
duplication.
---------
Co-authored-by: Andy Grundman <andy@hybridized.org>