Search existing issues
This appears to be a regression or an incomplete fix related to #34 and #115. Both issues are closed, and #115 was linked to fixes in #119 and #123, but the failure still reproduces with the packaged v1.8.0 Windows helper.
Describe the bug
On OpenScreen v1.8.0 for Windows, stopping a native Windows screen recording hangs for about one minute and then shows:
Timed out waiting for native Windows capture to stop
The output MP4 remains 0 bytes and the editor does not open normally.
After that timeout, clicking Record again shows a second error:
Native Windows capture is not running.
The second message appears to be a follow-on state error: the native helper is no longer considered active by the main process, while the renderer still retains the previous native recording state.
Expected behavior
Clicking Stop should make the native helper process the stdin stop command, finalize the MP4, emit recording-stopped, exit promptly, clear all recording state, and open the editor.
If native capture fails, the application should clear the stale recording state so that a subsequent recording attempt can start normally.
To Reproduce
- Install and run OpenScreen v1.8.0 on Windows 10.
- Select a display source and start recording.
- Wait a few seconds.
- Click Stop.
- Wait approximately one minute.
- Observe
Timed out waiting for native Windows capture to stop.
- Observe that the generated MP4 is 0 bytes.
- Click Record again.
- Observe
Native Windows capture is not running.
The failure persists after closing remote-control applications.
Direct helper reproduction and log
I also reproduced the failure by launching the packaged v1.8.0 wgc-capture.exe directly with display capture, default encoder selection, and system audio, microphone, webcam, and cursor capture disabled.
The helper started successfully. I sent stop\n three seconds after recording-started. It was still running 12 seconds later and had to be terminated for cleanup.
[stdout] {"event":"ready","schemaVersion":2}
[stdout] {"event":"cursor-capture","schemaVersion":2,"requested":false,"applied":false}
[stdout] {"event":"encoder-selection","schemaVersion":2,"video":"default","preferSoftwareEncoder":false}
[stdout] {"event":"cursor-capture","schemaVersion":2,"requested":false,"applied":false}
[stdout] {"event":"recording-started","schemaVersion":2}
Recording started
[diagnostic] sending stop
[diagnostic] helper still running 12s after expected stop; terminating for cleanup
{
"started": true,
"stopSent": true,
"exitedWithoutWatchdog": false,
"elapsedAfterStopMs": 14852,
"outputBytes": 0,
"hasStopTiming": false
}
No [stop-timing] line was emitted. This indicates that the main thread did not reach the first cleanup step after the stop wait. The hang occurs before microphone, loopback, webcam, video-writer, WGC-session, or encoder-finalization cleanup is logged.
OpenScreen did not create a dedicated application log containing this failure on this machine. Chromium LevelDB log files were present, but they did not contain useful OpenScreen recording diagnostics. The direct helper output above is the relevant diagnostic log.
Possible cause
PR #119 moved the potentially blocking IMFSinkWriter::WriteSample call outside the shared frame mutex, and #123 bounded the video-writer condition-variable wait. However, the main stop path still waits while acquiring the same shared frame mutex:
std::unique_lock lock(mutex);
control.cv.wait(lock, [&] {
return control.stopRequested.load();
});
That mutex is still used by the WGC frame callback around CopyResource and by the video writer around frame capture/GPU readback. A slow or blocked GPU copy/readback, or repeated lock reacquisition by frame-producing threads, can still prevent the main thread from acquiring the mutex after stopRequested becomes true.
The affected machine has multiple physical and virtual display adapters:
- AMD Radeon(TM) Graphics
- NVIDIA GeForce RTX 5070 Ti
- Todesk Virtual Display Adapter 16.44.2.509
- GameViewer Virtual Display Adapter 15.6.5.199
The virtual display drivers or multi-GPU scheduling may increase the likelihood of WGC/D3D copy or readback stalls. This remains a suspected trigger; the helper-level reproduction confirms that the problem is below the React UI.
A possible structural fix is to use a separate mutex/condition variable for stop control, independent from the frame-state mutex. Since stopRequested is atomic, the main stop waiter should not need to acquire a mutex that can be held by GPU frame work.
The second error can likely be prevented independently by clearing the renderer's active native recording state whenever native stop times out or the stop IPC call fails.
Verified workaround
Disabling native Windows WGC capture and using the existing Electron getDisplayMedia + MediaRecorder fallback avoids the issue on this machine.
Two consecutive test recordings stopped in approximately 0.39 seconds and 0.28 seconds. Both generated non-empty, valid H.264 WebM files, opened in the editor, and allowed another recording to start.
Screenshots
The two observed toast messages are:
Timed out waiting for native Windows capture to stop, with helper output ending at Recording started.
Native Windows capture is not running.
OS
Windows
OS Version
Windows 10 Pro 22H2, version 10.0.19045, build 19045, 64-bit
Device Type
Desktop
Additional context
Search existing issues
This appears to be a regression or an incomplete fix related to #34 and #115. Both issues are closed, and #115 was linked to fixes in #119 and #123, but the failure still reproduces with the packaged v1.8.0 Windows helper.
Describe the bug
On OpenScreen v1.8.0 for Windows, stopping a native Windows screen recording hangs for about one minute and then shows:
Timed out waiting for native Windows capture to stopThe output MP4 remains 0 bytes and the editor does not open normally.
After that timeout, clicking Record again shows a second error:
Native Windows capture is not running.The second message appears to be a follow-on state error: the native helper is no longer considered active by the main process, while the renderer still retains the previous native recording state.
Expected behavior
Clicking Stop should make the native helper process the stdin
stopcommand, finalize the MP4, emitrecording-stopped, exit promptly, clear all recording state, and open the editor.If native capture fails, the application should clear the stale recording state so that a subsequent recording attempt can start normally.
To Reproduce
Timed out waiting for native Windows capture to stop.Native Windows capture is not running.The failure persists after closing remote-control applications.
Direct helper reproduction and log
I also reproduced the failure by launching the packaged v1.8.0
wgc-capture.exedirectly with display capture, default encoder selection, and system audio, microphone, webcam, and cursor capture disabled.The helper started successfully. I sent
stop\nthree seconds afterrecording-started. It was still running 12 seconds later and had to be terminated for cleanup.No
[stop-timing]line was emitted. This indicates that the main thread did not reach the first cleanup step after the stop wait. The hang occurs before microphone, loopback, webcam, video-writer, WGC-session, or encoder-finalization cleanup is logged.OpenScreen did not create a dedicated application log containing this failure on this machine. Chromium LevelDB log files were present, but they did not contain useful OpenScreen recording diagnostics. The direct helper output above is the relevant diagnostic log.
Possible cause
PR #119 moved the potentially blocking
IMFSinkWriter::WriteSamplecall outside the shared frame mutex, and #123 bounded the video-writer condition-variable wait. However, the main stop path still waits while acquiring the same shared frame mutex:That mutex is still used by the WGC frame callback around
CopyResourceand by the video writer around frame capture/GPU readback. A slow or blocked GPU copy/readback, or repeated lock reacquisition by frame-producing threads, can still prevent the main thread from acquiring the mutex afterstopRequestedbecomes true.The affected machine has multiple physical and virtual display adapters:
The virtual display drivers or multi-GPU scheduling may increase the likelihood of WGC/D3D copy or readback stalls. This remains a suspected trigger; the helper-level reproduction confirms that the problem is below the React UI.
A possible structural fix is to use a separate mutex/condition variable for stop control, independent from the frame-state mutex. Since
stopRequestedis atomic, the main stop waiter should not need to acquire a mutex that can be held by GPU frame work.The second error can likely be prevented independently by clearing the renderer's active native recording state whenever native stop times out or the stop IPC call fails.
Verified workaround
Disabling native Windows WGC capture and using the existing Electron
getDisplayMedia+MediaRecorderfallback avoids the issue on this machine.Two consecutive test recordings stopped in approximately 0.39 seconds and 0.28 seconds. Both generated non-empty, valid H.264 WebM files, opened in the editor, and allowed another recording to start.
Screenshots
The two observed toast messages are:
Timed out waiting for native Windows capture to stop, with helper output ending atRecording started.Native Windows capture is not running.OS
Windows
OS Version
Windows 10 Pro 22H2, version 10.0.19045, build 19045, 64-bit
Device Type
Desktop
Additional context
043847EFF3C86E1006D2EA86563DC14A20F491BB42DECA4DB6A97B8738E879DEpreferSoftwareEncoder: false.