Projects
Multimedia
obs-vkcapture
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 4
View file
obs-vkcapture.changes
Changed
@@ -1,4 +1,10 @@ ------------------------------------------------------------------- +Wed Feb 25 12:35:48 UTC 2026 - Sqx. Flann <fl4nn@opensuse.org> + +- Update to version 1.5.5 + * Improve HDR support + +------------------------------------------------------------------- Wed Aug 27 14:51:00 UTC 2025 - Sqx. Flann <fl4nn@opensuse.org> - Update to version 1.5.3
View file
obs-vkcapture.spec
Changed
@@ -1,5 +1,5 @@ Name: obs-vkcapture -Version: 1.5.3 +Version: 1.5.5 Release: 0 Summary: OBS plugin for Vulkan/OpenGL game capture on Linux License: GPL-2.0-only @@ -11,6 +11,7 @@ BuildRequires: pkgconfig(vulkan) BuildRequires: pkgconfig(gl) BuildRequires: pkgconfig(egl) +BuildRequires: pkgconfig(simde) BuildRequires: pkgconfig(xcb) BuildRequires: pkgconfig(wayland-client) BuildRequires: pkgconfig(wayland-scanner)
View file
obs-vkcapture-1.5.3.tar.gz/.github/workflows/main.yml -> obs-vkcapture-1.5.5.tar.gz/.github/workflows/main.yml
Changed
@@ -20,7 +20,7 @@ run: | sudo add-apt-repository ppa:obsproject/obs-studio sudo apt update - sudo apt install libvulkan-dev obs-studio libgl-dev libegl-dev libx11-dev libxcb1-dev libxcb-xfixes0-dev libwayland-dev libwayland-bin + sudo apt install libvulkan-dev obs-studio libgl-dev libegl-dev libx11-dev libxcb1-dev libxcb-xfixes0-dev libwayland-dev libwayland-bin libsimde-dev - name: Configure run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
View file
obs-vkcapture-1.5.3.tar.gz/CMakeLists.txt -> obs-vkcapture-1.5.5.tar.gz/CMakeLists.txt
Changed
@@ -2,7 +2,7 @@ project(obs-vkcapture LANGUAGES C - VERSION 1.5.3) + VERSION 1.5.5) include(GNUInstallDirs) find_package(Vulkan REQUIRED)
View file
obs-vkcapture-1.5.3.tar.gz/data/locale/cs-CZ.ini -> obs-vkcapture-1.5.5.tar.gz/data/locale/cs-CZ.ini
Changed
@@ -5,4 +5,3 @@ CaptureAnyWindow="Zaznamenávat jakékoliv okno" CaptureAnyWindowExcept="Zaznamenávat jakékoliv okno kromě" AllowTransparency="Povolit průhlednost" -ForceHDR="Vynutit HDR"
View file
obs-vkcapture-1.5.3.tar.gz/data/locale/en-US.ini -> obs-vkcapture-1.5.5.tar.gz/data/locale/en-US.ini
Changed
@@ -5,4 +5,3 @@ CaptureAnyWindow="Capture any window" CaptureAnyWindowExcept="Capture any window except" AllowTransparency="Allow Transparency" -ForceHDR="Force HDR"
View file
obs-vkcapture-1.5.3.tar.gz/data/locale/fr-FR.ini -> obs-vkcapture-1.5.5.tar.gz/data/locale/fr-FR.ini
Changed
@@ -5,4 +5,3 @@ CaptureAnyWindow="Capturer n'importe quelle fenêtre" CaptureAnyWindowExcept="Capturer n'importe quelle fenêtre sauf" AllowTransparency="Autoriser la transparence" -ForceHDR="Forcer l'HDR"
View file
obs-vkcapture-1.5.3.tar.gz/data/locale/pt-BR.ini -> obs-vkcapture-1.5.5.tar.gz/data/locale/pt-BR.ini
Changed
@@ -5,4 +5,3 @@ CaptureAnyWindow="Capturar qualquer janela" CaptureAnyWindowExcept="Capturar qualquer janela exceto" AllowTransparency="Permitir transparência" -ForceHDR="Forçar HDR"
View file
obs-vkcapture-1.5.3.tar.gz/src/vkcapture.c -> obs-vkcapture-1.5.5.tar.gz/src/vkcapture.c
Changed
@@ -53,6 +53,10 @@ static uint8_t gl_device_uuid16; void (*p_glGetUnsignedBytei_vEXT)(unsigned int target, unsigned int index, unsigned char *data) = NULL; +#define VK_COLOR_SPACE_SRGB_NONLINEAR_KHR 0 +#define VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT 1000104002 +#define VK_COLOR_SPACE_HDR10_ST2084_EXT 1000104008 + enum vkcapture_import_attempt { IMPORT_DEFAULT = 0, IMPORT_NO_MODIFIERS = 1, @@ -96,7 +100,6 @@ #endif bool show_cursor; bool allow_transparency; - bool force_hdr; bool window_match; bool window_exclude; const char *window; @@ -324,7 +327,6 @@ ctx->show_cursor = obs_data_get_bool(settings, "show_cursor"); ctx->allow_transparency = obs_data_get_bool(settings, "allow_transparency"); - ctx->force_hdr = obs_data_get_bool(settings, "force_hdr"); ctx->window_match = false; ctx->window_exclude = false; @@ -359,8 +361,8 @@ { vkcapture_client_t *client = NULL; if (ctx->window) { - for (size_t i = 0; i < server.clients.num; i++) { - vkcapture_client_t *c = server.clients.array + i; + for (size_t i = server.clients.num; i > 0; i--) { + vkcapture_client_t *c = server.clients.array + i - 1; bool match = !strcmp(c->cdata.exe, ctx->window); if ((ctx->window_match && match) || (ctx->window_exclude && !match)) { client = c; @@ -368,7 +370,7 @@ } } } else if (server.clients.num) { - client = server.clients.array; + client = server.clients.array + server.clients.num - 1; } return client; } @@ -562,23 +564,105 @@ ioctl(fd, DMA_BUF_IOCTL_SYNC, &sync); } - const enum gs_color_space color_space = gs_get_color_space(); - const bool linear_srgb = gs_get_linear_srgb(); - const char *tech_name = linear_srgb ? "DrawSrgbDecompress" : "Draw"; + enum gs_color_space source_space = GS_CS_SRGB; + const bool is_pq = ctx->tdata.color_space == VK_COLOR_SPACE_HDR10_ST2084_EXT; + if (is_pq) + source_space = GS_CS_709_EXTENDED; + else if (ctx->tdata.color_space == VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT) + source_space = GS_CS_709_SCRGB; + + const enum gs_color_space current_space = gs_get_color_space(); + bool linear_sample = !gs_get_linear_srgb(); + const char *tech_name = "Draw"; float multiplier = 1.f; - if (color_space == GS_CS_709_EXTENDED) { - tech_name = "DrawPQ"; - multiplier = 10000.f / obs_get_video_sdr_white_level(); + switch (source_space) { + case GS_CS_SRGB: + switch (current_space) { + case GS_CS_SRGB: + if (ctx->allow_transparency && !linear_sample) + tech_name = "DrawSrgbDecompress"; + break; + case GS_CS_SRGB_16F: + case GS_CS_709_EXTENDED: + if (!linear_sample) + tech_name = "DrawSrgbDecompress"; + break; + case GS_CS_709_SCRGB: + if (linear_sample) + tech_name = "DrawMultiply"; + else + tech_name = "DrawSrgbDecompressMultiply"; + multiplier = obs_get_video_sdr_white_level() / 80.f; + } + break; + case GS_CS_SRGB_16F: + linear_sample = true; + switch (current_space) { + case GS_CS_SRGB: + case GS_CS_SRGB_16F: + case GS_CS_709_EXTENDED: + tech_name = is_pq ? "DrawSrgbDecompress" : "Draw"; + break; + case GS_CS_709_SCRGB: + tech_name = is_pq ? "DrawSrgbDecompressMultiply" : "DrawMultiply"; + multiplier = obs_get_video_sdr_white_level() / 80.f; + } + break; + case GS_CS_709_EXTENDED: + linear_sample = true; + if (is_pq) { + switch (current_space) { + case GS_CS_SRGB: + case GS_CS_SRGB_16F: + tech_name = "DrawTonemapPQ"; + multiplier = 10000.f / obs_get_video_sdr_white_level(); + break; + case GS_CS_709_EXTENDED: + tech_name = "DrawPQ"; + multiplier = 10000.f / obs_get_video_sdr_white_level(); + break; + case GS_CS_709_SCRGB: + tech_name = "DrawPQ"; + multiplier = 10000.f / 80.f; + } + } else { + switch (current_space) { + case GS_CS_SRGB: + case GS_CS_SRGB_16F: + tech_name = "DrawTonemap"; + break; + case GS_CS_709_SCRGB: + tech_name = "DrawMultiply"; + multiplier = obs_get_video_sdr_white_level() / 80.f; + default: + break; + } + } + break; + case GS_CS_709_SCRGB: + linear_sample = true; + switch (current_space) { + case GS_CS_SRGB: + case GS_CS_SRGB_16F: + tech_name = "DrawMultiplyTonemap"; + multiplier = 80.f / obs_get_video_sdr_white_level(); + break; + case GS_CS_709_EXTENDED: + tech_name = "DrawMultiply"; + multiplier = 80.f / obs_get_video_sdr_white_level(); + default: + break; + } } effect = obs_get_base_effect(ctx->allow_transparency ? OBS_EFFECT_DEFAULT : OBS_EFFECT_OPAQUE); const bool previous = gs_framebuffer_srgb_enabled(); - gs_enable_framebuffer_srgb(linear_srgb); + gs_enable_framebuffer_srgb(ctx->allow_transparency || linear_sample); gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image"); - if (linear_srgb) + if (linear_sample) gs_effect_set_texture_srgb(image, ctx->texture); else gs_effect_set_texture(image, ctx->texture); @@ -591,11 +675,13 @@ } } + gs_enable_framebuffer_srgb(previous); + if (!ctx->allow_transparency && ctx->show_cursor) { effect = obs_get_base_effect(OBS_EFFECT_DEFAULT); tech_name = "Draw"; multiplier = 1.f; - if (color_space == GS_CS_709_SCRGB) { + if (current_space == GS_CS_709_SCRGB) { tech_name = "DrawMultiply"; multiplier = obs_get_video_sdr_white_level() / 80.f; } @@ -603,9 +689,9 @@ gs_effect_set_float(gs_effect_get_param_by_name(effect, "multiplier"), multiplier); cursor_render(ctx); } - } - gs_enable_framebuffer_srgb(previous); + gs_set_linear_srgb(previous); + } } static const char *vkcapture_source_get_name(void *data) @@ -629,7 +715,6 @@ { obs_data_set_default_bool(defaults, "show_cursor", true); obs_data_set_default_bool(defaults, "allow_transparency", false); - obs_data_set_default_bool(defaults, "force_hdr", false); } static obs_properties_t *vkcapture_source_get_properties(void *data) @@ -649,6 +734,17 @@ pthread_mutex_lock(&server.mutex); for (size_t i = 0; i < server.clients.num; i++) { vkcapture_client_t *client = server.clients.array + i; + + bool already_exists = false; + for (size_t j = 0; j < obs_property_list_item_count(p); j++) { + if (!strcmp(client->cdata.exe, obs_property_list_item_string(p, j))) { + already_exists = true; + } + } + if (already_exists) { + continue; + } + obs_property_list_add_string(p, client->cdata.exe, client->cdata.exe); if (ctx->window && !strcmp(client->cdata.exe, ctx->window)) { window_found = true; @@ -675,7 +771,6 @@ } obs_properties_add_bool(props, "allow_transparency", obs_module_text("AllowTransparency")); - obs_properties_add_bool(props, "force_hdr", obs_module_text("ForceHDR")); return props; } @@ -684,15 +779,29 @@ { vkcapture_source_t *ctx = data; - enum gs_color_space color_space = ctx->tdata.color_space; + enum gs_color_space capture_space = GS_CS_SRGB; + uint32_t color_space = ctx->tdata.color_space; - if (ctx->force_hdr) { - color_space = GS_CS_709_EXTENDED; + if (color_space == VK_COLOR_SPACE_HDR10_ST2084_EXT || color_space == VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT) { + for (size_t i = 0; i < count; ++i) { + if (preferred_spacesi == GS_CS_709_SCRGB) { + return GS_CS_709_SCRGB; + } + } + capture_space = GS_CS_709_EXTENDED; } - - UNUSED_PARAMETER(count); - UNUSED_PARAMETER(preferred_spaces); - return color_space; + // TODO: Maybe handle GS_CS_SRGB_16F? SDR for >8 bit format + + // Same as win-capture/game-capture.c + enum gs_color_space space = capture_space; + for (size_t i = 0; i < count; ++i) { + const enum gs_color_space preferred_space = preferred_spacesi; + space = preferred_space; + if (preferred_space == capture_space) { + break; + } + } + return space; } static struct obs_source_info vkcapture_input = {
View file
obs-vkcapture-1.5.3.tar.gz/src/vklayer.c -> obs-vkcapture-1.5.5.tar.gz/src/vklayer.c
Changed
@@ -588,24 +588,6 @@ return -1; } -static uint32_t vk_color_space_to_obs(VkColorSpaceKHR vk) -{ - const char *force = getenv("OBS_VKCAPTURE_COLOR_SPACE"); - if (force) { - int value = atoi(force); - if (value >= 0 && value < 3) { - return value; - } - } - switch (vk) { - case VK_COLOR_SPACE_HDR10_ST2084_EXT: - return 2; // GS_CS_709_EXTENDED - case VK_COLOR_SPACE_SRGB_NONLINEAR_KHR: - default: - return 0; // GS_CS_SRGB - } -} - static inline bool vk_shtex_init_vulkan_tex(struct vk_data *data, struct vk_swap_data *swap) { @@ -907,7 +889,7 @@ capture_init_shtex(swap->image_extent.width, swap->image_extent.height, vk_format_to_drm(swap->export_format), swap->dmabuf_strides, swap->dmabuf_offsets, swap->dmabuf_modifier, - swap->winid, /*flip*/false, vk_color_space_to_obs(swap->color_space), + swap->winid, /*flip*/false, swap->color_space, swap->dmabuf_nfd, swap->dmabuf_fds); hlog("------------------ vulkan capture started ------------------");
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.