Skip to content

Commit a7de3f4

Browse files
YaLTeRRytoEX
authored andcommitted
linux-pipewire: Dup syncobj fds
PipeWire format renegotiation runs in parallel with video rendering. When the stream format is renegotiated, PipeWire removes the existing buffers and closes the syncobj file descriptors. At the same time, the video rendering thread may try to import the (already closed) syncobj acquire fd, and hang on waiting for the fence to become available. This is not a problem for the dmabuf fd because it's imported into a texture right away, which doesn't disappear when PipeWire closes the fd. This commit adds duping to the syncobj fds so that they too remain open as long as the rendering thread may access them.
1 parent 7092bc1 commit a7de3f4

File tree

1 file changed

+12
-2
lines changed

1 file changed

+12
-2
lines changed

plugins/linux-pipewire/pipewire.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include <gio/gio.h>
2828
#include <gio/gunixfdlist.h>
29+
#include <glib/gstdio.h>
2930

3031
#include <fcntl.h>
3132
#include <glad/glad.h>
@@ -765,14 +766,18 @@ static void process_video_sync(obs_pipewire_stream *obs_pw_stream)
765766
}
766767

767768
#if PW_CHECK_VERSION(1, 2, 0)
769+
g_clear_fd(&obs_pw_stream->sync.acquire_syncobj_fd, NULL);
770+
g_clear_fd(&obs_pw_stream->sync.release_syncobj_fd, NULL);
771+
768772
if (synctimeline && (buffer->n_datas == (planes + 2))) {
769773
assert(buffer->datas[planes].type == SPA_DATA_SyncObj);
770774
assert(buffer->datas[planes + 1].type == SPA_DATA_SyncObj);
771775

772-
obs_pw_stream->sync.acquire_syncobj_fd = buffer->datas[planes].fd;
776+
obs_pw_stream->sync.acquire_syncobj_fd = fcntl(buffer->datas[planes].fd, F_DUPFD_CLOEXEC, 5);
773777
obs_pw_stream->sync.acquire_point = synctimeline->acquire_point;
774778

775-
obs_pw_stream->sync.release_syncobj_fd = buffer->datas[planes + 1].fd;
779+
obs_pw_stream->sync.release_syncobj_fd =
780+
fcntl(buffer->datas[planes + 1].fd, F_DUPFD_CLOEXEC, 5);
776781
obs_pw_stream->sync.release_point = synctimeline->release_point;
777782

778783
obs_pw_stream->sync.set = true;
@@ -1179,6 +1184,8 @@ obs_pipewire_stream *obs_pipewire_connect_stream(obs_pipewire *obs_pw, obs_sourc
11791184
obs_pw_stream->cursor.visible = connect_info->screencast.cursor_visible;
11801185
obs_pw_stream->framerate.set = connect_info->video.framerate != NULL;
11811186
obs_pw_stream->resolution.set = connect_info->video.resolution != NULL;
1187+
obs_pw_stream->sync.acquire_syncobj_fd = -1;
1188+
obs_pw_stream->sync.release_syncobj_fd = -1;
11821189

11831190
if (obs_pw_stream->framerate.set)
11841191
obs_pw_stream->framerate.fraction = *connect_info->video.framerate;
@@ -1409,6 +1416,9 @@ void obs_pipewire_stream_destroy(obs_pipewire_stream *obs_pw_stream)
14091416
g_clear_pointer(&obs_pw_stream->stream, pw_stream_destroy);
14101417
pw_thread_loop_unlock(obs_pw_stream->obs_pw->thread_loop);
14111418

1419+
g_clear_fd(&obs_pw_stream->sync.acquire_syncobj_fd, NULL);
1420+
g_clear_fd(&obs_pw_stream->sync.release_syncobj_fd, NULL);
1421+
14121422
clear_format_info(obs_pw_stream);
14131423
bfree(obs_pw_stream);
14141424
}

0 commit comments

Comments
 (0)