Skip to content

Commit

Permalink
macOS 15 sequoia: migrate to ScreenCaptureKit (#984)
Browse files Browse the repository at this point in the history
  • Loading branch information
awawa-dev authored Nov 17, 2024
1 parent c2e3524 commit fa32e0f
Show file tree
Hide file tree
Showing 9 changed files with 178 additions and 30 deletions.
35 changes: 33 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,41 @@ if ( "${PLATFORM}" MATCHES "osx" )
list(APPEND CMAKE_PREFIX_PATH "/usr/local/opt/qt5")
endif()

SET ( DEFAULT_AVF ON )
SET ( DEFAULT_MAC_SYSTEM ON )
SET ( DEFAULT_AVF ON )
SET ( DEFAULT_EMBEDDED_WEB_RESOURCES OFF )

if (CMAKE_OSX_DEPLOYMENT_TARGET)
set(CMAKE_OSX_HYPERHDR_DEPLOYMENT_TARGET ${CMAKE_OSX_DEPLOYMENT_TARGET})
else()
set(VERSION_REPLACEMENT ${CMAKE_OSX_SYSROOT})
string(REPLACE "/SDKs/MacOSX" "." VERSION_REPLACEMENT ${VERSION_REPLACEMENT})
string(REPLACE "." ";" VERSION_REPLACEMENT_LIST ${VERSION_REPLACEMENT})
list(LENGTH VERSION_REPLACEMENT_LIST VERSION_REPLACEMENT_LIST_LENGTH)
if (${VERSION_REPLACEMENT_LIST_LENGTH} GREATER_EQUAL 1)
list (GET VERSION_REPLACEMENT_LIST 1 CMAKE_OSX_HYPERHDR_DEPLOYMENT_TARGET)
endif()
endif(CMAKE_OSX_DEPLOYMENT_TARGET)

if (CMAKE_OSX_HYPERHDR_DEPLOYMENT_TARGET)
message(STATUS "CMAKE_OSX_DEPLOYMENT_TARGET: ${CMAKE_OSX_HYPERHDR_DEPLOYMENT_TARGET}")
SET(CMAKE_OSX_DEPLOYMENT_TARGET_COPY ${CMAKE_OSX_HYPERHDR_DEPLOYMENT_TARGET})
string(REPLACE "." ";" CMAKE_OSX_DEPLOYMENT_TARGET_COPY_LIST ${CMAKE_OSX_DEPLOYMENT_TARGET_COPY})
list(GET CMAKE_OSX_DEPLOYMENT_TARGET_COPY_LIST 0 MACOS_MAJOR_VERSION)
message(STATUS "MAJOR MACOS VERSION: ${MACOS_MAJOR_VERSION}")

if (${MACOS_MAJOR_VERSION} GREATER_EQUAL "15")
message(STATUS "Looking for: ScreenCaptureKit")
find_library(MACOS_SCK ScreenCaptureKit)
if (MACOS_SCK)
SET ( DEFAULT_MAC_SYSTEM ON )
else()
message(WARNING "Could not find: ScreenCaptureKit")
endif(MACOS_SCK)
else()
SET ( DEFAULT_MAC_SYSTEM ON )
endif()
endif(CMAKE_OSX_HYPERHDR_DEPLOYMENT_TARGET)

elseif ( "${PLATFORM}" MATCHES "rpi" )
SET ( DEFAULT_WS281XPWM ON )
SET ( DEFAULT_CEC ON )
Expand Down
2 changes: 2 additions & 0 deletions include/grabber/osx/macOS/macOsGrabber.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ public slots:
bool init_device(QString selectedDeviceName);

void processFrame(int8_t* source);

void decodeFrame(CGImageRef capturedImage);

private:
QString _configurationPath;
Expand Down
12 changes: 10 additions & 2 deletions sources/grabber/osx/AVF/AVFGrabber.mm
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,11 @@ - (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleB
_deviceProperties.clear();

AVCaptureDeviceDiscoverySession* session = [AVCaptureDeviceDiscoverySession
discoverySessionWithDeviceTypes : @[AVCaptureDeviceTypeExternalUnknown]
#ifndef MACOS_VERSION_14_UP
discoverySessionWithDeviceTypes : @[AVCaptureDeviceTypeExternalUnknown]
#else
discoverySessionWithDeviceTypes : @[AVCaptureDeviceTypeExternal]
#endif
mediaType:AVMediaTypeVideo
position : AVCaptureDevicePositionUnspecified];

Expand Down Expand Up @@ -516,7 +520,11 @@ - (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleB


for (AVCaptureDevice* device in[AVCaptureDeviceDiscoverySession
discoverySessionWithDeviceTypes : @[AVCaptureDeviceTypeExternalUnknown]
#ifndef MACOS_VERSION_14_UP
discoverySessionWithDeviceTypes : @[AVCaptureDeviceTypeExternalUnknown]
#else
discoverySessionWithDeviceTypes : @[AVCaptureDeviceTypeExternal]
#endif
mediaType:AVMediaTypeVideo
position : AVCaptureDevicePositionUnspecified].devices)
{
Expand Down
4 changes: 4 additions & 0 deletions sources/grabber/osx/AVF/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ target_link_libraries(AVF-grabber
Qt${Qt_VERSION}::Network
)

if (${MACOS_MAJOR_VERSION} GREATER_EQUAL "14")
target_compile_definitions(AVF-grabber PUBLIC MACOS_VERSION_14_UP)
endif()

if(USE_PRECOMPILED_HEADERS AND COMMAND target_precompile_headers)
target_precompile_headers(AVF-grabber REUSE_FROM precompiled_hyperhdr_headers)
endif()
Expand Down
4 changes: 4 additions & 0 deletions sources/grabber/osx/macOS/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ target_link_libraries(MACOS-grabber
Qt${Qt_VERSION}::Network
)

if(MACOS_SCK)
target_compile_definitions(MACOS-grabber PUBLIC MACOS_SCK)
endif()

if(USE_PRECOMPILED_HEADERS AND COMMAND target_precompile_headers)
target_precompile_headers(MACOS-grabber REUSE_FROM precompiled_hyperhdr_headers)
endif()
Expand Down
132 changes: 108 additions & 24 deletions sources/grabber/osx/macOS/macOsGrabber.mm
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,18 @@
#import <Foundation/Foundation.h>
#import <Foundation/NSProcessInfo.h>

id activity;
#ifdef MACOS_SCK
#import <ScreenCaptureKit/ScreenCaptureKit.h>
#endif

namespace
{
id activity;
#ifdef MACOS_SCK
CGColorSpaceRef colorSpaceRgb = nil;
#endif
};


macOsGrabber::macOsGrabber(const QString& device, const QString& configurationPath)
: Grabber(configurationPath, "MACOS_SYSTEM:" + device.left(14))
Expand Down Expand Up @@ -99,6 +110,14 @@
Debug(_log, "Uninit grabber: %s", QSTRING_CSTR(_deviceName));
}

#ifdef MACOS_SCK
if (colorSpaceRgb)
{
CGColorSpaceRelease(colorSpaceRgb);
colorSpaceRgb = nil;
}
#endif

_actualDisplay = 0;

_initialized = false;
Expand All @@ -123,6 +142,13 @@
autoDiscovery = true;
}

#ifdef MACOS_SCK
if (!colorSpaceRgb)
{
colorSpaceRgb = CGColorSpaceCreateDeviceRGB();
}
#endif

if (autoDiscovery)
{
Debug(_log, "Forcing auto discovery device");
Expand Down Expand Up @@ -228,13 +254,82 @@
return true;
}

void macOsGrabber::grabFrame()
void macOsGrabber::decodeFrame(CGImageRef capturedImage)
{
bool stopNow = false;

CFDataRef sysData = CGDataProviderCopyData(CGImageGetDataProvider(capturedImage));

if (sysData != NULL)
{
uint8_t* rawData = (uint8_t*)CFDataGetBytePtr(sysData);
_actualWidth = CGImageGetWidth(capturedImage);
_actualHeight = CGImageGetHeight(capturedImage);

size_t bytesPerRow = CGImageGetBytesPerRow(capturedImage);
processSystemFrameBGRA(rawData, static_cast<int>(bytesPerRow));

CFRelease(sysData);
}
}

void macOsGrabber::grabFrame()
{
#ifdef MACOS_SCK
[SCShareableContent getShareableContentWithCompletionHandler:^(SCShareableContent* content, NSError* error)
{
SCDisplay* target = nil;
for (SCDisplay *display in content.displays)
{
if (display.displayID == _actualDisplay)
{
target = display;
break;
}
}
if (!target)
{
uninit();
QTimer::singleShot(3000, this, &macOsGrabber::start);
}
else
{
CGDisplayModeRef displayReference = CGDisplayCopyDisplayMode(_actualDisplay);
double scaleAspect = CGDisplayModeGetPixelWidth(displayReference)/static_cast<double>(CGDisplayModeGetWidth(displayReference));
CGDisplayModeRelease(displayReference);

CGRect displayBounds = CGDisplayBounds(_actualDisplay);

SCContentFilter* filter = [[SCContentFilter alloc] initWithDisplay:target excludingWindows:@[]];
SCStreamConfiguration* streamConfig = [[SCStreamConfiguration alloc] init];

streamConfig.width = displayBounds.size.width * scaleAspect;
streamConfig.height = displayBounds.size.height * scaleAspect;
streamConfig.sourceRect = displayBounds;
streamConfig.captureResolution = SCCaptureResolutionBest;
streamConfig.scalesToFit = false;
streamConfig.queueDepth = 1;

[SCScreenshotManager captureImageWithFilter:filter
configuration:streamConfig
completionHandler:^(CGImageRef sourceImg, NSError* error)
{
if (!error)
{
CGImageRef capturedImage = CGImageCreateCopyWithColorSpace(sourceImg, colorSpaceRgb);

decodeFrame(capturedImage);

CGImageRelease(capturedImage);
}
}
];

[streamConfig release];
[filter release];
}
}];
#else
bool stopNow = false;
CGImageRef display;
CFDataRef sysData;
uint8_t* rawData;

display = CGDisplayCreateImage(_actualDisplay);

Expand All @@ -245,28 +340,17 @@
}
else
{
sysData = CGDataProviderCopyData(CGImageGetDataProvider(display));;

if (sysData != NULL)
{
rawData = (uint8_t*)CFDataGetBytePtr(sysData);
_actualWidth = CGImageGetWidth(display);
_actualHeight = CGImageGetHeight(display);

size_t bytesPerRow = CGImageGetBytesPerRow(display);
processSystemFrameBGRA(rawData, static_cast<int>(bytesPerRow));

CFRelease(sysData);
}
decodeFrame(display);

CGImageRelease(display);
}

if (stopNow)
{
uninit();
QTimer::singleShot(3000, this, &macOsGrabber::start);
}
if (stopNow)
{
uninit();
QTimer::singleShot(3000, this, &macOsGrabber::start);
}
#endif
}


Expand Down
3 changes: 3 additions & 0 deletions sources/hyperhdr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ if (ENABLE_MAC_SYSTEM)
MACOS-grabber
"-framework CoreGraphics"
"-framework Foundation")
if (MACOS_SCK)
target_link_libraries(hyperhdr "${MACOS_SCK}")
endif(MACOS_SCK)
endif()

if (ENABLE_AVF)
Expand Down
4 changes: 4 additions & 0 deletions sources/sound-capture/macos/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ target_link_libraries(sound-capture-macos
Qt${Qt_VERSION}::Network
)

if (${MACOS_MAJOR_VERSION} GREATER_EQUAL "14")
target_compile_definitions(sound-capture-macos PUBLIC MACOS_VERSION_14_UP)
endif()

if(USE_PRECOMPILED_HEADERS AND COMMAND target_precompile_headers AND (NOT APPLE))
target_precompile_headers(sound-capture-macos REUSE_FROM precompiled_hyperhdr_headers)
endif()
12 changes: 10 additions & 2 deletions sources/sound-capture/macos/SoundCaptureMacOS.mm
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@ - (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleB
void SoundCaptureMacOS::listDevices()
{
AVCaptureDeviceDiscoverySession *session = [AVCaptureDeviceDiscoverySession
discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInMicrophone]
#ifndef MACOS_VERSION_14_UP
discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInMicrophone]
#else
discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeMicrophone]
#endif
mediaType:AVMediaTypeAudio
position:AVCaptureDevicePositionUnspecified];

Expand Down Expand Up @@ -144,7 +148,11 @@ - (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleB
_soundBufferIndex = 0;

for (AVCaptureDevice* device in [AVCaptureDeviceDiscoverySession
discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInMicrophone]
#ifndef MACOS_VERSION_14_UP
discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInMicrophone]
#else
discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeMicrophone]
#endif
mediaType:AVMediaTypeAudio
position:AVCaptureDevicePositionUnspecified].devices)
{
Expand Down

0 comments on commit fa32e0f

Please sign in to comment.