Skip to content

Conversation

@Wouterdek
Copy link

This PR adds additional capture consumer tasks, which are hinted to run in parallel. These tasks speed up the encoding and saving process, which was previously a bottleneck causing large memory usage and long waiting times at the end of recording. The degree of parallelization is set conservatively to avoid overwhelming the CPU on weaker systems. It is currently hardcoded at 25% of cpu cores (16 cores => 4 tasks, 12 cores => 3 tasks, 8 cores => 2 tasks, <8 cores => 1 task, ...)
This change is implemented for ImageCapture and DirectImageCapture, other capture methods are unchanged.

Performance

Before this change, recording 2 minutes of 1080p 60hz would spike my RAM usage up to 30GB and take over a minute of "Stopping..." before proceeding to the editor.
After this change, I can record 4k 60hz with RAM usage below 800MB and the editor immediately opens after stopping recording.

Safety

Capture() and Save() already run async with a blocking collection, which made it easier to implement this change. However, when saving multiple frames in parallel, multiple frames may try to append to Project.Frames at the same time. I've put a lock around that line to avoid race conditions corrupting the list. Also, a later frame may finish before an earlier one, so frames may be saved out of order. Therefore, I've added a post-process sorting step to ensure a correct order of Project.Frames.

This changelist adds additional capture consumer tasks, which are hinted to run in parallel. These tasks speed up the encoding and saving process, which was previously a bottleneck causing large memory usage and long waiting times at the end of recording.
The degree of parallelization is set conservatively to avoid overwhelming the CPU on weaker systems.
This change is implemented for ImageCapture and DirectImageCapture, other capture methods are unchanged.
bitmap.UnlockBits(mapDest);

//Set frame details.
frame.Index = FrameCount;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

frame.Index was only set later, after capturing. But because we need it to sort the frame list, we need the index to be set early.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant