Nix configurations for my homelab
0

Configure Feed

Select the types of activity you want to include in your feed.

at main 3.6 kB View raw
1From 8142629da7fd5e400fd00658d5ddaa8ea78cba53 Mon Sep 17 00:00:00 2001 2From: CToID <funk443@icloud.com> 3Date: Sun, 5 Apr 2026 23:24:45 +0800 4Subject: [PATCH] screencast: drive the Pipewire graph by ourselves. 5 6--- 7 src/screencast/pipewire_screencast.c | 56 +++++++++++++++++----------- 8 1 file changed, 35 insertions(+), 21 deletions(-) 9 10diff --git a/src/screencast/pipewire_screencast.c b/src/screencast/pipewire_screencast.c 11index 102a0f2b..04f3341b 100644 12--- a/src/screencast/pipewire_screencast.c 13+++ b/src/screencast/pipewire_screencast.c 14@@ -16,6 +16,7 @@ 15 #include "wlr_screencast.h" 16 #include "xdpw.h" 17 #include "logger.h" 18+#include "timespec_util.h" 19 20 #define DAMAGE_REGION_COUNT 16 21 22@@ -328,6 +329,31 @@ void xdpw_pwr_enqueue_buffer(struct xdpw_screencast_instance *cast) { 23 cast->current_frame.pw_buffer = NULL; 24 } 25 26+static void pwr_capture_one(void *data) { 27+ struct xdpw_screencast_instance *cast = data; 28+ 29+ if (!cast->pwr_stream_state) { 30+ logprint(INFO, "pipewire: not streaming"); 31+ return; 32+ } 33+ 34+ if (cast->current_frame.pw_buffer) { 35+ logprint(DEBUG, "pipewire: buffer already exported"); 36+ goto trigger_graph; 37+ } 38+ 39+ xdpw_pwr_dequeue_buffer(cast); 40+ if (!cast->current_frame.pw_buffer) { 41+ logprint(WARN, "pipewire: unable to export buffer"); 42+ goto trigger_graph; 43+ } 44+ 45+ xdpw_wlr_frame_capture(cast); 46+ 47+trigger_graph: 48+ pw_stream_trigger_process(cast->stream); 49+} 50+ 51 void pwr_update_stream_param(struct xdpw_screencast_instance *cast) { 52 logprint(TRACE, "pipewire: stream update parameters"); 53 struct pw_stream *stream = cast->stream; 54@@ -359,6 +385,7 @@ static void pwr_handle_stream_state_changed(void *data, 55 switch (state) { 56 case PW_STREAM_STATE_STREAMING: 57 cast->pwr_stream_state = true; 58+ pwr_capture_one(cast); 59 break; 60 case PW_STREAM_STATE_PAUSED: 61 if (old == PW_STREAM_STATE_STREAMING) { 62@@ -586,27 +613,13 @@ static void pwr_handle_stream_remove_buffer(void *data, struct pw_buffer *buffer 63 buffer->user_data = NULL; 64 } 65 66-static void pwr_handle_stream_on_process(void *data) { 67+static void pwr_handle_stream_trigger_done(void *data) { 68 struct xdpw_screencast_instance *cast = data; 69- 70- logprint(TRACE, "pipewire: on process event handle"); 71- 72- if (!cast->pwr_stream_state) { 73- logprint(INFO, "pipewire: not streaming"); 74- return; 75- } 76- 77- if (cast->current_frame.pw_buffer) { 78- logprint(DEBUG, "pipewire: buffer already exported"); 79- return; 80+ uint64_t delay_ns = fps_limit_measure_end(&cast->fps_limit, cast->framerate); 81+ if (delay_ns <= 0) { 82+ delay_ns = (1.0 / cast->framerate) * TIMESPEC_NSEC_PER_SEC; 83 } 84- 85- xdpw_pwr_dequeue_buffer(cast); 86- if (!cast->current_frame.pw_buffer) { 87- logprint(WARN, "pipewire: unable to export buffer"); 88- return; 89- } 90- xdpw_wlr_frame_capture(cast); 91+ xdpw_add_timer(cast->ctx->state, delay_ns, pwr_capture_one, cast); 92 } 93 94 static const struct pw_stream_events pwr_stream_events = { 95@@ -615,7 +628,7 @@ static const struct pw_stream_events pwr_stream_events = { 96 .param_changed = pwr_handle_stream_param_changed, 97 .add_buffer = pwr_handle_stream_add_buffer, 98 .remove_buffer = pwr_handle_stream_remove_buffer, 99- .process = pwr_handle_stream_on_process, 100+ .trigger_done = pwr_handle_stream_trigger_done, 101 }; 102 103 void xdpw_pwr_stream_create(struct xdpw_screencast_instance *cast) { 104@@ -652,7 +665,8 @@ void xdpw_pwr_stream_create(struct xdpw_screencast_instance *cast) { 105 pw_stream_connect(cast->stream, 106 PW_DIRECTION_OUTPUT, 107 PW_ID_ANY, 108- PW_STREAM_FLAG_ALLOC_BUFFERS, 109+ (PW_STREAM_FLAG_ALLOC_BUFFERS | 110+ PW_STREAM_FLAG_DRIVER), 111 params.data, params.size / sizeof(struct spa_pod *)); 112 113 spa_pod_dynamic_builder_clean(&builder);