The WGC capture session uses Direct3D11CaptureFramePool::CreateFreeThreaded,
which dispatches FrameArrived callbacks on thread pool threads concurrently.
MFEncoder::writeFrame() accesses non-thread-safe resources (ID3D11DeviceContext,
IMFSinkWriter, shared staging texture and NV12 buffer) without synchronization,
causing MP4 container corruption when callbacks overlap at high frame rates.
Add a mutex to serialize writeFrame() and finalize() calls, preventing
concurrent access to the D3D context and Media Foundation sink writer.
Fixes#96
Add IPC handler to expose app.getVersion() to the renderer and
display it in the More dropdown menu. Users can now verify which
version they're running.
Fixes#70
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Push selected-source changes from Electron to the launch window instead of polling every 500ms, reducing constant renderer and IPC churn. Also restore the TimelineEditor audio path narrowing fix so the current tree stays type-safe.
Enumerate cameras and microphones before requesting media permissions, only opening a stream once when labels need to be unlocked. Stop rerunning enumeration when the selected device changes so launch controls no longer churn hardware access on routine UI interaction.
Replace JSON-based snapshot cloning and equality checks with structured object comparisons in the video editor. Reuse memoized persisted project state for dirty tracking and saves so normal editor interactions stop rebuilding large serialized snapshots on every change.
Add minimal, dot, and inverted cursor styles for preview and export rendering, including the bundled minimal cursor asset and runtime cursor asset generation.
Add translation strings for the new caption, cursor, and zoom controls and include the indeterminate progress styling used by long-running caption and export actions.
Connect caption generation, Whisper model download state, caption persistence, export saving progress, and preview/export caption props through the main video editor workflow.