From ae0ea12e99115010c88c473b8cdf706267130225 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Thu, 9 Jul 2026 15:33:06 +0200 Subject: [PATCH] screencast: raise pipewire buffer pool from 2 to 4 buffers The ext_image_copy_capture_v1 backend negotiates a PipeWire buffer pool via SPA_POD_CHOICE_RANGE_Int(XDPW_PWR_BUFFERS, XDPW_PWR_BUFFERS_MIN, 32), and both constants are hardcoded to 2. With only two buffers, some consumers (observed with Chromium's and Firefox's PipeWire screencast source, both via WebRTC getDisplayMedia) end up holding both buffers at once, so pw_stream_dequeue_buffer() returns NULL and xdpw stops delivering new frames. This does not crash or log an error: the portal service and the PipeWire node both stay in a nominally healthy state, so the capture silently freezes on the last successfully delivered frame while consuming near-zero CPU/bandwidth. The freeze is easy to miss from the portal side alone since nothing errors, but is clearly visible in the consumer's own encoder stats: in a Chromium chrome://webrtc-internals capture, framesPerSecond collapsed from ~30 to exactly 1 within seconds to a couple of minutes of the screen share starting, and keyFramesEncoded stopped incrementing entirely for the rest of the session (13+ minutes observed), while frame dimensions and encoder implementation stayed correct throughout. OBS, which drives its own consumption loop differently, was unaffected on the same system. Raising XDPW_PWR_BUFFERS and XDPW_PWR_BUFFERS_MIN from 2 to 4 gives the consumer enough headroom to hold onto buffers briefly without starving the producer, and resolves the freeze. force_mod_linear does not help, since explicit-modifier negotiation bypasses it. Reproduced on two independent systems: sway 1.12 / wlroots 0.19-0.20 on AMD (amdgpu), and a second system on NixOS; both on xdg-desktop-portal-wlr 0.8.3 after the ext_image_copy_capture_v1 switch. Confirmed on the first system across both Chromium and Firefox, ruling out a browser-specific cause, and with GPU, CPU and network load, loss and latency all ruled out as contributing factors. Closes: https://github.com/emersion/xdg-desktop-portal-wlr/issues/395 Signed-off-by: Thomas Glanzmann Assisted-by: Claude Sonnet 5 (Anthropic) --- include/pipewire_screencast.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/pipewire_screencast.h b/include/pipewire_screencast.h index f8cd88e..227d51d 100644 --- a/include/pipewire_screencast.h +++ b/include/pipewire_screencast.h @@ -3,8 +3,8 @@ #include "screencast_common.h" -#define XDPW_PWR_BUFFERS 2 -#define XDPW_PWR_BUFFERS_MIN 2 +#define XDPW_PWR_BUFFERS 4 +#define XDPW_PWR_BUFFERS_MIN 4 #define XDPW_PWR_ALIGN 16 void xdpw_pwr_enqueue_buffer(struct xdpw_screencast_instance *cast); -- 2.53.0