Repository navigation
utils: Encode high-bit-depth sources to sRGB in screenshots - #16
Merged
Merged
Conversation
GetSourceScreenshot and SaveSourceScreenshot render the source with TakeSourceScreenshot(), which now lives in utils/SourceScreenshot.cpp as Utils::TakeSourceScreenshot(), so it can be tested on its own. No change in behaviour. Refs obs-rust/obs-studio#1141. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GetSourceScreenshot and SaveSourceScreenshot of a 10- or 12-bit source (P010, I010, I210, I412: HEVC Main10, VP9 profile 2, ProRes, 10-bit capture cards) came out too dark: orange (255, 96, 0) as (255, 30, 0), while the program output, the previews and recordings showed it right. libobs keeps these frames as linear float, and TakeSourceScreenshot() drew the source with linear sRGB off, so the linear values went into the 8-bit image unencoded. The source is now drawn with linear sRGB on when its colour space is not 8-bit sRGB, as scenes and the frontend previews draw it, so libobs encodes the colours to sRGB. 8-bit sources keep the direct path: their pixels and their straight (not premultiplied) alpha are unchanged. Refs obs-rust/obs-studio#1141. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 of 6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
GetSourceScreenshotandSaveSourceScreenshotof a 10- or 12-bit source (P010, I010, I210, I412: HEVC Main10, VP9 profile 2, ProRes, 10-bit capture cards) came out too dark: orange (255, 96, 0) as (255, 30, 0), mid grey 128 as 55, while the program output, the scene screenshot and recordings showed the right colours. libobs keeps these frames as a linear float texture (need_linear_output(),GS_CS_SRGB_16F), and the framebuffer's sRGB encode is only on while linear sRGB is on.TakeSourceScreenshot()drew the source on its own with linear sRGB off, so the linear values went into the 8-bit image unencoded. Scenes (render_item()) and the frontend's Properties/Filters/Interaction previews draw withgs_set_linear_srgb(true), which is why they were right. Found by our release check; no upstream report.Two commits:
utils: Move the source screenshot render into a helper:TakeSourceScreenshot()moves unchanged intosrc/utils/SourceScreenshot.cppasUtils::TakeSourceScreenshot(), so it can be tested on its own.utils: Encode high-bit-depth sources to sRGB in screenshots: the source is drawn with linear sRGB on when its colour space (obs_source_get_color_space()with SRGB, SRGB_16F and 709_EXTENDED preferred, the list transitions use) is not 8-bit sRGB. 8-bit sources keep the direct path, so their pixels and their straight alpha are unchanged. With linear sRGB on, libobs premultiplies semi-transparent 8-bit async sources (DrawNonlinearAlpha), and the PNG would have darker edges. HDR (PQ/HLG) async sources were already tone mapped with linear sRGB forced on by libobs, so nothing changes for them.Tested in obs-rust/obs-studio with
test_ws_screenshot_srgb, which builds the helper against libobs and the built OpenGL module and shows a flat colour from a test async source as the only item of the program scene. At the helper-only commit, 4 of 6 cases fail in both libobs lanes: P010 grey, and P010/I010/I210 orange. With the fix, all 6 pass in both lanes, and the 8-bit NV12 and half-transparent BGRA controls give the same values as before. Also tested in a full OBS build (frontend + obs-websocket) in both lanes, and end to end. The release v0.1.0-beta.20261014 returns (255, 30, 0) for ProRes 422, ProRes 4444 and HEVC Main10 Media Sources, and builds with this branch return (255, 96, 0), the same as the scene screenshot and the recording. The 8-bit H.264 and VP9-alpha screenshots are byte-identical to the release's below the pattern's changing strip.Refs obs-rust/obs-studio#1141. The obs-rust/obs-studio PR that moves the submodule to this branch carries the regression test and closes the issue.
🤖 Generated with Claude Code