Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mac-virtualcam: Fix frame sharing and colourspace issues #7403

Merged
merged 2 commits into from
Sep 21, 2022

Conversation

PatTheMav
Copy link
Member

Description

Fixes an issue with empty IOSurface references on Intel-based Macs and also broken output when OBS is set to deliver full colour range output.

Motivation and Context

The plugin was missing necessary IOSurface locks to ensure that modifications to the underlying memory reference made by the OS do not occur when client code accesses the image data.

On machines without unified memory this can lead to IOSurfaces pointing to GPU memory even though the data has been moved to CPU memory by the OS (to avoid unnecessarily large copy operations) and a PixelBuffer created from the IOSurface won't contain data.

In addition to the issue above, FFmpeg's swscale seems to have issues with converting images with full colour ranges to limited colour ranges, resulting in mangled frame data inside OBS.

As macOS natively supports partial range as well as as full ranges for pixel buffers, use these directly, avoiding costly colour space conversions for even more use cases than before - as this skips swscale entirely, the issue doesn't occur anymore.

Fixes #7333
Possibly fixes #7171

How Has This Been Tested?

Tested with macOS 12.6 on Intel-based and Apple-Silicon-based Macs.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)

Checklist:

  • My code has been run through clang-format.
  • I have read the contributing document.
  • My code is not on the master branch.
  • The code has been tested.
  • All commit messages are properly formatted and commits squashed where appropriate.
  • I have included updates to all appropriate documentation.

This issue primarily seems to affect Intel-based Macs without unified
memory: While an IOSurface is supposed to be shared via a mach port
with other processes, each process needs to lock the surface during
access (as is common with other shared resources).

Apple Silicon-based Macs seem to be less affected as a switch between
GPU and CPU memory (which can happen dynamically for IOSurfaces) would
still point to the same unified memory.
The root cause of the issue is `swscale` dropping the second plane of
biplanar pixel data, resulting in an "incomplete" frame being fed to the
CVPixelBuffer.

As CVPixelBuffers have dedicated support for full range colour, use
these directly, which improves performance even further (as any
conversion for full range data is avoided as well).

To ensure that OBS does not implicitly enable conversion via `swscale`
a video conversion struct needs to be set in any case, ensuring that the
output range and colourspace match the output configuration.
@PatTheMav PatTheMav added Bug Fix Non-breaking change which fixes an issue Seeking Testers Build artifacts on CI macOS Affects macOS labels Sep 18, 2022
@PatTheMav
Copy link
Member Author

Kudos to @ccgus for dropping the important hint on his blog: https://shapeof.com/archives/2017/12/moving_to_metal_episode_iii.html.

@RytoEX
Copy link
Member

RytoEX commented Sep 21, 2022

Per off-thread conversation with @PatTheMav and @gxalpha , this is good to merge as-is, so I'm merging it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Fix Non-breaking change which fixes an issue macOS Affects macOS Seeking Testers Build artifacts on CI
Projects
No open projects
Status: Fixed & Released
Development

Successfully merging this pull request may close these issues.

Virtual Cam shows a red screen instead of video Vitrual Cam's Picture Black
2 participants