mirror of
https://github.com/obsproject/obs-studio.git
synced 2026-08-29 02:03:03 +08:00
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.
This commit is contained in:
committed by
Ryan Foster
parent
7092bc17db
commit
a7de3f4bde
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <gio/gunixfdlist.h>
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <glad/glad.h>
|
||||
@@ -765,14 +766,18 @@ static void process_video_sync(obs_pipewire_stream *obs_pw_stream)
|
||||
}
|
||||
|
||||
#if PW_CHECK_VERSION(1, 2, 0)
|
||||
g_clear_fd(&obs_pw_stream->sync.acquire_syncobj_fd, NULL);
|
||||
g_clear_fd(&obs_pw_stream->sync.release_syncobj_fd, NULL);
|
||||
|
||||
if (synctimeline && (buffer->n_datas == (planes + 2))) {
|
||||
assert(buffer->datas[planes].type == SPA_DATA_SyncObj);
|
||||
assert(buffer->datas[planes + 1].type == SPA_DATA_SyncObj);
|
||||
|
||||
obs_pw_stream->sync.acquire_syncobj_fd = buffer->datas[planes].fd;
|
||||
obs_pw_stream->sync.acquire_syncobj_fd = fcntl(buffer->datas[planes].fd, F_DUPFD_CLOEXEC, 5);
|
||||
obs_pw_stream->sync.acquire_point = synctimeline->acquire_point;
|
||||
|
||||
obs_pw_stream->sync.release_syncobj_fd = buffer->datas[planes + 1].fd;
|
||||
obs_pw_stream->sync.release_syncobj_fd =
|
||||
fcntl(buffer->datas[planes + 1].fd, F_DUPFD_CLOEXEC, 5);
|
||||
obs_pw_stream->sync.release_point = synctimeline->release_point;
|
||||
|
||||
obs_pw_stream->sync.set = true;
|
||||
@@ -1179,6 +1184,8 @@ obs_pipewire_stream *obs_pipewire_connect_stream(obs_pipewire *obs_pw, obs_sourc
|
||||
obs_pw_stream->cursor.visible = connect_info->screencast.cursor_visible;
|
||||
obs_pw_stream->framerate.set = connect_info->video.framerate != NULL;
|
||||
obs_pw_stream->resolution.set = connect_info->video.resolution != NULL;
|
||||
obs_pw_stream->sync.acquire_syncobj_fd = -1;
|
||||
obs_pw_stream->sync.release_syncobj_fd = -1;
|
||||
|
||||
if (obs_pw_stream->framerate.set)
|
||||
obs_pw_stream->framerate.fraction = *connect_info->video.framerate;
|
||||
@@ -1409,6 +1416,9 @@ void obs_pipewire_stream_destroy(obs_pipewire_stream *obs_pw_stream)
|
||||
g_clear_pointer(&obs_pw_stream->stream, pw_stream_destroy);
|
||||
pw_thread_loop_unlock(obs_pw_stream->obs_pw->thread_loop);
|
||||
|
||||
g_clear_fd(&obs_pw_stream->sync.acquire_syncobj_fd, NULL);
|
||||
g_clear_fd(&obs_pw_stream->sync.release_syncobj_fd, NULL);
|
||||
|
||||
clear_format_info(obs_pw_stream);
|
||||
bfree(obs_pw_stream);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user