From 458a1495c8cb3d354624fe5fc86e55c0037e9483 Mon Sep 17 00:00:00 2001 From: skogaby Date: Fri, 20 Mar 2026 16:43:20 -0500 Subject: [PATCH] Fix stale frame returned by capture API on rapid successive calls (#583) Fix stale frame returned by capture API on rapid successive calls > [!NOTE] > Before submitting code changes... > * Please do note that this is a GPL v3.0 open source project. > * Please read the [CONTRIBUTING](https://github.com/spice2x/spice2x.github.io/blob/main/CONTRIBUTING.md) guide. > * Maintainers reserve the right to reject or modify your submission without reason. > * No new compiler warnings must be introduced. Check the CI build results. > > Feel free to remove this section after you have read it. ## Link to GitHub Issue or related Pull Request, if one exists https://github.com/spice2x/spice2x.github.io/issues/582 ## Description of change When using the SpiceAPI `capture` endpoint for taking screenshots, if you call multiple times in a row in a short period, there's a good chance for duplicate / stale data to be returned, and you end up with multiple identical screenshots. This is due to a race condition in the graphics capture pipeline because the capture data is never reset to null between invocations. `graphics_capture_receive_jpeg()` never resets the capture buffer's data pointer to `nullptr` after consuming it. The condition variable wait predicate checks `data != nullptr`, so subsequent calls find the predicate already satisfied and return immediately with the previous frame instead of waiting for the render thread to produce a fresh one. Fix: null out `capture.data` after copying the shared_ptr (which keeps the pixel data alive via refcount) but before releasing the lock. ## Testing Tested this locally and invoked the capture API 10+ times in a row without any duplicates. Previously, every other invocation would be a duplicate, basically. --- src/spice2x/hooks/graphics/graphics.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/spice2x/hooks/graphics/graphics.cpp b/src/spice2x/hooks/graphics/graphics.cpp index 51ea079..8532cfa 100644 --- a/src/spice2x/hooks/graphics/graphics.cpp +++ b/src/spice2x/hooks/graphics/graphics.cpp @@ -1052,6 +1052,7 @@ bool graphics_capture_receive_jpeg(int screen, TooJpeg::WRITE_ONE_BYTE receiver, auto capture_width = capture.width; auto capture_height = capture.height; auto capture_timestamp = capture.timestamp; + capture.data = nullptr; lock.unlock(); // validate data