From 36a86f52176e317638c02deb17156cd5446c68b8 Mon Sep 17 00:00:00 2001 From: PatTheMav Date: Tue, 11 Oct 2022 00:32:17 +0200 Subject: [PATCH 1/4] mac-virtualcam: Fix random crashes in applications loading VirtualCam Without invalidating the mach port used for sharing the IOSurface between OBS and the application displaying the virtual camera output, IOKit seems to run into the issue of receiving "shared" mach ports, possibly because of port exhaustion. IOKit requires a "new" port however and crashes upon that error otherwise. Co-authored-by: Steven Michaud --- plugins/mac-virtualcam/src/dal-plugin/OBSDALMachClient.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/mac-virtualcam/src/dal-plugin/OBSDALMachClient.mm b/plugins/mac-virtualcam/src/dal-plugin/OBSDALMachClient.mm index c6126398c..c6c0cde2a 100644 --- a/plugins/mac-virtualcam/src/dal-plugin/OBSDALMachClient.mm +++ b/plugins/mac-virtualcam/src/dal-plugin/OBSDALMachClient.mm @@ -114,6 +114,7 @@ IOSurfaceRef surface = IOSurfaceLookupFromMachPort( [framePort machPort]); + [framePort invalidate]; mach_port_deallocate(mach_task_self(), [framePort machPort]); From a754cacc7f762345877cc2c994ca68cdb712712e Mon Sep 17 00:00:00 2001 From: PatTheMav Date: Wed, 19 Oct 2022 00:53:30 +0200 Subject: [PATCH 2/4] mac-virtualcam: Use IOSurfaceLock on Intel-based Macs only Apple Silicon-based Macs have a unified memory architecture, as such an IOSurface will always be available in memory accessible to the CPU and GPU (and an off-load of the IOSurface will not take place). eGPUs are not supported on Apple Silicon-based Macs either, so an IOSurface lock to ensure data is copied back to CPU memory is not necessary. --- .../src/dal-plugin/OBSDALMachClient.mm | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/plugins/mac-virtualcam/src/dal-plugin/OBSDALMachClient.mm b/plugins/mac-virtualcam/src/dal-plugin/OBSDALMachClient.mm index c6c0cde2a..9514eee9f 100644 --- a/plugins/mac-virtualcam/src/dal-plugin/OBSDALMachClient.mm +++ b/plugins/mac-virtualcam/src/dal-plugin/OBSDALMachClient.mm @@ -10,7 +10,6 @@ #import "Logging.h" @interface OBSDALMachClient () { - uint32_t _seed; NSPort *_receivePort; } @end @@ -123,11 +122,20 @@ return; } - IOSurfaceLock(surface, 0, &_seed); + /* + * IOSurfaceLocks are only necessary on non Apple Silicon devices, as those have + * unified memory. On Intel machines, the lock ensures that the IOSurface is copied back + * from GPU memory to CPU memory so we can process the pixel buffer. + */ +#ifndef __aarch64__ + IOSurfaceLock(surface, kIOSurfaceLockReadOnly, NULL); +#endif CVPixelBufferRef frame; CVPixelBufferCreateWithIOSurface(kCFAllocatorDefault, surface, NULL, &frame); - IOSurfaceUnlock(surface, 0, &_seed); +#ifndef __aarch64__ + IOSurfaceUnlock(surface, kIOSurfaceLockReadOnly, NULL); +#endif CFRelease(surface); uint64_t timestamp; From 558c2a7074287f73d55f377a4cbbb575ba3d3abe Mon Sep 17 00:00:00 2001 From: PatTheMav Date: Tue, 11 Oct 2022 00:29:57 +0200 Subject: [PATCH 3/4] mac-virtualcam: Remove unnecessary use of NSAppleEventDescriptor --- plugins/mac-virtualcam/src/obs-plugin/plugin-main.mm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/mac-virtualcam/src/obs-plugin/plugin-main.mm b/plugins/mac-virtualcam/src/obs-plugin/plugin-main.mm index c9d7409f9..b4185525b 100644 --- a/plugins/mac-virtualcam/src/obs-plugin/plugin-main.mm +++ b/plugins/mac-virtualcam/src/obs-plugin/plugin-main.mm @@ -84,11 +84,9 @@ static bool check_dal_plugin() copyPluginCmd]; NSDictionary *errorDict; - NSAppleEventDescriptor *returnDescriptor = NULL; NSAppleScript *scriptObject = [[NSAppleScript alloc] initWithSource:copyCmd]; - returnDescriptor = - [scriptObject executeAndReturnError:&errorDict]; + [scriptObject executeAndReturnError:&errorDict]; if (errorDict != nil) { const char *errorMessage = [[errorDict objectForKey:@"NSAppleScriptErrorMessage"] From 0b0ac1b958a96fbe5442eff3e7366b3c3f9e927a Mon Sep 17 00:00:00 2001 From: PatTheMav Date: Tue, 11 Oct 2022 00:31:53 +0200 Subject: [PATCH 4/4] mac-virtualcam: Remove unnecessary IOSurfaceLocks in Mach Server IOSurface locks are only necessary when any processing with the data contained in the surface is done and an explicit copy of data from GPU memory back to CPU memory is needed. --- plugins/mac-virtualcam/src/obs-plugin/OBSDALMachServer.mm | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/mac-virtualcam/src/obs-plugin/OBSDALMachServer.mm b/plugins/mac-virtualcam/src/obs-plugin/OBSDALMachServer.mm index 8deafde50..efd33c1b4 100644 --- a/plugins/mac-virtualcam/src/obs-plugin/OBSDALMachServer.mm +++ b/plugins/mac-virtualcam/src/obs-plugin/OBSDALMachServer.mm @@ -15,7 +15,6 @@ @property NSPort *port; @property NSMutableSet *clientPorts; @property NSRunLoop *runLoop; -@property uint32_t seed; @end @implementation OBSDALMachServer @@ -156,7 +155,6 @@ return; } - IOSurfaceLock(surface, 0, &_seed); mach_port_t framePort = IOSurfaceCreateMachPort(surface); if (!framePort) { @@ -176,7 +174,6 @@ ]]; mach_port_deallocate(mach_task_self(), framePort); - IOSurfaceUnlock(surface, 0, &_seed); } }