From 43441a4d697bd7cb32a7f8bf57dad27c5844c222 Mon Sep 17 00:00:00 2001 From: Elliot Chen Date: Sat, 21 Jun 2025 17:35:48 +0900 Subject: [PATCH] pipewiresrc: fix sending last buffer failure if waiting operation exits in advance --- src/gst/gstpipewiresrc.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/gst/gstpipewiresrc.c b/src/gst/gstpipewiresrc.c index 0e9cab853..686ceb5de 100644 --- a/src/gst/gstpipewiresrc.c +++ b/src/gst/gstpipewiresrc.c @@ -1512,6 +1512,8 @@ gst_pipewire_src_create (GstPushSrc * psrc, GstBuffer ** buffer) GstBuffer *buf; gboolean update_time = FALSE, timeout = FALSE; GstCaps *caps = NULL; + struct timespec abstime = { 0, }; + bool have_abstime = false; pwsrc = GST_PIPEWIRE_SRC (psrc); @@ -1555,13 +1557,11 @@ gst_pipewire_src_create (GstPushSrc * psrc, GstBuffer ** buffer) update_time = TRUE; GST_LOG_OBJECT (pwsrc, "EOS, send last buffer"); break; - } else if (timeout) { - if (pwsrc->last_buffer != NULL) { - update_time = TRUE; - buf = gst_buffer_ref(pwsrc->last_buffer); - GST_LOG_OBJECT (pwsrc, "timeout, send keepalive buffer"); - break; - } + } else if (timeout && pwsrc->last_buffer != NULL) { + update_time = TRUE; + buf = gst_buffer_ref(pwsrc->last_buffer); + GST_LOG_OBJECT (pwsrc, "timeout, send keepalive buffer"); + break; } else { buf = dequeue_buffer (pwsrc); GST_LOG_OBJECT (pwsrc, "popped buffer %p", buf); @@ -1573,9 +1573,13 @@ gst_pipewire_src_create (GstPushSrc * psrc, GstBuffer ** buffer) } timeout = FALSE; if (pwsrc->keepalive_time > 0) { - struct timespec abstime; - pw_thread_loop_get_time(pwsrc->stream->core->loop, &abstime, - pwsrc->keepalive_time * SPA_NSEC_PER_MSEC); + if (!have_abstime) { + /* Record the time we want to timeout at once, for this loop -- the loop might get unrelated signal()s, + * and we don't want the keepalive time to get reset by that */ + pw_thread_loop_get_time(pwsrc->stream->core->loop, &abstime, + pwsrc->keepalive_time * SPA_NSEC_PER_MSEC); + have_abstime = TRUE; + } if (pw_thread_loop_timed_wait_full (pwsrc->stream->core->loop, &abstime) == -ETIMEDOUT) timeout = TRUE; } else {