From 4484e059e17a6e2de9ec833bdc1423a88beb4711 Mon Sep 17 00:00:00 2001 From: PancakeTAS Date: Wed, 28 Aug 2024 02:29:08 +0200 Subject: [PATCH] linux-pipewire: Fix 10- and 16-bit captures --- plugins/linux-pipewire/pipewire.c | 30 +++++++++++++++++++--- plugins/linux-pipewire/screencast-portal.c | 2 +- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/plugins/linux-pipewire/pipewire.c b/plugins/linux-pipewire/pipewire.c index 0bf2d2ecec3c1f..d5bca765739f51 100644 --- a/plugins/linux-pipewire/pipewire.c +++ b/plugins/linux-pipewire/pipewire.c @@ -804,8 +804,9 @@ static void process_video_sync(obs_pipewire_stream *obs_pw_stream) obs_pw_stream->texture = gs_texture_create_from_dmabuf( obs_pw_stream->format.info.raw.size.width, obs_pw_stream->format.info.raw.size.height, - obs_pw_video_format.drm_format, GS_BGRX, planes, fds, - strides, offsets, use_modifiers ? modifiers : NULL); + obs_pw_video_format.drm_format, + obs_pw_video_format.gs_format, planes, fds, strides, + offsets, use_modifiers ? modifiers : NULL); if (obs_pw_stream->texture == NULL) { remove_modifier_from_format( @@ -1355,8 +1356,20 @@ void obs_pipewire_stream_video_render(obs_pipewire_stream *obs_pw_stream, if (!obs_pw_stream->texture) return; + effect = obs_get_base_effect(OBS_EFFECT_OPAQUE); + gs_technique_t *tech = gs_effect_get_technique(effect, "DrawSrgbDecompress"); + gs_technique_begin(tech); + gs_technique_begin_pass(tech, 0); + + const bool linear_srgb = gs_get_linear_srgb(); + const bool previous = gs_framebuffer_srgb_enabled(); + gs_enable_framebuffer_srgb(linear_srgb); + image = gs_effect_get_param_by_name(effect, "image"); - gs_effect_set_texture(image, obs_pw_stream->texture); + if (linear_srgb) + gs_effect_set_texture_srgb(image, obs_pw_stream->texture); + else + gs_effect_set_texture(image, obs_pw_stream->texture); rotated = push_rotation(obs_pw_stream); @@ -1396,7 +1409,11 @@ void obs_pipewire_stream_video_render(obs_pipewire_stream *obs_pw_stream, gs_matrix_push(); gs_matrix_translate3f(cursor_x, cursor_y, 0.0f); - gs_effect_set_texture(image, obs_pw_stream->cursor.texture); + if (linear_srgb) + gs_effect_set_texture(image, obs_pw_stream->cursor.texture); + else + gs_effect_set_texture_srgb(image, + obs_pw_stream->cursor.texture); gs_draw_sprite(obs_pw_stream->texture, 0, obs_pw_stream->cursor.width, obs_pw_stream->cursor.height); @@ -1405,6 +1422,11 @@ void obs_pipewire_stream_video_render(obs_pipewire_stream *obs_pw_stream, } gs_blend_state_pop(); + + gs_enable_framebuffer_srgb(previous); + + gs_technique_end_pass(tech); + gs_technique_end(tech); } void obs_pipewire_stream_set_cursor_visible(obs_pipewire_stream *obs_pw_stream, diff --git a/plugins/linux-pipewire/screencast-portal.c b/plugins/linux-pipewire/screencast-portal.c index a5cdec7265761f..ceea604aab0408 100644 --- a/plugins/linux-pipewire/screencast-portal.c +++ b/plugins/linux-pipewire/screencast-portal.c @@ -828,7 +828,7 @@ void screencast_portal_load(void) const struct obs_source_info screencast_portal_capture_info = { .id = "pipewire-screen-capture-source", .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_VIDEO, + .output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_SRGB, .get_name = screencast_portal_desktop_capture_get_name, .create = screencast_portal_capture_create, .destroy = screencast_portal_capture_destroy,