From 01a88e3bfed1116626f99057a87ff7927dafeea3 Mon Sep 17 00:00:00 2001 From: Sverre Skodje Date: Sat, 10 Sep 2022 02:10:00 +0200 Subject: [PATCH] Fixed a scope issue causing mutex to be released before updating new frame count, causing a race condition. --- .../ScreenCaptureManager.cpp | 67 +++++++++---------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/ScreenRecorderLibNative/ScreenCaptureManager.cpp b/ScreenRecorderLibNative/ScreenCaptureManager.cpp index 40a2641..ee7a82a 100644 --- a/ScreenRecorderLibNative/ScreenCaptureManager.cpp +++ b/ScreenRecorderLibNative/ScreenCaptureManager.cpp @@ -723,45 +723,44 @@ DWORD WINAPI CaptureThreadProc(_In_ void *Param) LOG_ERROR(L"Unexpected error acquiring KeyMutex"); break; } - { - MeasureExecutionTime measureLock(string_format(L"CaptureThreadProc sync lock for %ls", pRecordingSourceCapture->Name().c_str())); - ReleaseKeyedMutexOnExit releaseMutex(KeyMutex, 1); - - // We can now process the current frame - if (WaitToProcessCurrentFrame) { - WaitToProcessCurrentFrame = false; - LONGLONG waitTimeMillis = duration_cast(chrono::steady_clock::now() - WaitForFrameBegin).count(); - LOG_TRACE(L"CaptureThreadProc waited for busy shared surface for %lld ms", waitTimeMillis); - } - if (pSource->IsCursorCaptureEnabled.value_or(true)) { - // Get mouse info - hr = pRecordingSourceCapture->GetMouse(pData->PtrInfo, pSourceData->FrameCoordinates, pSourceData->OffsetX, pSourceData->OffsetY); - if (FAILED(hr)) { - LOG_ERROR("Failed to get mouse data"); - } - } - else if (pData->PtrInfo) { - pData->PtrInfo->Visible = false; + MeasureExecutionTime measureLock(string_format(L"CaptureThreadProc sync lock for %ls", pRecordingSourceCapture->Name().c_str())); + ReleaseKeyedMutexOnExit releaseMutex(KeyMutex, 1); + + // We can now process the current frame + if (WaitToProcessCurrentFrame) { + WaitToProcessCurrentFrame = false; + LONGLONG waitTimeMillis = duration_cast(chrono::steady_clock::now() - WaitForFrameBegin).count(); + LOG_TRACE(L"CaptureThreadProc waited for busy shared surface for %lld ms", waitTimeMillis); + } + if (pSource->IsCursorCaptureEnabled.value_or(true)) { + // Get mouse info + hr = pRecordingSourceCapture->GetMouse(pData->PtrInfo, pSourceData->FrameCoordinates, pSourceData->OffsetX, pSourceData->OffsetY); + if (FAILED(hr)) { + LOG_ERROR("Failed to get mouse data"); } + } + else if (pData->PtrInfo) { + pData->PtrInfo->Visible = false; + } - if (pSource->IsVideoCaptureEnabled.value_or(true)) { - if (IsSharedSurfaceDirty) { - //The screen has been blacked out, so we restore a full frame to the shared surface before starting to apply updates. - RECT offsetFrameCoordinates = pSourceData->FrameCoordinates; - OffsetRect(&offsetFrameCoordinates, pSourceData->OffsetX, pSourceData->OffsetY); - hr = textureManager.DrawTexture(SharedSurf, pFrame, offsetFrameCoordinates); - IsSharedSurfaceDirty = false; - } - - hr = pRecordingSourceCapture->WriteNextFrameToSharedSurface(0, SharedSurf, pSourceData->OffsetX, pSourceData->OffsetY, pSourceData->FrameCoordinates); + if (pSource->IsVideoCaptureEnabled.value_or(true)) { + if (IsSharedSurfaceDirty) { + //The screen has been blacked out, so we restore a full frame to the shared surface before starting to apply updates. + RECT offsetFrameCoordinates = pSourceData->FrameCoordinates; + OffsetRect(&offsetFrameCoordinates, pSourceData->OffsetX, pSourceData->OffsetY); + hr = textureManager.DrawTexture(SharedSurf, pFrame, offsetFrameCoordinates); + IsSharedSurfaceDirty = false; } - else { - hr = textureManager.BlankTexture(SharedSurf, pSourceData->FrameCoordinates, pSourceData->OffsetX, pSourceData->OffsetY); - if (SUCCEEDED(hr)) { - IsCapturingVideo = false; - } + + hr = pRecordingSourceCapture->WriteNextFrameToSharedSurface(0, SharedSurf, pSourceData->OffsetX, pSourceData->OffsetY, pSourceData->FrameCoordinates); + } + else { + hr = textureManager.BlankTexture(SharedSurf, pSourceData->FrameCoordinates, pSourceData->OffsetX, pSourceData->OffsetY); + if (SUCCEEDED(hr)) { + IsCapturingVideo = false; } } + if (hr == DXGI_ERROR_WAIT_TIMEOUT) { continue; }