clang-format: Update formatting of all ObjC and ObjC++ files

This commit is contained in:
PatTheMav 2023-06-04 03:26:09 +02:00 committed by Patrick Heyer
parent db7491083c
commit f8e00d6071
36 changed files with 6822 additions and 7956 deletions

View file

@ -42,4 +42,5 @@ void GetCurrentWindowTitle(string &title)
}
}
void CleanupSceneSwitcher() {}
void CleanupSceneSwitcher()
{}

View file

@ -41,8 +41,7 @@ bool isInBundle()
bool GetDataFilePath(const char *data, string &output)
{
NSURL *bundleUrl = [[NSBundle mainBundle] bundleURL];
NSString *path = [[bundleUrl path]
stringByAppendingFormat:@"/%@/%s", @"Contents/Resources", data];
NSString *path = [[bundleUrl path] stringByAppendingFormat:@"/%@/%s", @"Contents/Resources", data];
output = path.UTF8String;
return !access(output.c_str(), R_OK);
@ -52,8 +51,7 @@ void CheckIfAlreadyRunning(bool &already_running)
{
NSString *bundleId = [[NSBundle mainBundle] bundleIdentifier];
NSUInteger appCount = [[NSRunningApplication
runningApplicationsWithBundleIdentifier:bundleId] count];
NSUInteger appCount = [[NSRunningApplication runningApplicationsWithBundleIdentifier:bundleId] count];
already_running = appCount > 1;
}
@ -61,10 +59,7 @@ void CheckIfAlreadyRunning(bool &already_running)
string GetDefaultVideoSavePath()
{
NSFileManager *fm = [NSFileManager defaultManager];
NSURL *url = [fm URLForDirectory:NSMoviesDirectory
inDomain:NSUserDomainMask
appropriateForURL:nil
create:true
NSURL *url = [fm URLForDirectory:NSMoviesDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:true
error:nil];
if (!url)
@ -85,8 +80,7 @@ vector<string> GetPreferredLocales()
if (locale.first == lang.substr(0, locale.first.size()))
return locale.first;
if (!lang_match.size() &&
locale.first.substr(0, 2) == lang.substr(0, 2))
if (!lang_match.size() && locale.first.substr(0, 2) == lang.substr(0, 2))
lang_match = locale.first;
}
@ -117,8 +111,7 @@ bool IsAlwaysOnTop(QWidget *window)
void disableColorSpaceConversion(QWidget *window)
{
NSView *view =
(__bridge NSView *)reinterpret_cast<void *>(window->winId());
NSView *view = (__bridge NSView *) reinterpret_cast<void *>(window->winId());
view.window.colorSpace = NSColorSpace.sRGBColorSpace;
}
@ -127,8 +120,7 @@ void SetAlwaysOnTop(QWidget *window, bool enable)
Qt::WindowFlags flags = window->windowFlags();
if (enable) {
NSView *view = (__bridge NSView *)reinterpret_cast<void *>(
window->winId());
NSView *view = (__bridge NSView *) reinterpret_cast<void *>(window->winId());
[[view window] setLevel:NSScreenSaverWindowLevel];
@ -161,10 +153,8 @@ void EnableOSXVSync(bool enable)
"QuartzCore.framework/QuartzCore",
RTLD_LAZY);
if (quartzCore) {
set_debug_options = (set_int_t)dlsym(
quartzCore, "CGSSetDebugOptions");
deferred_updates = (set_int_t)dlsym(
quartzCore, "CGSDeferredUpdates");
set_debug_options = (set_int_t) dlsym(quartzCore, "CGSSetDebugOptions");
deferred_updates = (set_int_t) dlsym(quartzCore, "CGSDeferredUpdates");
valid = set_debug_options && deferred_updates;
}
@ -183,8 +173,7 @@ void EnableOSXDockIcon(bool enable)
if (enable)
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
else
[NSApp setActivationPolicy:
NSApplicationActivationPolicyProhibited];
[NSApp setActivationPolicy:NSApplicationActivationPolicyProhibited];
}
@interface DockView : NSView {
@ -205,127 +194,92 @@ void EnableOSXDockIcon(bool enable)
CGSize size = dirtyRect.size;
/* Draw regular app icon */
NSImage *appIcon = [[NSWorkspace sharedWorkspace]
iconForFile:[[NSBundle mainBundle] bundlePath]];
NSImage *appIcon = [[NSWorkspace sharedWorkspace] iconForFile:[[NSBundle mainBundle] bundlePath]];
[appIcon drawInRect:CGRectMake(0, 0, size.width, size.height)];
/* Draw small icon on top */
float iconSize = 0.45;
CGImageRef image =
_icon.pixmap(size.width, size.height).toImage().toCGImage();
CGImageRef image = _icon.pixmap(size.width, size.height).toImage().toCGImage();
CGContextRef context = [[NSGraphicsContext currentContext] CGContext];
CGContextDrawImage(context,
CGRectMake(size.width * (1 - iconSize), 0,
size.width * iconSize,
size.height * iconSize),
image);
CGContextDrawImage(
context, CGRectMake(size.width * (1 - iconSize), 0, size.width * iconSize, size.height * iconSize), image);
CGImageRelease(image);
}
@end
MacPermissionStatus CheckPermissionWithPrompt(MacPermissionType type,
bool prompt_for_permission)
MacPermissionStatus CheckPermissionWithPrompt(MacPermissionType type, bool prompt_for_permission)
{
__block MacPermissionStatus permissionResponse =
kPermissionNotDetermined;
__block MacPermissionStatus permissionResponse = kPermissionNotDetermined;
switch (type) {
case kAudioDeviceAccess: {
AVAuthorizationStatus audioStatus = [AVCaptureDevice
authorizationStatusForMediaType:AVMediaTypeAudio];
AVAuthorizationStatus audioStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
if (audioStatus == AVAuthorizationStatusNotDetermined &&
prompt_for_permission) {
if (audioStatus == AVAuthorizationStatusNotDetermined && prompt_for_permission) {
os_event_t *block_finished;
os_event_init(&block_finished, OS_EVENT_TYPE_MANUAL);
[AVCaptureDevice
requestAccessForMediaType:AVMediaTypeAudio
completionHandler:^(
BOOL granted
__attribute((unused))) {
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio
completionHandler:^(BOOL granted __attribute((unused))) {
os_event_signal(block_finished);
}];
os_event_wait(block_finished);
os_event_destroy(block_finished);
audioStatus = [AVCaptureDevice
authorizationStatusForMediaType:AVMediaTypeAudio];
audioStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
}
permissionResponse = (MacPermissionStatus) audioStatus;
blog(LOG_INFO, "[macOS] Permission for audio device access %s.",
permissionResponse == kPermissionAuthorized ? "granted"
: "denied");
permissionResponse == kPermissionAuthorized ? "granted" : "denied");
break;
}
case kVideoDeviceAccess: {
AVAuthorizationStatus videoStatus = [AVCaptureDevice
authorizationStatusForMediaType:AVMediaTypeVideo];
AVAuthorizationStatus videoStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if (videoStatus == AVAuthorizationStatusNotDetermined &&
prompt_for_permission) {
if (videoStatus == AVAuthorizationStatusNotDetermined && prompt_for_permission) {
os_event_t *block_finished;
os_event_init(&block_finished, OS_EVENT_TYPE_MANUAL);
[AVCaptureDevice
requestAccessForMediaType:AVMediaTypeVideo
completionHandler:^(
BOOL granted
__attribute((unused))) {
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo
completionHandler:^(BOOL granted __attribute((unused))) {
os_event_signal(block_finished);
}];
os_event_wait(block_finished);
os_event_destroy(block_finished);
videoStatus = [AVCaptureDevice
authorizationStatusForMediaType:AVMediaTypeVideo];
videoStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
}
permissionResponse = (MacPermissionStatus) videoStatus;
blog(LOG_INFO, "[macOS] Permission for video device access %s.",
permissionResponse == kPermissionAuthorized ? "granted"
: "denied");
permissionResponse == kPermissionAuthorized ? "granted" : "denied");
break;
}
case kScreenCapture: {
permissionResponse = (CGPreflightScreenCaptureAccess()
? kPermissionAuthorized
: kPermissionDenied);
permissionResponse = (CGPreflightScreenCaptureAccess() ? kPermissionAuthorized : kPermissionDenied);
if (permissionResponse != kPermissionAuthorized &&
prompt_for_permission) {
permissionResponse = (CGRequestScreenCaptureAccess()
? kPermissionAuthorized
: kPermissionDenied);
if (permissionResponse != kPermissionAuthorized && prompt_for_permission) {
permissionResponse = (CGRequestScreenCaptureAccess() ? kPermissionAuthorized : kPermissionDenied);
}
blog(LOG_INFO, "[macOS] Permission for screen capture %s.",
permissionResponse == kPermissionAuthorized ? "granted"
: "denied");
permissionResponse == kPermissionAuthorized ? "granted" : "denied");
break;
}
case kAccessibility: {
permissionResponse = (AXIsProcessTrusted()
? kPermissionAuthorized
: kPermissionDenied);
permissionResponse = (AXIsProcessTrusted() ? kPermissionAuthorized : kPermissionDenied);
if (permissionResponse != kPermissionAuthorized &&
prompt_for_permission) {
NSDictionary *options = @{
(__bridge id)kAXTrustedCheckOptionPrompt: @YES
};
permissionResponse = (AXIsProcessTrustedWithOptions(
(CFDictionaryRef)options)
? kPermissionAuthorized
if (permissionResponse != kPermissionAuthorized && prompt_for_permission) {
NSDictionary *options = @{(__bridge id) kAXTrustedCheckOptionPrompt: @YES};
permissionResponse = (AXIsProcessTrustedWithOptions((CFDictionaryRef) options) ? kPermissionAuthorized
: kPermissionDenied);
}
blog(LOG_INFO, "[macOS] Permission for accessibility %s.",
permissionResponse == kPermissionAuthorized ? "granted"
: "denied");
permissionResponse == kPermissionAuthorized ? "granted" : "denied");
break;
}
}
@ -336,35 +290,29 @@ MacPermissionStatus CheckPermissionWithPrompt(MacPermissionType type,
void OpenMacOSPrivacyPreferences(const char *tab)
{
NSURL *url = [NSURL
URLWithString:
[NSString
stringWithFormat:
@"x-apple.systempreferences:com.apple.preference.security?Privacy_%s",
tab]];
URLWithString:[NSString
stringWithFormat:@"x-apple.systempreferences:com.apple.preference.security?Privacy_%s", tab]];
[[NSWorkspace sharedWorkspace] openURL:url];
}
void SetMacOSDarkMode(bool dark)
{
if (dark) {
NSApp.appearance =
[NSAppearance appearanceNamed:NSAppearanceNameDarkAqua];
NSApp.appearance = [NSAppearance appearanceNamed:NSAppearanceNameDarkAqua];
} else {
NSApp.appearance =
[NSAppearance appearanceNamed:NSAppearanceNameAqua];
NSApp.appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua];
}
}
void TaskbarOverlayInit() {}
void TaskbarOverlayInit()
{}
void TaskbarOverlaySetStatus(TaskbarOverlayStatus status)
{
QIcon icon;
if (status == TaskbarOverlayStatusActive)
icon = QIcon::fromTheme("obs-active",
QIcon(":/res/images/active_mac.png"));
icon = QIcon::fromTheme("obs-active", QIcon(":/res/images/active_mac.png"));
else if (status == TaskbarOverlayStatusPaused)
icon = QIcon::fromTheme("obs-paused",
QIcon(":/res/images/paused_mac.png"));
icon = QIcon::fromTheme("obs-paused", QIcon(":/res/images/paused_mac.png"));
NSDockTile *tile = [NSApp dockTile];
[tile setContentView:[[DockView alloc] initWithIcon:icon]];

View file

@ -4,15 +4,13 @@
#import <Security/Security.h>
#import <Security/SecKey.h>
bool VerifySignature(const uint8_t *pubKey, const size_t pubKeyLen,
const uint8_t *buf, const size_t len, const uint8_t *sig,
const size_t sigLen)
bool VerifySignature(const uint8_t *pubKey, const size_t pubKeyLen, const uint8_t *buf, const size_t len,
const uint8_t *sig, const size_t sigLen)
{
NSData *pubKeyData = [NSData dataWithBytes:pubKey length:pubKeyLen];
CFArrayRef items = nullptr;
OSStatus res = SecItemImport((CFDataRef)pubKeyData, nullptr, nullptr,
nullptr, (SecItemImportExportFlags)0,
OSStatus res = SecItemImport((CFDataRef) pubKeyData, nullptr, nullptr, nullptr, (SecItemImportExportFlags) 0,
nullptr, nullptr, &items);
if (res != errSecSuccess)
return false;
@ -22,10 +20,8 @@ bool VerifySignature(const uint8_t *pubKey, const size_t pubKeyLen,
NSData *signature = [NSData dataWithBytes:sig length:sigLen];
CFErrorRef errRef;
bool result = SecKeyVerifySignature(
pubKeyRef, kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
(__bridge CFDataRef)signedData, (__bridge CFDataRef)signature,
&errRef);
bool result = SecKeyVerifySignature(pubKeyRef, kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
(__bridge CFDataRef) signedData, (__bridge CFDataRef) signature, &errRef);
CFRelease(items);
return result;

View file

@ -16,19 +16,15 @@
@synthesize branch;
- (nonnull NSSet<NSString *> *)allowedChannelsForUpdater:
(nonnull SPUUpdater *)updater
- (nonnull NSSet<NSString *> *)allowedChannelsForUpdater:(nonnull SPUUpdater *)updater
{
return [NSSet setWithObject:branch];
}
- (void)observeCanCheckForUpdatesWithAction:(QAction *)action
{
[_updaterController.updater
addObserver:self
forKeyPath:NSStringFromSelector(@selector(canCheckForUpdates))
options:(NSKeyValueObservingOptionInitial |
NSKeyValueObservingOptionNew)
[_updaterController.updater addObserver:self forKeyPath:NSStringFromSelector(@selector(canCheckForUpdates))
options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew)
context:(void *) action];
}
@ -37,26 +33,18 @@
change:(NSDictionary<NSKeyValueChangeKey, id> *)change
context:(void *)context
{
if ([keyPath isEqualToString:NSStringFromSelector(
@selector(canCheckForUpdates))]) {
if ([keyPath isEqualToString:NSStringFromSelector(@selector(canCheckForUpdates))]) {
QAction *menuAction = (QAction *) context;
menuAction->setEnabled(
_updaterController.updater.canCheckForUpdates);
menuAction->setEnabled(_updaterController.updater.canCheckForUpdates);
} else {
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
- (void)dealloc
{
@autoreleasepool {
[_updaterController.updater
removeObserver:self
forKeyPath:NSStringFromSelector(
@selector(canCheckForUpdates))];
[_updaterController.updater removeObserver:self forKeyPath:NSStringFromSelector(@selector(canCheckForUpdates))];
}
}
@ -68,12 +56,9 @@ OBSSparkle::OBSSparkle(const char *branch, QAction *checkForUpdatesAction)
updaterDelegate = [[OBSUpdateDelegate alloc] init];
updaterDelegate.branch = [NSString stringWithUTF8String:branch];
updaterDelegate.updaterController =
[[SPUStandardUpdaterController alloc]
initWithStartingUpdater:YES
updaterDelegate:updaterDelegate
[[SPUStandardUpdaterController alloc] initWithStartingUpdater:YES updaterDelegate:updaterDelegate
userDriverDelegate:nil];
[updaterDelegate observeCanCheckForUpdatesWithAction:
checkForUpdatesAction];
[updaterDelegate observeCanCheckForUpdatesWithAction:checkForUpdatesAction];
}
}
@ -88,8 +73,7 @@ void OBSSparkle::checkForUpdates(bool manualCheck)
if (manualCheck) {
[updaterDelegate.updaterController checkForUpdates:nil];
} else {
[updaterDelegate.updaterController
.updater checkForUpdatesInBackground];
[updaterDelegate.updaterController.updater checkForUpdatesInBackground];
}
}
}

View file

@ -34,8 +34,7 @@ struct gl_platform {
static NSOpenGLContext *gl_context_create(NSOpenGLContext *share)
{
NSOpenGLPixelFormatAttribute attributes[] = {
NSOpenGLPFADoubleBuffer, NSOpenGLPFAOpenGLProfile,
NSOpenGLPixelFormatAttribute attributes[] = {NSOpenGLPFADoubleBuffer, NSOpenGLPFAOpenGLProfile,
NSOpenGLProfileVersion3_2Core, 0};
NSOpenGLPixelFormat *pf;
@ -46,8 +45,7 @@ static NSOpenGLContext *gl_context_create(NSOpenGLContext *share)
}
NSOpenGLContext *context;
context = [[NSOpenGLContext alloc] initWithFormat:pf
shareContext:share];
context = [[NSOpenGLContext alloc] initWithFormat:pf shareContext:share];
[pf release];
if (!context) {
blog(LOG_ERROR, "Failed to create context");
@ -59,8 +57,7 @@ static NSOpenGLContext *gl_context_create(NSOpenGLContext *share)
return context;
}
struct gl_platform *gl_platform_create(gs_device_t *device __unused,
uint32_t adapter __unused)
struct gl_platform *gl_platform_create(gs_device_t *device __unused, uint32_t adapter __unused)
{
NSOpenGLContext *context = gl_context_create(nil);
if (!context) {
@ -70,8 +67,7 @@ struct gl_platform *gl_platform_create(gs_device_t *device __unused,
[context makeCurrentContext];
GLint interval = 0;
[context setValues:&interval
forParameter:NSOpenGLContextParameterSwapInterval];
[context setValues:&interval forParameter:NSOpenGLContextParameterSwapInterval];
const bool success = gladLoadGL() != 0;
if (!success) {
@ -107,9 +103,8 @@ bool gl_platform_init_swapchain(struct gs_swap_chain *swap)
[parent makeCurrentContext];
struct gs_init_data *init_data = &swap->info;
swap->wi->texture = device_texture_create(
swap->device, init_data->cx, init_data->cy,
init_data->format, 1, NULL, GS_RENDER_TARGET);
swap->wi->texture = device_texture_create(swap->device, init_data->cx, init_data->cy, init_data->format, 1,
NULL, GS_RENDER_TARGET);
glFlush();
[NSOpenGLContext clearCurrentContext];
@ -123,13 +118,10 @@ bool gl_platform_init_swapchain(struct gs_swap_chain *swap)
[context setView:swap->wi->view];
#pragma clang diagnostic pop
GLint interval = 0;
[context setValues:&interval
forParameter:NSOpenGLContextParameterSwapInterval];
[context setValues:&interval forParameter:NSOpenGLContextParameterSwapInterval];
gl_gen_framebuffers(1, &swap->wi->fbo);
gl_bind_framebuffer(GL_FRAMEBUFFER, swap->wi->fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
swap->wi->texture->texture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, swap->wi->texture->texture, 0);
gl_success("glFrameBufferTexture2D");
glFlush();
[NSOpenGLContext clearCurrentContext];
@ -219,14 +211,9 @@ void gl_update(gs_device_t *device)
[context update];
struct gs_init_data *info = &swap->info;
gs_texture_t *previous = swap->wi->texture;
swap->wi->texture = device_texture_create(device, info->cx,
info->cy,
info->format, 1, NULL,
GS_RENDER_TARGET);
swap->wi->texture = device_texture_create(device, info->cx, info->cy, info->format, 1, NULL, GS_RENDER_TARGET);
gl_bind_framebuffer(GL_FRAMEBUFFER, swap->wi->fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
swap->wi->texture->texture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, swap->wi->texture->texture, 0);
gl_success("glFrameBufferTexture2D");
gs_texture_destroy(previous);
glFlush();
@ -298,8 +285,7 @@ void device_present(gs_device_t *device)
gl_bind_framebuffer(GL_DRAW_FRAMEBUFFER, 0);
const uint32_t width = device->cur_swap->info.cx;
const uint32_t height = device->cur_swap->info.cy;
glBlitFramebuffer(0, 0, width, height, 0, height, width, 0,
GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebuffer(0, 0, width, height, 0, height, width, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
[device->cur_swap->wi->context flushBuffer];
glFlush();
[NSOpenGLContext clearCurrentContext];
@ -314,8 +300,7 @@ bool device_is_monitor_hdr(gs_device_t *device __unused, void *monitor __unused)
return false;
}
void gl_getclientsize(const struct gs_swap_chain *swap, uint32_t *width,
uint32_t *height)
void gl_getclientsize(const struct gs_swap_chain *swap, uint32_t *width, uint32_t *height)
{
if (width)
*width = swap->info.cx;
@ -323,8 +308,7 @@ void gl_getclientsize(const struct gs_swap_chain *swap, uint32_t *width,
*height = swap->info.cy;
}
gs_texture_t *device_texture_create_from_iosurface(gs_device_t *device,
void *iosurf)
gs_texture_t *device_texture_create_from_iosurface(gs_device_t *device, void *iosurf)
{
IOSurfaceRef ref = (IOSurfaceRef) iosurf;
struct gs_texture_2d *tex = bzalloc(sizeof(struct gs_texture_2d));
@ -341,11 +325,9 @@ gs_texture_t *device_texture_create_from_iosurface(gs_device_t *device,
if (pf == 0)
blog(LOG_ERROR, "Invalid IOSurface Buffer");
else if ((pf != bgra_code) && !l10r)
blog(LOG_ERROR, "Unexpected pixel format: %d (%c%c%c%c)", pf,
pf >> 24, pf >> 16, pf >> 8, pf);
blog(LOG_ERROR, "Unexpected pixel format: %d (%c%c%c%c)", pf, pf >> 24, pf >> 16, pf >> 8, pf);
const enum gs_color_format color_format = l10r ? GS_R10G10B10A2
: GS_BGRA;
const enum gs_color_format color_format = l10r ? GS_R10G10B10A2 : GS_BGRA;
tex->base.device = device;
tex->base.type = GS_TEXTURE_2D;
@ -353,8 +335,7 @@ gs_texture_t *device_texture_create_from_iosurface(gs_device_t *device,
tex->base.levels = 1;
tex->base.gl_format = l10r ? GL_BGRA : convert_gs_format(color_format);
tex->base.gl_internal_format = convert_gs_internal_format(color_format);
tex->base.gl_type = l10r ? GL_UNSIGNED_INT_2_10_10_10_REV
: GL_UNSIGNED_INT_8_8_8_8_REV;
tex->base.gl_type = l10r ? GL_UNSIGNED_INT_2_10_10_10_REV : GL_UNSIGNED_INT_8_8_8_8_REV;
tex->base.gl_target = GL_TEXTURE_RECTANGLE_ARB;
tex->base.is_dynamic = false;
tex->base.is_render_target = false;
@ -368,10 +349,9 @@ gs_texture_t *device_texture_create_from_iosurface(gs_device_t *device,
if (!gl_bind_texture(tex->base.gl_target, tex->base.texture))
goto fail;
CGLError err = CGLTexImageIOSurface2D(
[[NSOpenGLContext currentContext] CGLContextObj],
tex->base.gl_target, tex->base.gl_internal_format, tex->width,
tex->height, tex->base.gl_format, tex->base.gl_type, ref, 0);
CGLError err = CGLTexImageIOSurface2D([[NSOpenGLContext currentContext] CGLContextObj], tex->base.gl_target,
tex->base.gl_internal_format, tex->width, tex->height, tex->base.gl_format,
tex->base.gl_type, ref, 0);
if (err != kCGLNoError) {
blog(LOG_ERROR,
@ -432,8 +412,7 @@ bool gs_texture_rebind_iosurface(gs_texture_t *texture, void *iosurf)
if (pf == 0) {
blog(LOG_ERROR, "Invalid IOSurface buffer");
} else if ((pf != bgra_code) && (pf != l10r_code)) {
blog(LOG_ERROR, "Unexpected pixel format: %d (%c%c%c%c)", pf,
pf >> 24, pf >> 16, pf >> 8, pf);
blog(LOG_ERROR, "Unexpected pixel format: %d (%c%c%c%c)", pf, pf >> 24, pf >> 16, pf >> 8, pf);
}
tex->width = (uint32_t) IOSurfaceGetWidth(ref);
@ -442,10 +421,9 @@ bool gs_texture_rebind_iosurface(gs_texture_t *texture, void *iosurf)
if (!gl_bind_texture(tex->base.gl_target, tex->base.texture))
return false;
CGLError err = CGLTexImageIOSurface2D(
[[NSOpenGLContext currentContext] CGLContextObj],
tex->base.gl_target, tex->base.gl_internal_format, tex->width,
tex->height, tex->base.gl_format, tex->base.gl_type, ref, 0);
CGLError err = CGLTexImageIOSurface2D([[NSOpenGLContext currentContext] CGLContextObj], tex->base.gl_target,
tex->base.gl_internal_format, tex->width, tex->height, tex->base.gl_format,
tex->base.gl_type, ref, 0);
if (err != kCGLNoError) {
blog(LOG_ERROR,

View file

@ -15,7 +15,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
#include "util/platform.h"
#include "util/dstr.h"
#include "obs.h"
#include "obs-internal.h"
@ -44,21 +43,17 @@ const char *get_module_extension(void)
void add_default_module_paths(void)
{
NSURL *pluginURL = [[NSBundle mainBundle] builtInPlugInsURL];
NSString *pluginModulePath = [[pluginURL path]
stringByAppendingString:@"/%module%.plugin/Contents/MacOS/"];
NSString *pluginDataPath = [[pluginURL path]
stringByAppendingString:@"/%module%.plugin/Contents/Resources/"];
NSString *pluginModulePath = [[pluginURL path] stringByAppendingString:@"/%module%.plugin/Contents/MacOS/"];
NSString *pluginDataPath = [[pluginURL path] stringByAppendingString:@"/%module%.plugin/Contents/Resources/"];
obs_add_module_path(pluginModulePath.UTF8String,
pluginDataPath.UTF8String);
obs_add_module_path(pluginModulePath.UTF8String, pluginDataPath.UTF8String);
}
char *find_libobs_data_file(const char *file)
{
NSBundle *frameworkBundle =
[NSBundle bundleWithIdentifier:@"com.obsproject.libobs"];
NSString *libobsDataPath = [[[frameworkBundle bundleURL] path]
stringByAppendingFormat:@"/%@/%s", @"Resources", file];
NSBundle *frameworkBundle = [NSBundle bundleWithIdentifier:@"com.obsproject.libobs"];
NSString *libobsDataPath =
[[[frameworkBundle bundleURL] path] stringByAppendingFormat:@"/%@/%s", @"Resources", file];
size_t path_length = strlen(libobsDataPath.UTF8String);
char *path = bmalloc(path_length + 1);
@ -100,14 +95,12 @@ static void log_processor_speed(void)
static void log_processor_cores(void)
{
blog(LOG_INFO, "Physical Cores: %d, Logical Cores: %d",
os_get_physical_cores(), os_get_logical_cores());
blog(LOG_INFO, "Physical Cores: %d, Logical Cores: %d", os_get_physical_cores(), os_get_logical_cores());
}
static void log_emulation_status(void)
{
blog(LOG_INFO, "Rosetta translation used: %s",
os_get_emulation_status() ? "true" : "false");
blog(LOG_INFO, "Rosetta translation used: %s", os_get_emulation_status() ? "true" : "false");
}
static void log_available_memory(void)
@ -119,16 +112,14 @@ static void log_available_memory(void)
size = sizeof(memory_available);
ret = sysctlbyname("hw.memsize", &memory_available, &size, NULL, 0);
if (ret == 0)
blog(LOG_INFO, "Physical Memory: %lldMB Total",
memory_available / 1024 / 1024);
blog(LOG_INFO, "Physical Memory: %lldMB Total", memory_available / 1024 / 1024);
}
static void log_os(void)
{
NSProcessInfo *pi = [NSProcessInfo processInfo];
blog(LOG_INFO, "OS Name: macOS");
blog(LOG_INFO, "OS Version: %s",
[[pi operatingSystemVersionString] UTF8String]);
blog(LOG_INFO, "OS Version: %s", [[pi operatingSystemVersionString] UTF8String]);
}
static void log_kernel_version(void)
@ -156,12 +147,10 @@ void log_system_info(void)
static bool dstr_from_cfstring(struct dstr *str, CFStringRef ref)
{
CFIndex length = CFStringGetLength(ref);
CFIndex max_size = CFStringGetMaximumSizeForEncoding(
length, kCFStringEncodingUTF8);
CFIndex max_size = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8);
dstr_reserve(str, max_size);
if (!CFStringGetCString(ref, str->array, max_size,
kCFStringEncodingUTF8))
if (!CFStringGetCString(ref, str->array, max_size, kCFStringEncodingUTF8))
return false;
str->len = strlen(str->array);
@ -510,17 +499,14 @@ void obs_key_to_str(obs_key_t key, struct dstr *str)
UInt32 dead_key_state = 0;
UniCharCount len = 0;
OSStatus err =
UCKeyTranslate(plat->layout, code, kUCKeyActionDown,
OSStatus err = UCKeyTranslate(plat->layout, code, kUCKeyActionDown,
0x104, //caps lock for upper case letters
LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit,
&dead_key_state, max_length, &len, buffer);
LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit, &dead_key_state, max_length, &len,
buffer);
if (err == noErr && len <= 0 && dead_key_state) {
err = UCKeyTranslate(plat->layout, kVK_Space, kUCKeyActionDown,
0x104, LMGetKbdType(),
kUCKeyTranslateNoDeadKeysBit,
&dead_key_state, max_length, &len, buffer);
err = UCKeyTranslate(plat->layout, kVK_Space, kUCKeyActionDown, 0x104, LMGetKbdType(),
kUCKeyTranslateNoDeadKeysBit, &dead_key_state, max_length, &len, buffer);
}
hotkeys_release(plat);
@ -541,8 +527,7 @@ void obs_key_to_str(obs_key_t key, struct dstr *str)
goto err;
}
CFStringRef string = CFStringCreateWithCharactersNoCopy(
NULL, buffer, len, kCFAllocatorNull);
CFStringRef string = CFStringCreateWithCharactersNoCopy(NULL, buffer, len, kCFAllocatorNull);
if (!string) {
blog(LOG_ERROR,
"hotkey-cocoa: Could not create CFStringRef "
@ -572,16 +557,14 @@ err:
#define OBS_COCOA_MODIFIER_SIZE 7
static void unichar_to_utf8(const UniChar *c, char *buff)
{
CFStringRef string = CFStringCreateWithCharactersNoCopy(
NULL, c, 2, kCFAllocatorNull);
CFStringRef string = CFStringCreateWithCharactersNoCopy(NULL, c, 2, kCFAllocatorNull);
if (!string) {
blog(LOG_ERROR, "hotkey-cocoa: Could not create CFStringRef "
"while populating modifier strings");
return;
}
if (!CFStringGetCString(string, buff, OBS_COCOA_MODIFIER_SIZE,
kCFStringEncodingUTF8))
if (!CFStringGetCString(string, buff, OBS_COCOA_MODIFIER_SIZE, kCFStringEncodingUTF8))
blog(LOG_ERROR,
"hotkey-cocoa: Error while populating "
" modifier string with glyph %d (0x%x)",
@ -625,12 +608,9 @@ void obs_key_combination_to_str(obs_key_combination_t key, struct dstr *str)
}
#define CHECK_MODIFIER(mod, str) ((key.modifiers & mod) ? str : "")
dstr_printf(str, "%s%s%s%s%s",
CHECK_MODIFIER(INTERACT_CONTROL_KEY, ctrl_str),
CHECK_MODIFIER(INTERACT_ALT_KEY, opt_str),
CHECK_MODIFIER(INTERACT_SHIFT_KEY, shift_str),
CHECK_MODIFIER(INTERACT_COMMAND_KEY, cmd_str),
key_str.len ? key_str.array : "");
dstr_printf(str, "%s%s%s%s%s", CHECK_MODIFIER(INTERACT_CONTROL_KEY, ctrl_str),
CHECK_MODIFIER(INTERACT_ALT_KEY, opt_str), CHECK_MODIFIER(INTERACT_SHIFT_KEY, shift_str),
CHECK_MODIFIER(INTERACT_COMMAND_KEY, cmd_str), key_str.len ? key_str.array : "");
#undef CHECK_MODIFIER
dstr_free(&key_str);
@ -639,8 +619,7 @@ void obs_key_combination_to_str(obs_key_combination_t key, struct dstr *str)
static bool log_layout_name(TISInputSourceRef tis)
{
struct dstr layout_name = {0};
CFStringRef sid = (CFStringRef)TISGetInputSourceProperty(
tis, kTISPropertyInputSourceID);
CFStringRef sid = (CFStringRef) TISGetInputSourceProperty(tis, kTISPropertyInputSourceID);
if (!sid) {
blog(LOG_ERROR, "hotkeys-cocoa: Failed getting InputSourceID");
return false;
@ -666,20 +645,13 @@ static void handle_monitor_event(obs_hotkeys_platform_t *plat, NSEvent *event)
{
if (event.type == NSEventTypeFlagsChanged) {
NSEventModifierFlags flags = event.modifierFlags;
plat->is_key_down[OBS_KEY_CAPSLOCK] =
!!(flags & NSEventModifierFlagCapsLock);
plat->is_key_down[OBS_KEY_SHIFT] =
!!(flags & NSEventModifierFlagShift);
plat->is_key_down[OBS_KEY_ALT] =
!!(flags & NSEventModifierFlagOption);
plat->is_key_down[OBS_KEY_META] =
!!(flags & NSEventModifierFlagCommand);
plat->is_key_down[OBS_KEY_CONTROL] =
!!(flags & NSEventModifierFlagControl);
} else if (event.type == NSEventTypeKeyDown ||
event.type == NSEventTypeKeyUp) {
plat->is_key_down[obs_key_from_virtual_key(event.keyCode)] =
(event.type == NSEventTypeKeyDown);
plat->is_key_down[OBS_KEY_CAPSLOCK] = !!(flags & NSEventModifierFlagCapsLock);
plat->is_key_down[OBS_KEY_SHIFT] = !!(flags & NSEventModifierFlagShift);
plat->is_key_down[OBS_KEY_ALT] = !!(flags & NSEventModifierFlagOption);
plat->is_key_down[OBS_KEY_META] = !!(flags & NSEventModifierFlagCommand);
plat->is_key_down[OBS_KEY_CONTROL] = !!(flags & NSEventModifierFlagControl);
} else if (event.type == NSEventTypeKeyDown || event.type == NSEventTypeKeyUp) {
plat->is_key_down[obs_key_from_virtual_key(event.keyCode)] = (event.type == NSEventTypeKeyDown);
}
}
@ -698,15 +670,12 @@ static bool init_hotkeys_platform(obs_hotkeys_platform_t **plat_)
void (^handler)(NSEvent *) = ^(NSEvent *event) {
handle_monitor_event(plat, event);
};
plat->monitor = (__bridge CFTypeRef)[NSEvent
addGlobalMonitorForEventsMatchingMask:NSEventMaskKeyDown |
NSEventMaskKeyUp |
NSEventMaskFlagsChanged
plat->monitor = (__bridge CFTypeRef)
[NSEvent addGlobalMonitorForEventsMatchingMask:NSEventMaskKeyDown | NSEventMaskKeyUp | NSEventMaskFlagsChanged
handler:handler];
plat->tis = TISCopyCurrentKeyboardLayoutInputSource();
plat->layout_data = (CFDataRef)TISGetInputSourceProperty(
plat->tis, kTISPropertyUnicodeKeyLayoutData);
plat->layout_data = (CFDataRef) TISGetInputSourceProperty(plat->tis, kTISPropertyUnicodeKeyLayoutData);
if (!plat->layout_data) {
blog(LOG_ERROR, "hotkeys-cocoa: Failed getting LayoutData");
@ -747,8 +716,7 @@ static inline void free_hotkeys_platform(obs_hotkeys_platform_t *plat)
bfree(plat);
}
static void input_method_changed(CFNotificationCenterRef nc, void *observer,
CFStringRef name, const void *object,
static void input_method_changed(CFNotificationCenterRef nc, void *observer, CFStringRef name, const void *object,
CFDictionaryRef user_info)
{
UNUSED_PARAMETER(nc);
@ -765,8 +733,7 @@ static void input_method_changed(CFNotificationCenterRef nc, void *observer,
pthread_mutex_lock(&hotkeys->mutex);
plat = hotkeys->platform_context;
if (new_plat && plat &&
new_plat->layout_data == plat->layout_data) {
if (new_plat && plat && new_plat->layout_data == plat->layout_data) {
pthread_mutex_unlock(&hotkeys->mutex);
hotkeys_release(new_plat);
return;
@ -778,8 +745,7 @@ static void input_method_changed(CFNotificationCenterRef nc, void *observer,
pthread_mutex_unlock(&hotkeys->mutex);
calldata_t params = {0};
signal_handler_signal(hotkeys->signals, "hotkey_layout_change",
&params);
signal_handler_signal(hotkeys->signals, "hotkey_layout_change", &params);
if (plat)
hotkeys_release(plat);
}
@ -787,9 +753,7 @@ static void input_method_changed(CFNotificationCenterRef nc, void *observer,
bool obs_hotkeys_platform_init(struct obs_core_hotkeys *hotkeys)
{
CFNotificationCenterAddObserver(
CFNotificationCenterGetDistributedCenter(), hotkeys,
input_method_changed,
CFNotificationCenterAddObserver(CFNotificationCenterGetDistributedCenter(), hotkeys, input_method_changed,
kTISNotifySelectedKeyboardInputSourceChanged, NULL,
CFNotificationSuspensionBehaviorDeliverImmediately);
@ -799,8 +763,7 @@ bool obs_hotkeys_platform_init(struct obs_core_hotkeys *hotkeys)
void obs_hotkeys_platform_free(struct obs_core_hotkeys *hotkeys)
{
CFNotificationCenterRemoveEveryObserver(
CFNotificationCenterGetDistributedCenter(), hotkeys);
CFNotificationCenterRemoveEveryObserver(CFNotificationCenterGetDistributedCenter(), hotkeys);
hotkeys_release(hotkeys->platform_context);
}
@ -855,8 +818,7 @@ static bool mouse_button_pressed(obs_key_t key, bool *pressed)
return true;
}
bool obs_hotkeys_platform_is_pressed(obs_hotkeys_platform_t *plat,
obs_key_t key)
bool obs_hotkeys_platform_is_pressed(obs_hotkeys_platform_t *plat, obs_key_t key)
{
bool mouse_pressed = false;
if (mouse_button_pressed(key, &mouse_pressed))

View file

@ -44,11 +44,9 @@ uint64_t os_gettime_ns(void)
}
/* gets the location [domain mask]/Library/Application Support/[name] */
static int os_get_path_internal(char *dst, size_t size, const char *name,
NSSearchPathDomainMask domainMask)
static int os_get_path_internal(char *dst, size_t size, const char *name, NSSearchPathDomainMask domainMask)
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSApplicationSupportDirectory, domainMask, YES);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, domainMask, YES);
if ([paths count] == 0)
bcrash("Could not get home directory (platform-cocoa)");
@ -62,19 +60,16 @@ static int os_get_path_internal(char *dst, size_t size, const char *name,
return snprintf(dst, size, "%s/%s", base_path, name);
}
static char *os_get_path_ptr_internal(const char *name,
NSSearchPathDomainMask domainMask)
static char *os_get_path_ptr_internal(const char *name, NSSearchPathDomainMask domainMask)
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSApplicationSupportDirectory, domainMask, YES);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, domainMask, YES);
if ([paths count] == 0)
bcrash("Could not get home directory (platform-cocoa)");
NSString *application_support = paths[0];
NSUInteger len = [application_support
lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
NSUInteger len = [application_support lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
char *path_ptr = bmalloc(len + 1);
@ -144,8 +139,7 @@ struct os_cpu_usage_info {
int core_count;
};
static inline void add_time_value(time_value_t *dst, time_value_t *a,
time_value_t *b)
static inline void add_time_value(time_value_t *dst, time_value_t *a, time_value_t *b)
{
dst->microseconds = a->microseconds + b->microseconds;
dst->seconds = a->seconds + b->seconds;
@ -169,19 +163,16 @@ static bool get_time_info(int64_t *cpu_time, int64_t *sys_time)
*sys_time = 0;
count = TASK_THREAD_TIMES_INFO_COUNT;
kern_ret = task_info(task, TASK_THREAD_TIMES_INFO,
(task_info_t)&thread_data, &count);
kern_ret = task_info(task, TASK_THREAD_TIMES_INFO, (task_info_t) &thread_data, &count);
if (kern_ret != KERN_SUCCESS)
return false;
count = TASK_BASIC_INFO_64_COUNT;
kern_ret = task_info(task, TASK_BASIC_INFO_64, (task_info_t)&task_data,
&count);
kern_ret = task_info(task, TASK_BASIC_INFO_64, (task_info_t) &task_data, &count);
if (kern_ret != KERN_SUCCESS)
return false;
add_time_value(&cur_time, &thread_data.user_time,
&thread_data.system_time);
add_time_value(&cur_time, &thread_data.user_time, &thread_data.system_time);
add_time_value(&cur_time, &cur_time, &task_data.user_time);
add_time_value(&cur_time, &cur_time, &task_data.system_time);
@ -220,8 +211,7 @@ double os_cpu_usage_info_query(os_cpu_usage_info_t *info)
info->last_sys_time = sys_time;
info->last_cpu_time = cpu_time;
return (double)sys_time_delta * 100.0 / (double)cpu_time_delta /
(double)info->core_count;
return (double) sys_time_delta * 100.0 / (double) cpu_time_delta / (double) info->core_count;
}
void os_cpu_usage_info_destroy(os_cpu_usage_info_t *info)
@ -239,8 +229,7 @@ os_performance_token_t *os_request_high_performance(const char *reason)
return nil;
//taken from http://stackoverflow.com/a/20100906
id activity = [pi beginActivityWithOptions:0x00FFFFFF
reason:@(reason)];
id activity = [pi beginActivityWithOptions:0x00FFFFFF reason:@(reason)];
return CFBridgingRetain(activity);
}
@ -269,11 +258,9 @@ os_inhibit_t *os_inhibit_sleep_create(const char *reason)
{
struct os_inhibit_info *info = bzalloc(sizeof(*info));
if (!reason)
info->reason = CFStringCreateWithCString(
kCFAllocatorDefault, reason, kCFStringEncodingUTF8);
info->reason = CFStringCreateWithCString(kCFAllocatorDefault, reason, kCFStringEncodingUTF8);
else
info->reason =
CFStringCreateCopy(kCFAllocatorDefault, CFSTR(""));
info->reason = CFStringCreateCopy(kCFAllocatorDefault, CFSTR(""));
return info;
}
@ -288,11 +275,9 @@ bool os_inhibit_sleep_set_active(os_inhibit_t *info, bool active)
return false;
if (active) {
IOPMAssertionDeclareUserActivity(
info->reason, kIOPMUserActiveLocal, &info->user_id);
success = IOPMAssertionCreateWithName(
kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn,
info->reason, &info->sleep_id);
IOPMAssertionDeclareUserActivity(info->reason, kIOPMUserActiveLocal, &info->user_id);
success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, info->reason,
&info->sleep_id);
if (success != kIOReturnSuccess) {
blog(LOG_WARNING, "Failed to disable sleep");
@ -326,8 +311,7 @@ bool os_get_emulation_status(void)
#else
int rosettaTranslated = 0;
size_t size = sizeof(rosettaTranslated);
if (sysctlbyname("sysctl.proc_translated", &rosettaTranslated, &size,
NULL, 0) == -1)
if (sysctlbyname("sysctl.proc_translated", &rosettaTranslated, &size, NULL, 0) == -1)
return false;
return rosettaTranslated == 1;
@ -345,13 +329,11 @@ static void os_get_cores_internal(void)
int ret;
size = sizeof(physical_cores);
ret = sysctlbyname("machdep.cpu.core_count", &physical_cores, &size,
NULL, 0);
ret = sysctlbyname("machdep.cpu.core_count", &physical_cores, &size, NULL, 0);
if (ret != 0)
return;
ret = sysctlbyname("machdep.cpu.thread_count", &logical_cores, &size,
NULL, 0);
ret = sysctlbyname("machdep.cpu.thread_count", &logical_cores, &size, NULL, 0);
}
int os_get_physical_cores(void)
@ -371,8 +353,7 @@ int os_get_logical_cores(void)
static inline bool os_get_sys_memory_usage_internal(vm_statistics_t vmstat)
{
mach_msg_type_number_t out_count = HOST_VM_INFO_COUNT;
if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)vmstat,
&out_count) != KERN_SUCCESS)
if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t) vmstat, &out_count) != KERN_SUCCESS)
return false;
return true;
}
@ -408,14 +389,12 @@ uint64_t os_get_sys_total_size(void)
return total_memory;
}
static inline bool
os_get_proc_memory_usage_internal(mach_task_basic_info_data_t *taskinfo)
static inline bool os_get_proc_memory_usage_internal(mach_task_basic_info_data_t *taskinfo)
{
const task_flavor_t flavor = MACH_TASK_BASIC_INFO;
mach_msg_type_number_t out_count = MACH_TASK_BASIC_INFO_COUNT;
if (task_info(mach_task_self(), flavor, (task_info_t)taskinfo,
&out_count) != KERN_SUCCESS)
if (task_info(mach_task_self(), flavor, (task_info_t) taskinfo, &out_count) != KERN_SUCCESS)
return false;
return true;
}
@ -456,16 +435,14 @@ char *cfstr_copy_cstr(CFStringRef cfstring, CFStringEncoding cfstring_encoding)
return NULL;
// Try the quick way to obtain the buffer
const char *tmp_buffer =
CFStringGetCStringPtr(cfstring, cfstring_encoding);
const char *tmp_buffer = CFStringGetCStringPtr(cfstring, cfstring_encoding);
if (tmp_buffer != NULL)
return bstrdup(tmp_buffer);
// The quick way did not work, try the more expensive one
CFIndex length = CFStringGetLength(cfstring);
CFIndex max_size =
CFStringGetMaximumSizeForEncoding(length, cfstring_encoding);
CFIndex max_size = CFStringGetMaximumSizeForEncoding(length, cfstring_encoding);
// If result would exceed LONG_MAX, kCFNotFound is returned
if (max_size == kCFNotFound)
@ -481,8 +458,7 @@ char *cfstr_copy_cstr(CFStringRef cfstring, CFStringEncoding cfstring_encoding)
}
// Copy CFString in requested encoding to buffer
Boolean success = CFStringGetCString(cfstring, buffer, max_size,
cfstring_encoding);
Boolean success = CFStringGetCString(cfstring, buffer, max_size, cfstring_encoding);
if (!success) {
bfree(buffer);
@ -495,15 +471,13 @@ char *cfstr_copy_cstr(CFStringRef cfstring, CFStringEncoding cfstring_encoding)
* Returns true on success or false on failure.
* In case of failure, the dstr capacity but not size is changed.
*/
bool cfstr_copy_dstr(CFStringRef cfstring, CFStringEncoding cfstring_encoding,
struct dstr *str)
bool cfstr_copy_dstr(CFStringRef cfstring, CFStringEncoding cfstring_encoding, struct dstr *str)
{
if (!cfstring)
return false;
// Try the quick way to obtain the buffer
const char *tmp_buffer =
CFStringGetCStringPtr(cfstring, cfstring_encoding);
const char *tmp_buffer = CFStringGetCStringPtr(cfstring, cfstring_encoding);
if (tmp_buffer != NULL) {
dstr_copy(str, tmp_buffer);
@ -512,8 +486,7 @@ bool cfstr_copy_dstr(CFStringRef cfstring, CFStringEncoding cfstring_encoding,
// The quick way did not work, try the more expensive one
CFIndex length = CFStringGetLength(cfstring);
CFIndex max_size =
CFStringGetMaximumSizeForEncoding(length, cfstring_encoding);
CFIndex max_size = CFStringGetMaximumSizeForEncoding(length, cfstring_encoding);
// If result would exceed LONG_MAX, kCFNotFound is returned
if (max_size == kCFNotFound)
@ -525,8 +498,7 @@ bool cfstr_copy_dstr(CFStringRef cfstring, CFStringEncoding cfstring_encoding,
dstr_ensure_capacity(str, max_size);
// Copy CFString in requested encoding to dstr buffer
Boolean success = CFStringGetCString(cfstring, str->array, max_size,
cfstring_encoding);
Boolean success = CFStringGetCString(cfstring, str->array, max_size, cfstring_encoding);
if (success)
dstr_resize(str, max_size);

File diff suppressed because it is too large Load diff

View file

@ -35,8 +35,7 @@ typedef struct CF_BRIDGED_TYPE(id) CGDisplayStream *CGDisplayStreamRef;
regions were merely copied from one place to another. A routine is provided to merge two update refs together in cases
where apps need to coalesce the values because they decided to skip processing for one or more frames.
*/
typedef const struct CF_BRIDGED_TYPE(id)
CGDisplayStreamUpdate *CGDisplayStreamUpdateRef;
typedef const struct CF_BRIDGED_TYPE(id) CGDisplayStreamUpdate *CGDisplayStreamUpdateRef;
/*!
@enum CGDisplayStreamUpdateRectType
@ -84,8 +83,7 @@ typedef CF_ENUM(int32_t, CGDisplayStreamFrameStatus) {
of the handler, you must CFRetain() it, as it will be CFRelease()'d by the CGDisplayStream after the handler returns. The updateRef will be NULL in cases
when status is not kCGDisplayStreamFrameStatusFrameComplete.
*/
typedef void (^CGDisplayStreamFrameAvailableHandler)(
CGDisplayStreamFrameStatus status, uint64_t displayTime,
typedef void (^CGDisplayStreamFrameAvailableHandler)(CGDisplayStreamFrameStatus status, uint64_t displayTime,
IOSurfaceRef __nullable frameSurface,
CGDisplayStreamUpdateRef __nullable updateRef);
@ -94,8 +92,7 @@ typedef void (^CGDisplayStreamFrameAvailableHandler)(
@abstract Returns the CF "class" ID for CGDisplayStreamUpdate
@result The CFTypeID of the CGDisplayStreamUpdate class.
*/
CG_EXTERN CFTypeID
CGDisplayStreamUpdateGetTypeID(void) CG_AVAILABLE_BUT_DEPRECATED(
CG_EXTERN CFTypeID CGDisplayStreamUpdateGetTypeID(void) CG_AVAILABLE_BUT_DEPRECATED(
11.0, 14.0,
"There is no direct replacement for this function. Please use ScreenCaptureKit API's SCStreamOutputType instead");
@ -107,12 +104,11 @@ CGDisplayStreamUpdateGetTypeID(void) CG_AVAILABLE_BUT_DEPRECATED(
@param rectCount A pointer to where the count of the number of rectangles in the array is to be returned. Must not be NULL.
@result A pointer to the array of CGRectangles. This array should not be freed by the caller.
*/
CG_EXTERN const CGRect *__nullable CGDisplayStreamUpdateGetRects(
CGDisplayStreamUpdateRef __nullable updateRef,
CGDisplayStreamUpdateRectType rectType, size_t *rectCount)
CG_EXTERN const CGRect *__nullable CGDisplayStreamUpdateGetRects(CGDisplayStreamUpdateRef __nullable updateRef,
CGDisplayStreamUpdateRectType rectType,
size_t *rectCount)
CG_AVAILABLE_BUT_DEPRECATED(
11.0, 14.0,
"Please use ScreenCaptureKit API's SCStreamFrameInfo with SCStreamFrameInfoContentRect instead");
11.0, 14.0, "Please use ScreenCaptureKit API's SCStreamFrameInfo with SCStreamFrameInfoContentRect instead");
/*!
@function CGDisplayStreamUpdateCreateMerged
@ -126,10 +122,8 @@ CG_EXTERN const CGRect *__nullable CGDisplayStreamUpdateGetRects(
@param secondUpdate The second update (in a temporal sense)
@result The new CGDisplayStreamUpdateRef
*/
CG_EXTERN CGDisplayStreamUpdateRef __nullable
CGDisplayStreamUpdateCreateMergedUpdate(
CGDisplayStreamUpdateRef __nullable firstUpdate,
CGDisplayStreamUpdateRef __nullable secondUpdate)
CG_EXTERN CGDisplayStreamUpdateRef __nullable CGDisplayStreamUpdateCreateMergedUpdate(
CGDisplayStreamUpdateRef __nullable firstUpdate, CGDisplayStreamUpdateRef __nullable secondUpdate)
CG_AVAILABLE_BUT_DEPRECATED(
11.0, 14.0,
"There is no direct replacement for this function. Please use ScreenCaptureKit API's SCStreamFrameInfo to replace CGDisplayStreamUpdate");
@ -142,11 +136,10 @@ CGDisplayStreamUpdateCreateMergedUpdate(
@param dy A pointer to a CGFloat to store the y component of the movement delta
@discussion The delta values describe the offset from the moved rectangles back to the source location.
*/
CG_EXTERN void CGDisplayStreamUpdateGetMovedRectsDelta(
CGDisplayStreamUpdateRef __nullable updateRef, CGFloat *dx, CGFloat *dy)
CG_EXTERN void CGDisplayStreamUpdateGetMovedRectsDelta(CGDisplayStreamUpdateRef __nullable updateRef, CGFloat *dx,
CGFloat *dy)
CG_AVAILABLE_BUT_DEPRECATED(
11.0, 14.0,
"Please use ScreenCaptureKit API's SCStreamFrameInfo with SCStreamFrameInfoContentRect instead");
11.0, 14.0, "Please use ScreenCaptureKit API's SCStreamFrameInfo with SCStreamFrameInfoContentRect instead");
/*!
@function CGDisplayStreamGetDropCount
@ -156,9 +149,7 @@ CG_EXTERN void CGDisplayStreamUpdateGetMovedRectsDelta(
@discussion This call is primarily useful for performance measurement to determine if the client is keeping up with
all WindowServer updates.
*/
CG_EXTERN size_t
CGDisplayStreamUpdateGetDropCount(CGDisplayStreamUpdateRef __nullable updateRef)
CG_AVAILABLE_BUT_DEPRECATED(
CG_EXTERN size_t CGDisplayStreamUpdateGetDropCount(CGDisplayStreamUpdateRef __nullable updateRef) CG_AVAILABLE_BUT_DEPRECATED(
11.0, 14.0,
"There is no direct replacement for this function. Please use ScreenCaptureKit API's SCStreamFrameInfo to replace CGDisplayStreamUpdate");
@ -235,8 +226,7 @@ CG_EXTERN const CFStringRef kCGDisplayStreamQueueDepth CG_AVAILABLE_BUT_DEPRECAT
The value should be one of the three kCGDisplayStreamYCbCrMatrix values specified below.
*/
CG_EXTERN const CFStringRef kCGDisplayStreamYCbCrMatrix CG_AVAILABLE_BUT_DEPRECATED(
11.0, 14.0,
"Please use ScreenCaptureKit API's SCStreamConfiguration colorMatrix property");
11.0, 14.0, "Please use ScreenCaptureKit API's SCStreamConfiguration colorMatrix property");
/* Supported YCbCr matrices. Note that these strings have identical values to the equivalent CoreVideo strings. */
CG_EXTERN const CFStringRef kCGDisplayStreamYCbCrMatrix_ITU_R_709_2;
@ -272,12 +262,11 @@ CG_EXTERN CFTypeID CGDisplayStreamGetTypeID(void) CG_AVAILABLE_BUT_DEPRECATED(
@param handler A block that will be called for frame deliver.
@result The new CGDisplayStream object.
*/
CG_EXTERN CGDisplayStreamRef __nullable CGDisplayStreamCreate(
CGDirectDisplayID display, size_t outputWidth, size_t outputHeight,
int32_t pixelFormat, CFDictionaryRef __nullable properties,
CG_EXTERN CGDisplayStreamRef __nullable CGDisplayStreamCreate(CGDirectDisplayID display, size_t outputWidth,
size_t outputHeight, int32_t pixelFormat,
CFDictionaryRef __nullable properties,
CGDisplayStreamFrameAvailableHandler __nullable handler)
CG_AVAILABLE_BUT_DEPRECATED(
11.0, 14.0,
CG_AVAILABLE_BUT_DEPRECATED(11.0, 14.0,
"Please use ScreenCaptureKit API's initWithFilter:configuration:delegate: instead");
/*!
@ -295,12 +284,10 @@ CG_EXTERN CGDisplayStreamRef __nullable CGDisplayStreamCreate(
@result The new CGDisplayStream object.
*/
CG_EXTERN CGDisplayStreamRef __nullable CGDisplayStreamCreateWithDispatchQueue(
CGDirectDisplayID display, size_t outputWidth, size_t outputHeight,
int32_t pixelFormat, CFDictionaryRef __nullable properties,
dispatch_queue_t queue,
CGDirectDisplayID display, size_t outputWidth, size_t outputHeight, int32_t pixelFormat,
CFDictionaryRef __nullable properties, dispatch_queue_t queue,
CGDisplayStreamFrameAvailableHandler __nullable handler)
CG_AVAILABLE_BUT_DEPRECATED(
11.0, 14.0,
CG_AVAILABLE_BUT_DEPRECATED(11.0, 14.0,
"Please use ScreenCaptureKit API's initWithFilter:configuration:delegate: instead");
/*!
@ -309,11 +296,8 @@ CG_EXTERN CGDisplayStreamRef __nullable CGDisplayStreamCreateWithDispatchQueue(
@param displayStream to be started
@result kCGErrorSuccess If the display stream was started, otherwise an error.
*/
CG_EXTERN CGError
CGDisplayStreamStart(CGDisplayStreamRef cg_nullable displayStream)
CG_AVAILABLE_BUT_DEPRECATED(
11.0, 14.0,
"Please use ScreenCaptureKit API's startCaptureWithCompletionHandler: to start a stream instead");
CG_EXTERN CGError CGDisplayStreamStart(CGDisplayStreamRef cg_nullable displayStream) CG_AVAILABLE_BUT_DEPRECATED(
11.0, 14.0, "Please use ScreenCaptureKit API's startCaptureWithCompletionHandler: to start a stream instead");
/*!
@function CGDisplayStreamStop
@ -324,11 +308,8 @@ CGDisplayStreamStart(CGDisplayStreamRef cg_nullable displayStream)
status of kCGDisplayStreamFrameStatusStopped. After that point it is safe to release the CGDisplayStream.
It is safe to call this function from within the handler block, but the previous caveat still applies.
*/
CG_EXTERN CGError
CGDisplayStreamStop(CGDisplayStreamRef cg_nullable displayStream)
CG_AVAILABLE_BUT_DEPRECATED(
11.0, 14.0,
"Please use ScreenCaptureKit API's stopCaptureWithCompletionHandler: to stop a stream instead");
CG_EXTERN CGError CGDisplayStreamStop(CGDisplayStreamRef cg_nullable displayStream) CG_AVAILABLE_BUT_DEPRECATED(
11.0, 14.0, "Please use ScreenCaptureKit API's stopCaptureWithCompletionHandler: to stop a stream instead");
/*!
@function CGDisplayStreamGetRunLoopSource
@ -337,8 +318,7 @@ CGDisplayStreamStop(CGDisplayStreamRef cg_nullable displayStream)
@result The CFRunLoopSource for this displayStream. Note: This function will return NULL if the
display stream was created via CGDisplayStreamCreateWithDispatchQueue().
*/
CG_EXTERN CFRunLoopSourceRef __nullable
CGDisplayStreamGetRunLoopSource(CGDisplayStreamRef cg_nullable displayStream)
CG_EXTERN CFRunLoopSourceRef __nullable CGDisplayStreamGetRunLoopSource(CGDisplayStreamRef cg_nullable displayStream)
CG_AVAILABLE_BUT_DEPRECATED(
11.0, 14.0,
"There is no direct replacement for this function. Please use ScreenCaptureKit API's SCStream to replace CGDisplayStream");

View file

@ -127,17 +127,14 @@ static inline void update_window_params(struct display_capture *dc)
if (!requires_window(dc->crop))
return;
NSArray *arr = (NSArray *)CGWindowListCopyWindowInfo(
kCGWindowListOptionIncludingWindow, dc->window.window_id);
NSArray *arr = (NSArray *) CGWindowListCopyWindowInfo(kCGWindowListOptionIncludingWindow, dc->window.window_id);
if (arr.count) {
NSDictionary *dict = arr[0];
NSDictionary *ref = dict[(NSString *) kCGWindowBounds];
CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)ref,
&dc->window_rect);
CGRectMakeWithDictionaryRepresentation((CFDictionaryRef) ref, &dc->window_rect);
dc->on_screen = dict[(NSString *) kCGWindowIsOnscreen] != nil;
dc->window_rect =
[dc->screen convertRectToBacking:dc->window_rect];
dc->window_rect = [dc->screen convertRectToBacking:dc->window_rect];
} else {
if (find_window(&dc->window, NULL, false))
@ -149,10 +146,8 @@ static inline void update_window_params(struct display_capture *dc)
[arr release];
}
static inline void display_stream_update(struct display_capture *dc,
CGDisplayStreamFrameStatus status,
uint64_t display_time,
IOSurfaceRef frame_surface,
static inline void display_stream_update(struct display_capture *dc, CGDisplayStreamFrameStatus status,
uint64_t display_time, IOSurfaceRef frame_surface,
CGDisplayStreamUpdateRef update_ref)
{
UNUSED_PARAMETER(display_time);
@ -182,20 +177,15 @@ static inline void display_stream_update(struct display_capture *dc,
size_t dropped_frames = CGDisplayStreamUpdateGetDropCount(update_ref);
if (dropped_frames > 0)
blog(LOG_INFO, "%s: Dropped %zu frames",
obs_source_get_name(dc->source), dropped_frames);
blog(LOG_INFO, "%s: Dropped %zu frames", obs_source_get_name(dc->source), dropped_frames);
}
static bool init_display_stream(struct display_capture *dc)
{
[[NSScreen screens]
enumerateObjectsUsingBlock:^(NSScreen *_Nonnull screen,
NSUInteger index __unused,
[[NSScreen screens] enumerateObjectsUsingBlock:^(NSScreen *_Nonnull screen, NSUInteger index __unused,
BOOL *_Nonnull stop __unused) {
NSNumber *screenNumber =
screen.deviceDescription[@"NSScreenNumber"];
CGDirectDisplayID display_id =
(CGDirectDisplayID)screenNumber.intValue;
NSNumber *screenNumber = screen.deviceDescription[@"NSScreenNumber"];
CGDirectDisplayID display_id = (CGDirectDisplayID) screenNumber.intValue;
if (display_id == dc->display) {
dc->screen = [screen retain];
@ -212,19 +202,15 @@ static bool init_display_stream(struct display_capture *dc)
NSNumber *screen_num = dc->screen.deviceDescription[@"NSScreenNumber"];
CGDirectDisplayID disp_id = screen_num.unsignedIntValue;
NSDictionary *rect_dict =
CFBridgingRelease(CGRectCreateDictionaryRepresentation(
CGRectMake(0, 0, dc->screen.frame.size.width,
dc->screen.frame.size.height)));
NSDictionary *rect_dict = CFBridgingRelease(CGRectCreateDictionaryRepresentation(
CGRectMake(0, 0, dc->screen.frame.size.width, dc->screen.frame.size.height)));
CFBooleanRef show_cursor_cf = dc->hide_cursor ? kCFBooleanFalse
: kCFBooleanTrue;
CFBooleanRef show_cursor_cf = dc->hide_cursor ? kCFBooleanFalse : kCFBooleanTrue;
NSDictionary *dict = @{
(__bridge NSString *) kCGDisplayStreamSourceRect: rect_dict,
(__bridge NSString *) kCGDisplayStreamQueueDepth: @5,
(__bridge NSString *)
kCGDisplayStreamShowCursor: (id)show_cursor_cf,
(__bridge NSString *) kCGDisplayStreamShowCursor: (id) show_cursor_cf,
};
os_event_init(&dc->disp_finished, OS_EVENT_TYPE_MANUAL);
@ -234,14 +220,11 @@ static bool init_display_stream(struct display_capture *dc)
const CGSize *size = &dc->frame.size;
dc->disp = CGDisplayStreamCreateWithDispatchQueue(
disp_id, (size_t)size->width, (size_t)size->height, bgra_code,
(__bridge CFDictionaryRef)dict,
disp_id, (size_t) size->width, (size_t) size->height, bgra_code, (__bridge CFDictionaryRef) dict,
dispatch_queue_create(NULL, NULL),
^(CGDisplayStreamFrameStatus status, uint64_t displayTime,
IOSurfaceRef frameSurface,
^(CGDisplayStreamFrameStatus status, uint64_t displayTime, IOSurfaceRef frameSurface,
CGDisplayStreamUpdateRef updateRef) {
display_stream_update(dc, status, displayTime,
frameSurface, updateRef);
display_stream_update(dc, status, displayTime, frameSurface, updateRef);
});
return !CGDisplayStreamStart(dc->disp);
@ -305,30 +288,19 @@ static void *display_capture_create(obs_data_t *settings, obs_source_t *source)
bool legacy_display_id = obs_data_has_user_value(settings, "display");
if (legacy_display_id) {
CGDirectDisplayID display_id =
(CGDirectDisplayID)obs_data_get_int(settings,
"display");
CFUUIDRef display_uuid =
CGDisplayCreateUUIDFromDisplayID(display_id);
CFStringRef uuid_string =
CFUUIDCreateString(kCFAllocatorDefault, display_uuid);
obs_data_set_string(
settings, "display_uuid",
CFStringGetCStringPtr(uuid_string,
kCFStringEncodingUTF8));
CGDirectDisplayID display_id = (CGDirectDisplayID) obs_data_get_int(settings, "display");
CFUUIDRef display_uuid = CGDisplayCreateUUIDFromDisplayID(display_id);
CFStringRef uuid_string = CFUUIDCreateString(kCFAllocatorDefault, display_uuid);
obs_data_set_string(settings, "display_uuid", CFStringGetCStringPtr(uuid_string, kCFStringEncodingUTF8));
obs_data_erase(settings, "display");
CFRelease(uuid_string);
CFRelease(display_uuid);
}
const char *display_uuid =
obs_data_get_string(settings, "display_uuid");
const char *display_uuid = obs_data_get_string(settings, "display_uuid");
if (display_uuid) {
CFStringRef uuid_string = CFStringCreateWithCString(
kCFAllocatorDefault, display_uuid,
kCFStringEncodingUTF8);
CFUUIDRef uuid_ref = CFUUIDCreateFromString(kCFAllocatorDefault,
uuid_string);
CFStringRef uuid_string = CFStringCreateWithCString(kCFAllocatorDefault, display_uuid, kCFStringEncodingUTF8);
CFUUIDRef uuid_ref = CFUUIDCreateFromString(kCFAllocatorDefault, uuid_string);
dc->display = CGDisplayGetDisplayIDFromUUID(uuid_ref);
CFRelease(uuid_string);
CFRelease(uuid_ref);
@ -349,8 +321,8 @@ fail:
return NULL;
}
static void build_sprite(struct gs_vb_data *data, float fcx, float fcy,
float start_u, float end_u, float start_v, float end_v)
static void build_sprite(struct gs_vb_data *data, float fcx, float fcy, float start_u, float end_u, float start_v,
float end_v)
{
struct vec2 *tvarray = data->tvarray[0].array;
@ -363,11 +335,9 @@ static void build_sprite(struct gs_vb_data *data, float fcx, float fcy,
vec2_set(tvarray + 3, end_u, end_v);
}
static inline void build_sprite_rect(struct gs_vb_data *data, float origin_x,
float origin_y, float end_x, float end_y)
static inline void build_sprite_rect(struct gs_vb_data *data, float origin_x, float origin_y, float end_x, float end_y)
{
build_sprite(data, fabsf(end_x - origin_x), fabsf(end_y - origin_y),
origin_x, end_x, origin_y, end_y);
build_sprite(data, fabsf(end_x - origin_x), fabsf(end_y - origin_y), origin_x, end_x, origin_y, end_y);
}
static void display_capture_video_tick(void *data, float seconds)
@ -426,8 +396,7 @@ static void display_capture_video_tick(void *data, float seconds)
}
obs_enter_graphics();
build_sprite_rect(gs_vertexbuffer_get_data(dc->vertbuf),
(float)origin.x, (float)origin.y, (float)end.x,
build_sprite_rect(gs_vertexbuffer_get_data(dc->vertbuf), (float) origin.x, (float) origin.y, (float) end.x,
(float) end.y);
if (dc->tex)
@ -534,16 +503,11 @@ static uint32_t display_capture_getheight(void *data)
static void display_capture_defaults(obs_data_t *settings)
{
NSNumber *screen =
[[NSScreen mainScreen] deviceDescription][@"NSScreenNumber"];
NSNumber *screen = [[NSScreen mainScreen] deviceDescription][@"NSScreenNumber"];
CFUUIDRef display_uuid = CGDisplayCreateUUIDFromDisplayID(
(CGDirectDisplayID)screen.intValue);
CFStringRef uuid_string =
CFUUIDCreateString(kCFAllocatorDefault, display_uuid);
obs_data_set_default_string(
settings, "display_uuid",
CFStringGetCStringPtr(uuid_string, kCFStringEncodingUTF8));
CFUUIDRef display_uuid = CGDisplayCreateUUIDFromDisplayID((CGDirectDisplayID) screen.intValue);
CFStringRef uuid_string = CFUUIDCreateString(kCFAllocatorDefault, display_uuid);
obs_data_set_default_string(settings, "display_uuid", CFStringGetCStringPtr(uuid_string, kCFStringEncodingUTF8));
CFRelease(uuid_string);
CFRelease(display_uuid);
obs_data_set_default_bool(settings, "show_cursor", true);
@ -564,9 +528,7 @@ void load_crop(struct display_capture *dc, obs_data_t *settings)
load_crop_mode(&dc->crop, settings);
#define CROP_VAR_NAME(var, mode) (mode "." #var)
#define LOAD_CROP_VAR(var, mode) \
dc->crop_rect.var = \
obs_data_get_double(settings, CROP_VAR_NAME(var, mode));
#define LOAD_CROP_VAR(var, mode) dc->crop_rect.var = obs_data_get_double(settings, CROP_VAR_NAME(var, mode));
switch (dc->crop) {
case CROP_MANUAL:
LOAD_CROP_VAR(origin.x, "manual");
@ -600,11 +562,8 @@ static void display_capture_update(void *data, obs_data_t *settings)
update_window(&dc->window, settings);
CFStringRef uuid_string = CFStringCreateWithCString(
kCFAllocatorDefault,
obs_data_get_string(settings, "display_uuid"),
kCFStringEncodingUTF8);
CFUUIDRef display_uuid =
CFUUIDCreateFromString(kCFAllocatorDefault, uuid_string);
kCFAllocatorDefault, obs_data_get_string(settings, "display_uuid"), kCFStringEncodingUTF8);
CFUUIDRef display_uuid = CFUUIDCreateFromString(kCFAllocatorDefault, uuid_string);
CGDirectDisplayID display = CGDisplayGetDisplayIDFromUUID(display_uuid);
CFRelease(uuid_string);
CFRelease(display_uuid);
@ -623,8 +582,7 @@ static void display_capture_update(void *data, obs_data_t *settings)
obs_leave_graphics();
}
static bool switch_crop_mode(obs_properties_t *props, obs_property_t *p,
obs_data_t *settings)
static bool switch_crop_mode(obs_properties_t *props, obs_property_t *p, obs_data_t *settings)
{
UNUSED_PARAMETER(p);
@ -654,8 +612,7 @@ static bool switch_crop_mode(obs_properties_t *props, obs_property_t *p,
return true;
}
static const char *crop_names[] = {"CropMode.None", "CropMode.Manual",
"CropMode.ToWindow",
static const char *crop_names[] = {"CropMode.None", "CropMode.Manual", "CropMode.ToWindow",
"CropMode.ToWindowAndManual"};
#ifndef COUNTOF
@ -667,55 +624,36 @@ static obs_properties_t *display_capture_properties(void *unused)
obs_properties_t *props = obs_properties_create();
obs_property_t *list = obs_properties_add_list(
props, "display_uuid",
obs_module_text("DisplayCapture.Display"), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_STRING);
obs_property_t *list = obs_properties_add_list(props, "display_uuid", obs_module_text("DisplayCapture.Display"),
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
[[NSScreen screens] enumerateObjectsUsingBlock:^(
NSScreen *_Nonnull screen,
NSUInteger index __unused,
[[NSScreen screens] enumerateObjectsUsingBlock:^(NSScreen *_Nonnull screen, NSUInteger index __unused,
BOOL *_Nonnull stop __unused) {
char dimension_buffer[4][12];
char name_buffer[256];
snprintf(dimension_buffer[0], sizeof(dimension_buffer[0]), "%u",
(uint32_t)[screen frame].size.width);
snprintf(dimension_buffer[1], sizeof(dimension_buffer[0]), "%u",
(uint32_t)[screen frame].size.height);
snprintf(dimension_buffer[2], sizeof(dimension_buffer[0]), "%d",
(int32_t)[screen frame].origin.x);
snprintf(dimension_buffer[3], sizeof(dimension_buffer[0]), "%d",
(int32_t)[screen frame].origin.y);
snprintf(dimension_buffer[0], sizeof(dimension_buffer[0]), "%u", (uint32_t)[screen frame].size.width);
snprintf(dimension_buffer[1], sizeof(dimension_buffer[0]), "%u", (uint32_t)[screen frame].size.height);
snprintf(dimension_buffer[2], sizeof(dimension_buffer[0]), "%d", (int32_t)[screen frame].origin.x);
snprintf(dimension_buffer[3], sizeof(dimension_buffer[0]), "%d", (int32_t)[screen frame].origin.y);
snprintf(name_buffer, sizeof(name_buffer),
"%.200s: %.12sx%.12s @ %.12s,%.12s",
[[screen localizedName] UTF8String],
dimension_buffer[0], dimension_buffer[1],
dimension_buffer[2], dimension_buffer[3]);
snprintf(name_buffer, sizeof(name_buffer), "%.200s: %.12sx%.12s @ %.12s,%.12s",
[[screen localizedName] UTF8String], dimension_buffer[0], dimension_buffer[1], dimension_buffer[2],
dimension_buffer[3]);
NSNumber *screenNumber =
screen.deviceDescription[@"NSScreenNumber"];
NSNumber *screenNumber = screen.deviceDescription[@"NSScreenNumber"];
CGDirectDisplayID display_id =
(CGDirectDisplayID)screenNumber.intValue;
CFUUIDRef display_uuid =
CGDisplayCreateUUIDFromDisplayID(display_id);
CFStringRef uuid_string =
CFUUIDCreateString(kCFAllocatorDefault, display_uuid);
obs_property_list_add_string(
list, name_buffer,
CFStringGetCStringPtr(uuid_string,
kCFStringEncodingUTF8));
CGDirectDisplayID display_id = (CGDirectDisplayID) screenNumber.intValue;
CFUUIDRef display_uuid = CGDisplayCreateUUIDFromDisplayID(display_id);
CFStringRef uuid_string = CFUUIDCreateString(kCFAllocatorDefault, display_uuid);
obs_property_list_add_string(list, name_buffer, CFStringGetCStringPtr(uuid_string, kCFStringEncodingUTF8));
CFRelease(uuid_string);
CFRelease(display_uuid);
}];
obs_properties_add_bool(props, "show_cursor",
obs_module_text("DisplayCapture.ShowCursor"));
obs_properties_add_bool(props, "show_cursor", obs_module_text("DisplayCapture.ShowCursor"));
obs_property_t *crop = obs_properties_add_list(
props, "crop_mode", obs_module_text("CropMode"),
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_t *crop = obs_properties_add_list(props, "crop_mode", obs_module_text("CropMode"), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_modified_callback(crop, switch_crop_mode);
for (unsigned i = 0; i < COUNTOF(crop_names); i++) {
@ -731,8 +669,7 @@ static obs_properties_t *display_capture_properties(void *unused)
float min;
#define LOAD_CROP_VAR(var, mode) \
name = CROP_VAR_NAME(var, mode); \
p = obs_properties_add_float( \
props, name, obs_module_text("Crop." #var), min, 4096.f, .5f); \
p = obs_properties_add_float(props, name, obs_module_text("Crop." #var), min, 4096.f, .5f); \
obs_property_set_visible(p, false);
min = 0.f;
@ -759,8 +696,7 @@ struct obs_source_info display_capture_info = {
.create = display_capture_create,
.destroy = display_capture_destroy,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW |
OBS_SOURCE_DO_NOT_DUPLICATE | OBS_SOURCE_SRGB,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW | OBS_SOURCE_DO_NOT_DUPLICATE | OBS_SOURCE_SRGB,
.video_tick = display_capture_video_tick,
.video_render = display_capture_video_render,

File diff suppressed because it is too large Load diff

View file

@ -28,16 +28,14 @@ struct window_capture {
static CGImageRef get_image(struct window_capture *wc)
{
NSArray *arr = (NSArray *)CGWindowListCreate(
kCGWindowListOptionIncludingWindow, wc->window.window_id);
NSArray *arr = (NSArray *) CGWindowListCreate(kCGWindowListOptionIncludingWindow, wc->window.window_id);
[arr autorelease];
if (!arr.count && !find_window(&wc->window, NULL, false))
return NULL;
return CGWindowListCreateImage(CGRectNull,
kCGWindowListOptionIncludingWindow,
wc->window.window_id, wc->image_option);
return CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, wc->window.window_id,
wc->image_option);
}
static inline void capture_frame(struct window_capture *wc)
@ -50,8 +48,7 @@ static inline void capture_frame(struct window_capture *wc)
size_t width = CGImageGetWidth(img);
size_t height = CGImageGetHeight(img);
if (!width || !height || CGImageGetBitsPerPixel(img) != 32 ||
CGImageGetBitsPerComponent(img) != 8) {
if (!width || !height || CGImageGetBitsPerPixel(img) != 32 || CGImageGetBitsPerComponent(img) != 8) {
CGImageRelease(img);
return;
}
@ -91,8 +88,7 @@ static void *capture_thread(void *data)
return NULL;
}
static inline void *window_capture_create_internal(obs_data_t *settings,
obs_source_t *source)
static inline void *window_capture_create_internal(obs_data_t *settings, obs_source_t *source)
{
struct window_capture *wc = bzalloc(sizeof(struct window_capture));
@ -104,8 +100,7 @@ static inline void *window_capture_create_internal(obs_data_t *settings,
init_window(&wc->window, settings);
wc->image_option = obs_data_get_bool(settings, "show_shadow")
? kCGWindowImageDefault
wc->image_option = obs_data_get_bool(settings, "show_shadow") ? kCGWindowImageDefault
: kCGWindowImageBoundsIgnoreFraming;
os_event_init(&wc->capture_event, OS_EVENT_TYPE_AUTO);
@ -158,17 +153,14 @@ static obs_properties_t *window_capture_properties(void *unused)
add_window_properties(props);
obs_properties_add_bool(props, "show_shadow",
obs_module_text("WindowCapture.ShowShadow"));
obs_properties_add_bool(props, "show_shadow", obs_module_text("WindowCapture.ShowShadow"));
return props;
}
static inline void window_capture_update_internal(struct window_capture *wc,
obs_data_t *settings)
static inline void window_capture_update_internal(struct window_capture *wc, obs_data_t *settings)
{
wc->image_option = obs_data_get_bool(settings, "show_shadow")
? kCGWindowImageDefault
wc->image_option = obs_data_get_bool(settings, "show_shadow") ? kCGWindowImageDefault
: kCGWindowImageBoundsIgnoreFraming;
update_window(&wc->window, settings);
@ -178,9 +170,7 @@ static inline void window_capture_update_internal(struct window_capture *wc,
"[window-capture: '%s'] update settings:\n"
"\twindow: %s\n"
"\towner: %s",
obs_source_get_name(wc->source),
[wc->window.window_name UTF8String],
[wc->window.owner_name UTF8String]);
obs_source_get_name(wc->source), [wc->window.window_name UTF8String], [wc->window.owner_name UTF8String]);
}
}
@ -197,8 +187,7 @@ static const char *window_capture_getname(void *unused)
return obs_module_text("WindowCapture");
}
static inline void window_capture_tick_internal(struct window_capture *wc,
float seconds)
static inline void window_capture_tick_internal(struct window_capture *wc, float seconds)
{
UNUSED_PARAMETER(seconds);
os_event_signal(wc->capture_event);

View file

@ -25,8 +25,7 @@ static NSComparator win_info_cmp = ^(NSDictionary *o1, NSDictionary *o2) {
NSArray *enumerate_windows(void)
{
NSArray *arr = (NSArray *)CGWindowListCopyWindowInfo(
kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
NSArray *arr = (NSArray *) CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
[arr autorelease];
@ -91,13 +90,9 @@ void init_window(cocoa_window_t cw, obs_data_t *settings)
NSNumber *owner_pid = @(obs_data_get_int(settings, "owner_pid"));
NSNumber *window_id = @(obs_data_get_int(settings, "window"));
for (NSDictionary *dict in enumerate_windows()) {
bool owner_names_match =
[cw->owner_name isEqualToString:dict[OWNER_NAME]];
bool ids_match =
[owner_pid isEqualToNumber:dict[OWNER_PID]] &&
[window_id isEqualToNumber:dict[WINDOW_NUMBER]];
bool window_names_match =
[cw->window_name isEqualToString:dict[WINDOW_NAME]];
bool owner_names_match = [cw->owner_name isEqualToString:dict[OWNER_NAME]];
bool ids_match = [owner_pid isEqualToNumber:dict[OWNER_PID]] && [window_id isEqualToNumber:dict[WINDOW_NUMBER]];
bool window_names_match = [cw->window_name isEqualToString:dict[WINDOW_NAME]];
if (owner_names_match && (ids_match || window_names_match)) {
pthread_mutex_unlock(&cw->name_lock);
@ -158,8 +153,7 @@ static inline NSDictionary *find_window_dict(NSArray *arr, int window_id)
return nil;
}
static inline bool window_changed_internal(obs_property_t *p,
obs_data_t *settings)
static inline bool window_changed_internal(obs_property_t *p, obs_data_t *settings)
{
int window_id = (int) obs_data_get_int(settings, "window");
NSString *window_owner = @(obs_data_get_string(settings, "owner_name"));
@ -184,26 +178,20 @@ static inline bool window_changed_internal(obs_property_t *p,
NSString *name = (NSString *) dict[WINDOW_NAME];
NSNumber *wid = (NSNumber *) dict[WINDOW_NUMBER];
if (!window_added &&
win_info_cmp(win_info, dict) == NSOrderedAscending) {
if (!window_added && win_info_cmp(win_info, dict) == NSOrderedAscending) {
window_added = true;
size_t idx = obs_property_list_add_int(
p, make_name(window_owner, window_name),
window_id);
size_t idx = obs_property_list_add_int(p, make_name(window_owner, window_name), window_id);
obs_property_list_item_disable(p, idx, true);
}
if (!show_empty_names && !name.length &&
window_id != wid.intValue)
if (!show_empty_names && !name.length && window_id != wid.intValue)
continue;
obs_property_list_add_int(p, make_name(owner, name),
wid.intValue);
obs_property_list_add_int(p, make_name(owner, name), wid.intValue);
}
if (!window_added) {
size_t idx = obs_property_list_add_int(
p, make_name(window_owner, window_name), window_id);
size_t idx = obs_property_list_add_int(p, make_name(window_owner, window_name), window_id);
obs_property_list_item_disable(p, idx, true);
}
@ -219,8 +207,7 @@ static inline bool window_changed_internal(obs_property_t *p,
return true;
}
static bool window_changed(obs_properties_t *props, obs_property_t *p,
obs_data_t *settings)
static bool window_changed(obs_properties_t *props, obs_property_t *p, obs_data_t *settings)
{
UNUSED_PARAMETER(props);
@ -229,13 +216,11 @@ static bool window_changed(obs_properties_t *props, obs_property_t *p,
}
}
static bool toggle_empty_names(obs_properties_t *props, obs_property_t *p,
obs_data_t *settings)
static bool toggle_empty_names(obs_properties_t *props, obs_property_t *p, obs_data_t *settings)
{
UNUSED_PARAMETER(p);
return window_changed(props, obs_properties_get(props, "window"),
settings);
return window_changed(props, obs_properties_get(props, "window"), settings);
}
void window_defaults(obs_data_t *settings)
@ -246,20 +231,17 @@ void window_defaults(obs_data_t *settings)
void add_window_properties(obs_properties_t *props)
{
obs_property_t *window_list = obs_properties_add_list(
props, "window", obs_module_text("WindowUtils.Window"),
obs_property_t *window_list = obs_properties_add_list(props, "window", obs_module_text("WindowUtils.Window"),
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_set_modified_callback(window_list, window_changed);
obs_property_t *empty = obs_properties_add_bool(
props, "show_empty_names",
obs_module_text("WindowUtils.ShowEmptyNames"));
obs_property_t *empty =
obs_properties_add_bool(props, "show_empty_names", obs_module_text("WindowUtils.ShowEmptyNames"));
obs_property_set_modified_callback(empty, toggle_empty_names);
}
void show_window_properties(obs_properties_t *props, bool show)
{
obs_property_set_visible(obs_properties_get(props, "window"), show);
obs_property_set_visible(obs_properties_get(props, "show_empty_names"),
show);
obs_property_set_visible(obs_properties_get(props, "show_empty_names"), show);
}

View file

@ -4,9 +4,7 @@
#include <obs-module.h>
#include <AvailabilityMacros.h>
#define LOG(level, message, ...) \
blog(level, "%s: " message, obs_source_get_name(s->source), \
##__VA_ARGS__)
#define LOG(level, message, ...) blog(level, "%s: " message, obs_source_get_name(s->source), ##__VA_ARGS__)
struct syphon {
SYPHON_CLIENT_UNIQUE_CLASS_NAME *client;
@ -147,8 +145,7 @@ static inline void check_description(syphon_t s, NSDictionary *desc)
surfaces_string.UTF8String);
}
static inline void handle_new_frame(syphon_t s,
SYPHON_CLIENT_UNIQUE_CLASS_NAME *client)
static inline void handle_new_frame(syphon_t s, SYPHON_CLIENT_UNIQUE_CLASS_NAME *client)
{
IOSurfaceRef ref = [client IOSurface];
@ -184,16 +181,14 @@ static void create_client(syphon_t s)
return;
SyphonServerDirectory *ssd = [SyphonServerDirectory sharedDirectory];
NSArray *servers = [ssd serversMatchingName:s->name
appName:s->app_name];
NSArray *servers = [ssd serversMatchingName:s->name appName:s->app_name];
if (!servers.count)
return;
NSDictionary *desc = find_by_uuid(servers, s->uuid);
if (!desc) {
desc = servers[0];
if (![s->uuid isEqualToString:
desc[SyphonServerDescriptionUUIDKey]]) {
if (![s->uuid isEqualToString:desc[SyphonServerDescriptionUUIDKey]]) {
s->uuid_changed = true;
}
}
@ -201,11 +196,9 @@ static void create_client(syphon_t s)
check_version(s, desc);
check_description(s, desc);
s->client = [[SYPHON_CLIENT_UNIQUE_CLASS_NAME alloc]
initWithServerDescription:desc
options:nil
newFrameHandler:^(
SYPHON_CLIENT_UNIQUE_CLASS_NAME *client) {
s->client =
[[SYPHON_CLIENT_UNIQUE_CLASS_NAME alloc] initWithServerDescription:desc options:nil
newFrameHandler:^(SYPHON_CLIENT_UNIQUE_CLASS_NAME *client) {
handle_new_frame(s, client);
}];
@ -216,8 +209,7 @@ static inline bool load_syphon_settings(syphon_t s, obs_data_t *settings)
{
NSString *app_name = @(obs_data_get_string(settings, "app_name"));
NSString *name = @(obs_data_get_string(settings, "name"));
bool equal_names = [app_name isEqual:s->app_name] &&
[name isEqual:s->name];
bool equal_names = [app_name isEqual:s->app_name] && [name isEqual:s->name];
if (s->uuid_changed && equal_names)
return false;
@ -244,8 +236,7 @@ static inline void update_from_announce(syphon_t s, NSDictionary *info)
NSString *name = info[SyphonServerDescriptionNameKey];
NSString *uuid = info[SyphonServerDescriptionUUIDKey];
if (![uuid isEqual:s->uuid] &&
!([app_name isEqual:s->app_name] && [name isEqual:s->name]))
if (![uuid isEqual:s->uuid] && !([app_name isEqual:s->app_name] && [name isEqual:s->name]))
return;
s->app_name = app_name;
@ -345,19 +336,13 @@ static inline bool init_obs_graphics_objects(syphon_t s)
static inline bool create_syphon_listeners(syphon_t s)
{
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
s->new_server_listener = [nc
addObserverForName:SyphonServerAnnounceNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
s->new_server_listener = [nc addObserverForName:SyphonServerAnnounceNotification object:nil
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
handle_announce(s, note);
}];
s->retire_listener = [nc
addObserverForName:SyphonServerRetireNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
s->retire_listener = [nc addObserverForName:SyphonServerRetireNotification object:nil
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
handle_retire(s, note);
}];
@ -405,8 +390,7 @@ static void *syphon_create_internal(obs_data_t *settings, obs_source_t *source)
load_crop(s, settings);
s->allow_transparency =
obs_data_get_bool(settings, "allow_transparency");
s->allow_transparency = obs_data_get_bool(settings, "allow_transparency");
return s;
}
@ -459,8 +443,7 @@ static inline NSString *get_string(obs_data_t *settings, const char *name)
return @(obs_data_get_string(settings, name));
}
static inline void update_strings_from_context(syphon_t s, obs_data_t *settings,
NSString **app, NSString **name,
static inline void update_strings_from_context(syphon_t s, obs_data_t *settings, NSString **app, NSString **name,
NSString **uuid)
{
if (!s || !s->uuid_changed)
@ -476,8 +459,7 @@ static inline void update_strings_from_context(syphon_t s, obs_data_t *settings,
obs_data_set_string(settings, "uuid", s->uuid.UTF8String);
}
static inline void add_servers(syphon_t s, obs_property_t *list,
obs_data_t *settings)
static inline void add_servers(syphon_t s, obs_property_t *list, obs_data_t *settings)
{
bool found_current = settings == NULL;
@ -485,8 +467,7 @@ static inline void add_servers(syphon_t s, obs_property_t *list,
NSString *set_name = get_string(settings, "name");
NSString *set_uuid = get_string(settings, "uuid");
update_strings_from_context(s, settings, &set_app, &set_name,
&set_uuid);
update_strings_from_context(s, settings, &set_app, &set_name, &set_uuid);
obs_property_list_add_string(list, "", "");
NSArray *arr = [[SyphonServerDirectory sharedDirectory] servers];
@ -494,11 +475,9 @@ static inline void add_servers(syphon_t s, obs_property_t *list,
NSString *app = server[SyphonServerDescriptionAppNameKey];
NSString *name = server[SyphonServerDescriptionNameKey];
NSString *uuid = server[SyphonServerDescriptionUUIDKey];
NSString *serv =
[NSString stringWithFormat:@"[%@] %@", app, name];
NSString *serv = [NSString stringWithFormat:@"[%@] %@", app, name];
obs_property_list_add_string(list, serv.UTF8String,
uuid.UTF8String);
obs_property_list_add_string(list, serv.UTF8String, uuid.UTF8String);
if (!found_current)
found_current = [uuid isEqual:set_uuid];
@ -507,15 +486,12 @@ static inline void add_servers(syphon_t s, obs_property_t *list,
if (found_current || !set_uuid.length || !set_app.length)
return;
NSString *serv =
[NSString stringWithFormat:@"[%@] %@", set_app, set_name];
size_t idx = obs_property_list_add_string(list, serv.UTF8String,
set_uuid.UTF8String);
NSString *serv = [NSString stringWithFormat:@"[%@] %@", set_app, set_name];
size_t idx = obs_property_list_add_string(list, serv.UTF8String, set_uuid.UTF8String);
obs_property_list_item_disable(list, idx, true);
}
static bool servers_changed(obs_properties_t *props, obs_property_t *list,
obs_data_t *settings)
static bool servers_changed(obs_properties_t *props, obs_property_t *list, obs_data_t *settings)
{
@autoreleasepool {
obs_property_list_clear(list);
@ -524,8 +500,7 @@ static bool servers_changed(obs_properties_t *props, obs_property_t *list,
}
}
static bool update_crop(obs_properties_t *props, obs_property_t *prop,
obs_data_t *settings)
static bool update_crop(obs_properties_t *props, obs_property_t *prop, obs_data_t *settings)
{
bool enabled = obs_data_get_bool(settings, "crop");
@ -549,19 +524,14 @@ static void show_syphon_license_internal(void)
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
NSURL *url = [NSURL
URLWithString:
[@"file://"
stringByAppendingString:
[NSString
stringWithCString:path
NSURL *url =
[NSURL URLWithString:[@"file://" stringByAppendingString:[NSString stringWithCString:path
encoding:NSUTF8StringEncoding]]];
[ws openURL:url];
bfree(path);
}
static bool show_syphon_license(obs_properties_t *props, obs_property_t *prop,
void *data)
static bool show_syphon_license(obs_properties_t *props, obs_property_t *prop, void *data)
{
UNUSED_PARAMETER(props);
UNUSED_PARAMETER(prop);
@ -587,34 +557,25 @@ static inline obs_properties_t *syphon_properties_internal(syphon_t s)
s = NULL;
}
obs_properties_t *props =
obs_properties_create_param(s, syphon_release);
obs_properties_t *props = obs_properties_create_param(s, syphon_release);
obs_property_t *list = obs_properties_add_list(
props, "uuid", obs_module_text("Source"), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_STRING);
obs_property_t *list =
obs_properties_add_list(props, "uuid", obs_module_text("Source"), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
obs_property_set_modified_callback(list, servers_changed);
obs_properties_add_bool(props, "allow_transparency",
obs_module_text("AllowTransparency"));
obs_properties_add_bool(props, "allow_transparency", obs_module_text("AllowTransparency"));
obs_property_t *crop =
obs_properties_add_bool(props, "crop", obs_module_text("Crop"));
obs_property_t *crop = obs_properties_add_bool(props, "crop", obs_module_text("Crop"));
obs_property_set_modified_callback(crop, update_crop);
#define LOAD_CROP(x) \
obs_properties_add_float(props, "crop." #x, \
obs_module_text("Crop." #x), 0., 4096.f, \
.5f);
#define LOAD_CROP(x) obs_properties_add_float(props, "crop." #x, obs_module_text("Crop." #x), 0., 4096.f, .5f);
LOAD_CROP(origin.x);
LOAD_CROP(origin.y);
LOAD_CROP(size.width);
LOAD_CROP(size.height);
#undef LOAD_CROP
obs_properties_add_button(props, "syphon license",
obs_module_text("SyphonLicense"),
show_syphon_license);
obs_properties_add_button(props, "syphon license", obs_module_text("SyphonLicense"), show_syphon_license);
return props;
}
@ -643,9 +604,8 @@ static void syphon_save(void *data, obs_data_t *settings)
}
}
static inline void build_sprite(struct gs_vb_data *data, float fcx, float fcy,
float start_u, float end_u, float start_v,
float end_v)
static inline void build_sprite(struct gs_vb_data *data, float fcx, float fcy, float start_u, float end_u,
float start_v, float end_v)
{
struct vec2 *tvarray = data->tvarray[0].array;
@ -658,11 +618,9 @@ static inline void build_sprite(struct gs_vb_data *data, float fcx, float fcy,
vec2_set(tvarray + 3, end_u, end_v);
}
static inline void build_sprite_rect(struct gs_vb_data *data, float origin_x,
float origin_y, float end_x, float end_y)
static inline void build_sprite_rect(struct gs_vb_data *data, float origin_x, float origin_y, float end_x, float end_y)
{
build_sprite(data, fabsf(end_x - origin_x), fabsf(end_y - origin_y),
origin_x, end_x, origin_y, end_y);
build_sprite(data, fabsf(end_x - origin_x), fabsf(end_y - origin_y), origin_x, end_x, origin_y, end_y);
}
static void syphon_video_tick(void *data, float seconds)
@ -680,10 +638,8 @@ static void syphon_video_tick(void *data, float seconds)
crop = &s->crop_rect;
obs_enter_graphics();
build_sprite_rect(gs_vertexbuffer_get_data(s->vertbuffer),
(float)crop->origin.x,
s->height - (float)crop->origin.y,
s->width - (float)crop->size.width,
build_sprite_rect(gs_vertexbuffer_get_data(s->vertbuffer), (float) crop->origin.x,
s->height - (float) crop->origin.y, s->width - (float) crop->size.width,
(float) crop->size.height);
obs_leave_graphics();
}
@ -703,8 +659,7 @@ static void syphon_video_render(void *data, gs_effect_t *effect)
gs_load_samplerstate(s->sampler, 0);
const char *tech_name = s->allow_transparency ? "Draw" : "DrawOpaque";
gs_technique_t *tech = gs_effect_get_technique(s->effect, tech_name);
gs_effect_set_texture(gs_effect_get_param_by_name(s->effect, "image"),
s->tex);
gs_effect_set_texture(gs_effect_get_param_by_name(s->effect, "image"), s->tex);
gs_technique_begin(tech);
gs_technique_begin_pass(tech, 0);
@ -719,8 +674,7 @@ static uint32_t syphon_get_width(void *data)
syphon_t s = (syphon_t) data;
if (!s->crop)
return s->width;
int32_t width = s->width - (int)s->crop_rect.origin.x -
(int)s->crop_rect.size.width;
int32_t width = s->width - (int) s->crop_rect.origin.x - (int) s->crop_rect.size.width;
return MAX(0, width);
}
@ -729,8 +683,7 @@ static uint32_t syphon_get_height(void *data)
syphon_t s = (syphon_t) data;
if (!s->crop)
return s->height;
int32_t height = s->height - (int)s->crop_rect.origin.y -
(int)s->crop_rect.size.height;
int32_t height = s->height - (int) s->crop_rect.origin.y - (int) s->crop_rect.size.height;
return MAX(0, height);
}
@ -760,8 +713,7 @@ static inline bool update_syphon(syphon_t s, obs_data_t *settings)
static void syphon_update_internal(syphon_t s, obs_data_t *settings)
{
s->allow_transparency =
obs_data_get_bool(settings, "allow_transparency");
s->allow_transparency = obs_data_get_bool(settings, "allow_transparency");
load_crop(s, settings);
@ -779,8 +731,7 @@ static void syphon_update(void *data, obs_data_t *settings)
struct obs_source_info syphon_info = {
.id = "syphon-input",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW |
OBS_SOURCE_DO_NOT_DUPLICATE,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW | OBS_SOURCE_DO_NOT_DUPLICATE,
.get_name = syphon_get_name,
.create = syphon_create,
.destroy = syphon_destroy,

View file

@ -7,8 +7,7 @@
#import "CMSampleBufferUtils.h"
CMSampleTimingInfo CMSampleTimingInfoForTimestamp(uint64_t timestampNanos,
uint32_t fpsNumerator,
CMSampleTimingInfo CMSampleTimingInfoForTimestamp(uint64_t timestampNanos, uint32_t fpsNumerator,
uint32_t fpsDenominator)
{
// The timing here is quite important. For frames to be delivered correctly and successfully be recorded by apps
@ -19,10 +18,8 @@ CMSampleTimingInfo CMSampleTimingInfoForTimestamp(uint64_t timestampNanos,
// 600 is a common default in Apple's docs https://developer.apple.com/documentation/avfoundation/avmutablemovie/1390622-timescale
CMTimeScale scale = 600;
CMSampleTimingInfo timing;
timing.duration =
CMTimeMake(fpsDenominator * scale, fpsNumerator * scale);
timing.presentationTimeStamp = CMTimeMakeWithSeconds(
timestampNanos / (double)NSEC_PER_SEC, scale);
timing.duration = CMTimeMake(fpsDenominator * scale, fpsNumerator * scale);
timing.presentationTimeStamp = CMTimeMakeWithSeconds(timestampNanos / (double) NSEC_PER_SEC, scale);
timing.decodeTimeStamp = kCMTimeInvalid;
return timing;
}

View file

@ -24,8 +24,7 @@
#ifdef DEBUG
#define DLog(fmt, ...) NSLog((PLUGIN_NAME @"(DAL): " fmt), ##__VA_ARGS__)
#define DLogFunc(fmt, ...) \
NSLog((PLUGIN_NAME @"(DAL): %s " fmt), __FUNCTION__, ##__VA_ARGS__)
#define DLogFunc(fmt, ...) NSLog((PLUGIN_NAME @"(DAL): %s " fmt), __FUNCTION__, ##__VA_ARGS__)
#else
#define DLog(...) (void) sizeof(__VA_ARGS__)
#define DLogFunc(...) (void) sizeof(__VA_ARGS__)

View file

@ -36,7 +36,6 @@
qualifierDataSize:(UInt32)qualifierDataSize
qualifierData:(nonnull const void *)qualifierData
{
switch (address.mSelector) {
case kCMIOObjectPropertyName:
return sizeof(CFStringRef);
@ -99,7 +98,6 @@
dataUsed:(nonnull UInt32 *)dataUsed
data:(nonnull void *)data
{
switch (address.mSelector) {
case kCMIOObjectPropertyName:
*static_cast<CFStringRef *>(data) = CFSTR("OBS Virtual Camera");
@ -122,18 +120,15 @@
*dataUsed = sizeof(CMIOObjectID);
break;
case kCMIODevicePropertyDeviceUID:
*static_cast<CFStringRef *>(data) =
CFSTR("obs-virtual-cam-device");
*static_cast<CFStringRef *>(data) = CFSTR("obs-virtual-cam-device");
*dataUsed = sizeof(CFStringRef);
break;
case kCMIODevicePropertyModelUID:
*static_cast<CFStringRef *>(data) =
CFSTR("obs-virtual-cam-model");
*static_cast<CFStringRef *>(data) = CFSTR("obs-virtual-cam-model");
*dataUsed = sizeof(CFStringRef);
break;
case kCMIODevicePropertyTransportType:
*static_cast<UInt32 *>(data) =
kIOAudioDeviceTransportTypeBuiltIn;
*static_cast<UInt32 *>(data) = kIOAudioDeviceTransportTypeBuiltIn;
*dataUsed = sizeof(UInt32);
break;
case kCMIODevicePropertyDeviceIsAlive:
@ -262,11 +257,9 @@
dataSize:(UInt32)dataSize
data:(nonnull const void *)data
{
switch (address.mSelector) {
case kCMIODevicePropertyExcludeNonDALAccess:
self.excludeNonDALAccess =
(*static_cast<const UInt32 *>(data) != 0);
self.excludeNonDALAccess = (*static_cast<const UInt32 *>(data) != 0);
break;
case kCMIODevicePropertyDeviceMaster:
self.masterPid = *static_cast<const pid_t *>(data);

View file

@ -27,8 +27,7 @@
// See note in MachServer.mm and don't judge me
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [[NSMachBootstrapServer sharedInstance]
portForName:@MACH_SERVICE_NAME];
return [[NSMachBootstrapServer sharedInstance] portForName:@MACH_SERVICE_NAME];
#pragma clang diagnostic pop
}
@ -44,24 +43,16 @@
_receivePort = receivePort;
_receivePort.delegate = self;
__weak __typeof(self) weakSelf = self;
dispatch_async(
dispatch_get_global_queue(
DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addPort:receivePort
forMode:NSDefaultRunLoopMode];
[runLoop addPort:receivePort forMode:NSDefaultRunLoopMode];
// weakSelf should become nil when this object gets destroyed
while (weakSelf) {
[[NSRunLoop currentRunLoop]
runUntilDate:
[NSDate dateWithTimeIntervalSinceNow:
0.1]];
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
DLog(@"Shutting down receive run loop");
});
DLog(@"Initialized mach port %d for receiving",
((NSMachPort *)_receivePort).machPort);
DLog(@"Initialized mach port %d for receiving", ((NSMachPort *) _receivePort).machPort);
}
return _receivePort;
}
@ -76,9 +67,7 @@
return NO;
}
NSPortMessage *message = [[NSPortMessage alloc]
initWithSendPort:sendPort
receivePort:self.receivePort
NSPortMessage *message = [[NSPortMessage alloc] initWithSendPort:sendPort receivePort:self.receivePort
components:nil];
message.msgid = MachMsgIdConnect;
@ -113,8 +102,7 @@
if (!framePort)
return;
IOSurfaceRef surface = IOSurfaceLookupFromMachPort(
[framePort machPort]);
IOSurfaceRef surface = IOSurfaceLookupFromMachPort([framePort machPort]);
if (surface) {
/*
@ -123,38 +111,27 @@
* from GPU memory to CPU memory so we can process the pixel buffer.
*/
#ifndef __aarch64__
IOSurfaceLock(surface, kIOSurfaceLockReadOnly,
NULL);
IOSurfaceLock(surface, kIOSurfaceLockReadOnly, NULL);
#endif
CVPixelBufferRef frame;
CVPixelBufferCreateWithIOSurface(
kCFAllocatorDefault, surface, NULL,
&frame);
CVPixelBufferCreateWithIOSurface(kCFAllocatorDefault, surface, NULL, &frame);
#ifndef __aarch64__
IOSurfaceUnlock(surface, kIOSurfaceLockReadOnly,
NULL);
IOSurfaceUnlock(surface, kIOSurfaceLockReadOnly, NULL);
#endif
CFRelease(surface);
uint64_t timestamp;
[components[1] getBytes:&timestamp
length:sizeof(timestamp)];
[components[1] getBytes:&timestamp length:sizeof(timestamp)];
VLog(@"Received frame data: %zux%zu (%llu)",
CVPixelBufferGetWidth(frame),
VLog(@"Received frame data: %zux%zu (%llu)", CVPixelBufferGetWidth(frame),
CVPixelBufferGetHeight(frame), timestamp);
uint32_t fpsNumerator;
[components[2] getBytes:&fpsNumerator
length:sizeof(fpsNumerator)];
[components[2] getBytes:&fpsNumerator length:sizeof(fpsNumerator)];
uint32_t fpsDenominator;
[components[3] getBytes:&fpsDenominator
length:sizeof(fpsDenominator)];
[components[3] getBytes:&fpsDenominator length:sizeof(fpsDenominator)];
[strongDelegate
receivedPixelBuffer:frame
timestamp:timestamp
fpsNumerator:fpsNumerator
[strongDelegate receivedPixelBuffer:frame timestamp:timestamp fpsNumerator:fpsNumerator
fpsDenominator:fpsDenominator];
CVPixelBufferRelease(frame);
@ -162,8 +139,7 @@
ELog(@"Failed to obtain IOSurface from Mach port");
}
[framePort invalidate];
mach_port_deallocate(mach_task_self(),
[framePort machPort]);
mach_port_deallocate(mach_task_self(), [framePort machPort]);
}
break;
case MachMsgIdStop:
@ -171,8 +147,7 @@
[strongDelegate receivedStop];
break;
default:
ELog(@"Received unexpected response msgid %u",
(unsigned)message.msgid);
ELog(@"Received unexpected response msgid %u", (unsigned) message.msgid);
break;
}
}

View file

@ -220,9 +220,7 @@
return @"kCMIOHardwarePropertyAllowWirelessScreenCaptureDevices";
default:
uint8_t *chars = (uint8_t *) &selector;
return [NSString stringWithFormat:@"Unknown selector: %c%c%c%c",
chars[0], chars[1], chars[2],
chars[3]];
return [NSString stringWithFormat:@"Unknown selector: %c%c%c%c", chars[0], chars[1], chars[2], chars[3]];
}
}

View file

@ -57,12 +57,9 @@ typedef enum {
- (instancetype)init
{
if (self = [super init]) {
_stateQueue = dispatch_queue_create(
"com.obsproject.obs-mac-virtualcam.dal.state",
DISPATCH_QUEUE_SERIAL);
_stateQueue = dispatch_queue_create("com.obsproject.obs-mac-virtualcam.dal.state", DISPATCH_QUEUE_SERIAL);
_timeoutTimer = dispatch_source_create(
DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _stateQueue);
_timeoutTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _stateQueue);
__weak __typeof(self) weakSelf = self;
dispatch_source_set_event_handler(_timeoutTimer, ^{
if (weakSelf.state == PlugInStateReceivingFrames) {
@ -75,19 +72,16 @@ typedef enum {
_machClient = [[OBSDALMachClient alloc] init];
_machClient.delegate = self;
_machConnectTimer = dispatch_source_create(
DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _stateQueue);
_machConnectTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _stateQueue);
dispatch_time_t startTime = dispatch_time(DISPATCH_TIME_NOW, 0);
uint64_t intervalTime = (int64_t) (1 * NSEC_PER_SEC);
dispatch_source_set_timer(_machConnectTimer, startTime,
intervalTime, 0);
dispatch_source_set_timer(_machConnectTimer, startTime, intervalTime, 0);
dispatch_source_set_event_handler(_machConnectTimer, ^{
__strong __typeof(weakSelf) strongSelf = weakSelf;
if (![[strongSelf machClient] isServerAvailable]) {
DLog(@"Server is not available");
} else if (strongSelf.state ==
PlugInStateWaitingForServer) {
} else if (strongSelf.state == PlugInStateWaitingForServer) {
DLog(@"Attempting connection");
[[strongSelf machClient] connectToServer];
}
@ -122,12 +116,10 @@ typedef enum {
}
- (void)initialize
{
}
{}
- (void)teardown
{
}
{}
#pragma mark - CMIOObject
@ -138,8 +130,7 @@ typedef enum {
return true;
default:
DLog(@"PlugIn unhandled hasPropertyWithAddress for %@",
[OBSDALObjectStore
StringFromPropertySelector:address.mSelector]);
[OBSDALObjectStore StringFromPropertySelector:address.mSelector]);
return false;
};
}
@ -151,8 +142,7 @@ typedef enum {
return false;
default:
DLog(@"PlugIn unhandled isPropertySettableWithAddress for %@",
[OBSDALObjectStore
StringFromPropertySelector:address.mSelector]);
[OBSDALObjectStore StringFromPropertySelector:address.mSelector]);
return false;
};
}
@ -166,8 +156,7 @@ typedef enum {
return sizeof(CFStringRef);
default:
DLog(@"PlugIn unhandled getPropertyDataSizeWithAddress for %@",
[OBSDALObjectStore
StringFromPropertySelector:address.mSelector]);
[OBSDALObjectStore StringFromPropertySelector:address.mSelector]);
return 0;
};
}
@ -181,14 +170,12 @@ typedef enum {
{
switch (address.mSelector) {
case kCMIOObjectPropertyName:
*static_cast<CFStringRef *>(data) =
CFSTR("OBS Virtual Camera Plugin");
*static_cast<CFStringRef *>(data) = CFSTR("OBS Virtual Camera Plugin");
*dataUsed = sizeof(CFStringRef);
return;
default:
DLog(@"PlugIn unhandled getPropertyDataWithAddress for %@",
[OBSDALObjectStore
StringFromPropertySelector:address.mSelector]);
[OBSDALObjectStore StringFromPropertySelector:address.mSelector]);
return;
};
}
@ -215,15 +202,10 @@ typedef enum {
dispatch_sync(_stateQueue, ^{
if (_state == PlugInStateWaitingForServer) {
NSUserDefaults *defaults =
[NSUserDefaults standardUserDefaults];
[defaults setInteger:(long)width
forKey:kTestCardWidthKey];
[defaults setInteger:(long)height
forKey:kTestCardHeightKey];
[defaults setDouble:(double)fpsNumerator /
(double)fpsDenominator
forKey:kTestCardFPSKey];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:(long) width forKey:kTestCardWidthKey];
[defaults setInteger:(long) height forKey:kTestCardHeightKey];
[defaults setDouble:(double) fpsNumerator / (double) fpsDenominator forKey:kTestCardFPSKey];
dispatch_suspend(_machConnectTimer);
[self.stream stopServingDefaultFrames];
@ -233,15 +215,10 @@ typedef enum {
});
// Add 5 more seconds onto the timeout timer
dispatch_source_set_timer(
_timeoutTimer,
dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)),
dispatch_source_set_timer(_timeoutTimer, dispatch_time(DISPATCH_TIME_NOW, (int64_t) (5.0 * NSEC_PER_SEC)),
(uint64_t) (5.0 * NSEC_PER_SEC), (1ull * NSEC_PER_SEC) / 10);
[self.stream queuePixelBuffer:frame
timestamp:timestamp
fpsNumerator:fpsNumerator
fpsDenominator:fpsDenominator];
[self.stream queuePixelBuffer:frame timestamp:timestamp fpsNumerator:fpsNumerator fpsDenominator:fpsDenominator];
}
- (void)receivedStop

View file

@ -44,8 +44,7 @@ ULONG HardwarePlugIn_Release(CMIOHardwarePlugInRef)
return sRefCount;
}
HRESULT HardwarePlugIn_QueryInterface(CMIOHardwarePlugInRef, REFIID uuid,
LPVOID *interface)
HRESULT HardwarePlugIn_QueryInterface(CMIOHardwarePlugInRef, REFIID uuid, LPVOID *interface)
{
if (!interface) {
DLogFunc(@"Received an empty interface");
@ -58,8 +57,7 @@ HRESULT HardwarePlugIn_QueryInterface(CMIOHardwarePlugInRef, REFIID uuid,
// Create a CoreFoundation UUIDRef for the requested interface.
CFUUIDRef cfUuid = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault, uuid);
CFStringRef uuidString = CFUUIDCreateString(NULL, cfUuid);
CFStringRef hardwarePluginUuid =
CFUUIDCreateString(NULL, kCMIOHardwarePlugInInterfaceID);
CFStringRef hardwarePluginUuid = CFUUIDCreateString(NULL, kCMIOHardwarePlugInInterfaceID);
CFRelease(cfUuid);
if (CFEqual(uuidString, hardwarePluginUuid)) {
@ -78,15 +76,13 @@ HRESULT HardwarePlugIn_QueryInterface(CMIOHardwarePlugInRef, REFIID uuid,
}
// I think this is deprecated, seems that HardwarePlugIn_InitializeWithObjectID gets called instead
OSStatus HardwarePlugIn_Initialize(CMIOHardwarePlugInRef self
__attribute__((unused)))
OSStatus HardwarePlugIn_Initialize(CMIOHardwarePlugInRef self __attribute__((unused)))
{
DLogFunc(@"ERR self=%p", self);
return kCMIOHardwareUnspecifiedError;
}
OSStatus HardwarePlugIn_InitializeWithObjectID(CMIOHardwarePlugInRef self,
CMIOObjectID objectID)
OSStatus HardwarePlugIn_InitializeWithObjectID(CMIOHardwarePlugInRef self, CMIOObjectID objectID)
{
DLogFunc(@"self=%p", self);
@ -94,51 +90,42 @@ OSStatus HardwarePlugIn_InitializeWithObjectID(CMIOHardwarePlugInRef self,
OBSDALPlugin *plugIn = [OBSDALPlugin SharedPlugIn];
plugIn.objectId = objectID;
[[OBSDALObjectStore SharedObjectStore] setObject:plugIn
forObjectId:objectID];
[[OBSDALObjectStore SharedObjectStore] setObject:plugIn forObjectId:objectID];
OBSDALDevice *device = [[OBSDALDevice alloc] init];
CMIOObjectID deviceId;
error = CMIOObjectCreate(OBSDALPlugInRef(), kCMIOObjectSystemObject,
kCMIODeviceClassID, &deviceId);
error = CMIOObjectCreate(OBSDALPlugInRef(), kCMIOObjectSystemObject, kCMIODeviceClassID, &deviceId);
if (error != noErr) {
DLog(@"CMIOObjectCreate Error %d", error);
return error;
}
device.objectId = deviceId;
device.pluginId = objectID;
[[OBSDALObjectStore SharedObjectStore] setObject:device
forObjectId:deviceId];
[[OBSDALObjectStore SharedObjectStore] setObject:device forObjectId:deviceId];
OBSDALStream *stream = [[OBSDALStream alloc] init];
CMIOObjectID streamId;
error = CMIOObjectCreate(OBSDALPlugInRef(), deviceId,
kCMIOStreamClassID, &streamId);
error = CMIOObjectCreate(OBSDALPlugInRef(), deviceId, kCMIOStreamClassID, &streamId);
if (error != noErr) {
DLog(@"CMIOObjectCreate Error %d", error);
return error;
}
stream.objectId = streamId;
[[OBSDALObjectStore SharedObjectStore] setObject:stream
forObjectId:streamId];
[[OBSDALObjectStore SharedObjectStore] setObject:stream forObjectId:streamId];
device.streamId = streamId;
plugIn.stream = stream;
// Tell the system about the Device
error = CMIOObjectsPublishedAndDied(
OBSDALPlugInRef(), kCMIOObjectSystemObject, 1, &deviceId, 0, 0);
error = CMIOObjectsPublishedAndDied(OBSDALPlugInRef(), kCMIOObjectSystemObject, 1, &deviceId, 0, 0);
if (error != kCMIOHardwareNoError) {
DLog(@"CMIOObjectsPublishedAndDied plugin/device Error %d",
error);
DLog(@"CMIOObjectsPublishedAndDied plugin/device Error %d", error);
return error;
}
// Tell the system about the Stream
error = CMIOObjectsPublishedAndDied(OBSDALPlugInRef(), deviceId, 1,
&streamId, 0, 0);
error = CMIOObjectsPublishedAndDied(OBSDALPlugInRef(), deviceId, 1, &streamId, 0, 0);
if (error != kCMIOHardwareNoError) {
DLog(@"CMIOObjectsPublishedAndDied device/stream Error %d",
error);
DLog(@"CMIOObjectsPublishedAndDied device/stream Error %d", error);
return error;
}
@ -164,12 +151,10 @@ void HardwarePlugIn_ObjectShow(CMIOHardwarePlugInRef self, CMIOObjectID)
DLogFunc(@"self=%p", self);
}
Boolean
HardwarePlugIn_ObjectHasProperty(CMIOHardwarePlugInRef, CMIOObjectID objectID,
Boolean HardwarePlugIn_ObjectHasProperty(CMIOHardwarePlugInRef, CMIOObjectID objectID,
const CMIOObjectPropertyAddress *address)
{
NSObject<CMIOObject> *object =
[OBSDALObjectStore GetObjectWithId:objectID];
NSObject<CMIOObject> *object = [OBSDALObjectStore GetObjectWithId:objectID];
if (object == nil) {
DLogFunc(@"ERR nil object");
@ -181,13 +166,10 @@ HardwarePlugIn_ObjectHasProperty(CMIOHardwarePlugInRef, CMIOObjectID objectID,
return answer;
}
OSStatus HardwarePlugIn_ObjectIsPropertySettable(
CMIOHardwarePlugInRef self, CMIOObjectID objectID,
OSStatus HardwarePlugIn_ObjectIsPropertySettable(CMIOHardwarePlugInRef self, CMIOObjectID objectID,
const CMIOObjectPropertyAddress *address, Boolean *isSettable)
{
NSObject<CMIOObject> *object =
[OBSDALObjectStore GetObjectWithId:objectID];
NSObject<CMIOObject> *object = [OBSDALObjectStore GetObjectWithId:objectID];
if (object == nil) {
DLogFunc(@"ERR nil object");
@ -196,52 +178,41 @@ OSStatus HardwarePlugIn_ObjectIsPropertySettable(
*isSettable = [object isPropertySettableWithAddress:*address];
DLogFunc(@"%@(%d) %@ self=%p settable=%d",
NSStringFromClass([object class]), objectID,
[OBSDALObjectStore
StringFromPropertySelector:address->mSelector],
self, *isSettable);
DLogFunc(@"%@(%d) %@ self=%p settable=%d", NSStringFromClass([object class]), objectID,
[OBSDALObjectStore StringFromPropertySelector:address->mSelector], self, *isSettable);
return kCMIOHardwareNoError;
}
OSStatus HardwarePlugIn_ObjectGetPropertyDataSize(
CMIOHardwarePlugInRef, CMIOObjectID objectID,
OSStatus HardwarePlugIn_ObjectGetPropertyDataSize(CMIOHardwarePlugInRef, CMIOObjectID objectID,
const CMIOObjectPropertyAddress *address, UInt32 qualifierDataSize,
const void *qualifierData, UInt32 *dataSize)
{
NSObject<CMIOObject> *object =
[OBSDALObjectStore GetObjectWithId:objectID];
NSObject<CMIOObject> *object = [OBSDALObjectStore GetObjectWithId:objectID];
if (object == nil) {
DLogFunc(@"ERR nil object");
return kCMIOHardwareBadObjectError;
}
*dataSize = [object getPropertyDataSizeWithAddress:*address
qualifierDataSize:qualifierDataSize
*dataSize = [object getPropertyDataSizeWithAddress:*address qualifierDataSize:qualifierDataSize
qualifierData:qualifierData];
return kCMIOHardwareNoError;
}
OSStatus HardwarePlugIn_ObjectGetPropertyData(
CMIOHardwarePlugInRef, CMIOObjectID objectID,
OSStatus HardwarePlugIn_ObjectGetPropertyData(CMIOHardwarePlugInRef, CMIOObjectID objectID,
const CMIOObjectPropertyAddress *address, UInt32 qualifierDataSize,
const void *qualifierData, UInt32 dataSize, UInt32 *dataUsed,
void *data)
const void *qualifierData, UInt32 dataSize, UInt32 *dataUsed, void *data)
{
NSObject<CMIOObject> *object =
[OBSDALObjectStore GetObjectWithId:objectID];
NSObject<CMIOObject> *object = [OBSDALObjectStore GetObjectWithId:objectID];
if (object == nil) {
DLogFunc(@"ERR nil object");
return kCMIOHardwareBadObjectError;
}
[object getPropertyDataWithAddress:*address
qualifierDataSize:qualifierDataSize
qualifierData:qualifierData
[object getPropertyDataWithAddress:*address qualifierDataSize:qualifierDataSize qualifierData:qualifierData
dataSize:dataSize
dataUsed:dataUsed
data:data];
@ -249,14 +220,11 @@ OSStatus HardwarePlugIn_ObjectGetPropertyData(
return kCMIOHardwareNoError;
}
OSStatus HardwarePlugIn_ObjectSetPropertyData(
CMIOHardwarePlugInRef self, CMIOObjectID objectID,
OSStatus HardwarePlugIn_ObjectSetPropertyData(CMIOHardwarePlugInRef self, CMIOObjectID objectID,
const CMIOObjectPropertyAddress *address, UInt32 qualifierDataSize,
const void *qualifierData, UInt32 dataSize, const void *data)
{
NSObject<CMIOObject> *object =
[OBSDALObjectStore GetObjectWithId:objectID];
NSObject<CMIOObject> *object = [OBSDALObjectStore GetObjectWithId:objectID];
if (object == nil) {
DLogFunc(@"ERR nil object");
@ -264,15 +232,10 @@ OSStatus HardwarePlugIn_ObjectSetPropertyData(
}
UInt32 *dataInt = (UInt32 *) data;
DLogFunc(@"%@(%d) %@ self=%p data(int)=%d",
NSStringFromClass([object class]), objectID,
[OBSDALObjectStore
StringFromPropertySelector:address->mSelector],
self, *dataInt);
DLogFunc(@"%@(%d) %@ self=%p data(int)=%d", NSStringFromClass([object class]), objectID,
[OBSDALObjectStore StringFromPropertySelector:address->mSelector], self, *dataInt);
[object setPropertyDataWithAddress:*address
qualifierDataSize:qualifierDataSize
qualifierData:qualifierData
[object setPropertyDataWithAddress:*address qualifierDataSize:qualifierDataSize qualifierData:qualifierData
dataSize:dataSize
data:data];
@ -280,38 +243,30 @@ OSStatus HardwarePlugIn_ObjectSetPropertyData(
}
#pragma mark CMIOStream Operations
OSStatus HardwarePlugIn_StreamCopyBufferQueue(
CMIOHardwarePlugInRef self, CMIOStreamID streamID,
OSStatus HardwarePlugIn_StreamCopyBufferQueue(CMIOHardwarePlugInRef self, CMIOStreamID streamID,
CMIODeviceStreamQueueAlteredProc queueAlteredProc,
void *queueAlteredRefCon, CMSimpleQueueRef *queue)
{
OBSDALStream *stream =
(OBSDALStream *)[OBSDALObjectStore GetObjectWithId:streamID];
OBSDALStream *stream = (OBSDALStream *) [OBSDALObjectStore GetObjectWithId:streamID];
if (stream == nil) {
DLogFunc(@"ERR nil object");
return kCMIOHardwareBadObjectError;
}
*queue = [stream copyBufferQueueWithAlteredProc:queueAlteredProc
alteredRefCon:queueAlteredRefCon];
*queue = [stream copyBufferQueueWithAlteredProc:queueAlteredProc alteredRefCon:queueAlteredRefCon];
DLogFunc(@"%@ (id=%d) self=%p queue=%@", stream, streamID, self,
(__bridge NSObject *)*queue);
DLogFunc(@"%@ (id=%d) self=%p queue=%@", stream, streamID, self, (__bridge NSObject *) *queue);
return kCMIOHardwareNoError;
}
#pragma mark CMIODevice Operations
OSStatus HardwarePlugIn_DeviceStartStream(CMIOHardwarePlugInRef self,
CMIODeviceID deviceID,
CMIOStreamID streamID)
OSStatus HardwarePlugIn_DeviceStartStream(CMIOHardwarePlugInRef self, CMIODeviceID deviceID, CMIOStreamID streamID)
{
DLogFunc(@"self=%p device=%d stream=%d", self, deviceID, streamID);
OBSDALStream *stream =
(OBSDALStream *)[OBSDALObjectStore GetObjectWithId:streamID];
OBSDALStream *stream = (OBSDALStream *) [OBSDALObjectStore GetObjectWithId:streamID];
if (stream == nil) {
DLogFunc(@"ERR nil object");
@ -335,14 +290,11 @@ OSStatus HardwarePlugIn_DeviceResume(CMIOHardwarePlugInRef self, CMIODeviceID)
return kCMIOHardwareNoError;
}
OSStatus HardwarePlugIn_DeviceStopStream(CMIOHardwarePlugInRef self,
CMIODeviceID deviceID,
CMIOStreamID streamID)
OSStatus HardwarePlugIn_DeviceStopStream(CMIOHardwarePlugInRef self, CMIODeviceID deviceID, CMIOStreamID streamID)
{
DLogFunc(@"self=%p device=%d stream=%d", self, deviceID, streamID);
OBSDALStream *stream =
(OBSDALStream *)[OBSDALObjectStore GetObjectWithId:streamID];
OBSDALStream *stream = (OBSDALStream *) [OBSDALObjectStore GetObjectWithId:streamID];
if (stream == nil) {
DLogFunc(@"ERR nil object");
@ -354,17 +306,13 @@ OSStatus HardwarePlugIn_DeviceStopStream(CMIOHardwarePlugInRef self,
return kCMIOHardwareNoError;
}
OSStatus HardwarePlugIn_DeviceProcessAVCCommand(CMIOHardwarePlugInRef self,
CMIODeviceID,
CMIODeviceAVCCommand *)
OSStatus HardwarePlugIn_DeviceProcessAVCCommand(CMIOHardwarePlugInRef self, CMIODeviceID, CMIODeviceAVCCommand *)
{
DLogFunc(@"self=%p", self);
return kCMIOHardwareNoError;
}
OSStatus HardwarePlugIn_DeviceProcessRS422Command(CMIOHardwarePlugInRef self,
CMIODeviceID,
CMIODeviceRS422Command *)
OSStatus HardwarePlugIn_DeviceProcessRS422Command(CMIOHardwarePlugInRef self, CMIODeviceID, CMIODeviceRS422Command *)
{
DLogFunc(@"self=%p", self);
return kCMIOHardwareNoError;
@ -382,15 +330,13 @@ OSStatus HardwarePlugIn_StreamDeckStop(CMIOHardwarePlugInRef self, CMIOStreamID)
return kCMIOHardwareIllegalOperationError;
}
OSStatus HardwarePlugIn_StreamDeckJog(CMIOHardwarePlugInRef self, CMIOStreamID,
SInt32)
OSStatus HardwarePlugIn_StreamDeckJog(CMIOHardwarePlugInRef self, CMIOStreamID, SInt32)
{
DLogFunc(@"self=%p", self);
return kCMIOHardwareIllegalOperationError;
}
OSStatus HardwarePlugIn_StreamDeckCueTo(CMIOHardwarePlugInRef self,
CMIOStreamID, Float64, Boolean)
OSStatus HardwarePlugIn_StreamDeckCueTo(CMIOHardwarePlugInRef self, CMIOStreamID, Float64, Boolean)
{
DLogFunc(@"self=%p", self);
return kCMIOHardwareIllegalOperationError;
@ -401,25 +347,17 @@ static CMIOHardwarePlugInInterface sInterface = {
NULL,
// IUnknown Routines
(HRESULT (*)(void *, CFUUIDBytes,
void **))HardwarePlugIn_QueryInterface,
(ULONG(*)(void *))HardwarePlugIn_AddRef,
(HRESULT (*)(void *, CFUUIDBytes, void **)) HardwarePlugIn_QueryInterface, (ULONG(*)(void *)) HardwarePlugIn_AddRef,
(ULONG(*)(void *)) HardwarePlugIn_Release,
// DAL Plug-In Routines
HardwarePlugIn_Initialize, HardwarePlugIn_InitializeWithObjectID,
HardwarePlugIn_Teardown, HardwarePlugIn_ObjectShow,
HardwarePlugIn_ObjectHasProperty,
HardwarePlugIn_ObjectIsPropertySettable,
HardwarePlugIn_ObjectGetPropertyDataSize,
HardwarePlugIn_ObjectGetPropertyData,
HardwarePlugIn_ObjectSetPropertyData, HardwarePlugIn_DeviceSuspend,
HardwarePlugIn_DeviceResume, HardwarePlugIn_DeviceStartStream,
HardwarePlugIn_DeviceStopStream, HardwarePlugIn_DeviceProcessAVCCommand,
HardwarePlugIn_DeviceProcessRS422Command,
HardwarePlugIn_StreamCopyBufferQueue, HardwarePlugIn_StreamDeckPlay,
HardwarePlugIn_StreamDeckStop, HardwarePlugIn_StreamDeckJog,
HardwarePlugIn_StreamDeckCueTo};
HardwarePlugIn_Initialize, HardwarePlugIn_InitializeWithObjectID, HardwarePlugIn_Teardown,
HardwarePlugIn_ObjectShow, HardwarePlugIn_ObjectHasProperty, HardwarePlugIn_ObjectIsPropertySettable,
HardwarePlugIn_ObjectGetPropertyDataSize, HardwarePlugIn_ObjectGetPropertyData,
HardwarePlugIn_ObjectSetPropertyData, HardwarePlugIn_DeviceSuspend, HardwarePlugIn_DeviceResume,
HardwarePlugIn_DeviceStartStream, HardwarePlugIn_DeviceStopStream, HardwarePlugIn_DeviceProcessAVCCommand,
HardwarePlugIn_DeviceProcessRS422Command, HardwarePlugIn_StreamCopyBufferQueue, HardwarePlugIn_StreamDeckPlay,
HardwarePlugIn_StreamDeckStop, HardwarePlugIn_StreamDeckJog, HardwarePlugIn_StreamDeckCueTo};
static CMIOHardwarePlugInInterface *sInterfacePtr = &sInterface;
static CMIOHardwarePlugInRef sPlugInRef = &sInterfacePtr;

View file

@ -28,8 +28,7 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype _Nonnull)init;
- (CMSimpleQueueRef)copyBufferQueueWithAlteredProc:
(CMIODeviceStreamQueueAlteredProc)alteredProc
- (CMSimpleQueueRef)copyBufferQueueWithAlteredProc:(CMIODeviceStreamQueueAlteredProc)alteredProc
alteredRefCon:(void *)alteredRefCon;
- (void)startServingDefaultFrames;

View file

@ -56,10 +56,8 @@
{
self = [super init];
if (self) {
_frameDispatchSource = dispatch_source_create(
DISPATCH_SOURCE_TYPE_TIMER, 0, 0,
dispatch_get_global_queue(
DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
_frameDispatchSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
__weak __typeof(self) wself = self;
dispatch_source_set_event_handler(_frameDispatchSource, ^{
[wself fillFrame];
@ -87,8 +85,7 @@
_fps = 0;
dispatch_time_t startTime = dispatch_time(DISPATCH_TIME_NOW, 0);
uint64_t intervalTime = (int64_t) (NSEC_PER_SEC / self.fps);
dispatch_source_set_timer(_frameDispatchSource, startTime, intervalTime,
0);
dispatch_source_set_timer(_frameDispatchSource, startTime, intervalTime, 0);
dispatch_resume(_frameDispatchSource);
}
@ -102,8 +99,7 @@
{
if (_queue == NULL) {
// Allocate a one-second long queue, which we can use our FPS constant for.
OSStatus err = CMSimpleQueueCreate(kCFAllocatorDefault,
(int32_t)self.fps, &_queue);
OSStatus err = CMSimpleQueueCreate(kCFAllocatorDefault, (int32_t) self.fps, &_queue);
if (err != noErr) {
DLog(@"Err %d in CMSimpleQueueCreate", err);
}
@ -114,11 +110,8 @@
- (CFTypeRef)clock
{
if (_clock == NULL) {
OSStatus err = CMIOStreamClockCreate(
kCFAllocatorDefault,
CFSTR("obs-mac-virtualcam::Stream::clock"),
(__bridge void *)self, CMTimeMake(1, 10), 100, 10,
&_clock);
OSStatus err = CMIOStreamClockCreate(kCFAllocatorDefault, CFSTR("obs-mac-virtualcam::Stream::clock"),
(__bridge void *) self, CMTimeMake(1, 10), 100, 10, &_clock);
if (err != noErr) {
DLog(@"Error %d from CMIOStreamClockCreate", err);
}
@ -129,15 +122,11 @@
- (NSSize)testCardSize
{
if (NSEqualSizes(_testCardSize, NSZeroSize)) {
NSUserDefaults *defaults =
[NSUserDefaults standardUserDefaults];
NSInteger width = [[defaults objectForKey:kTestCardWidthKey]
integerValue];
NSInteger height = [[defaults objectForKey:kTestCardHeightKey]
integerValue];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSInteger width = [[defaults objectForKey:kTestCardWidthKey] integerValue];
NSInteger height = [[defaults objectForKey:kTestCardHeightKey] integerValue];
if (width == 0 || height == 0) {
_testCardSize =
NSMakeSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
_testCardSize = NSMakeSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
} else {
_testCardSize = NSMakeSize(width, height);
}
@ -148,10 +137,8 @@
- (Float64)fps
{
if (_fps == 0) {
NSUserDefaults *defaults =
[NSUserDefaults standardUserDefaults];
double fps =
[[defaults objectForKey:kTestCardFPSKey] doubleValue];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
double fps = [[defaults objectForKey:kTestCardFPSKey] doubleValue];
if (fps == 0) {
_fps = DEFAULT_FPS;
} else {
@ -164,29 +151,22 @@
- (NSImage *)testCardImage
{
if (_testCardImage == nil) {
NSString *bundlePath = [[NSBundle
bundleForClass:[OBSDALStream class]] bundlePath];
NSString *placeHolderPath = [bundlePath
stringByAppendingString:
@"/Contents/Resources/placeholder.png"];
NSString *bundlePath = [[NSBundle bundleForClass:[OBSDALStream class]] bundlePath];
NSString *placeHolderPath = [bundlePath stringByAppendingString:@"/Contents/Resources/placeholder.png"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *homeUrl = [fileManager homeDirectoryForCurrentUser];
NSURL *customUrl = [homeUrl
URLByAppendingPathComponent:
NSURL *customUrl =
[homeUrl URLByAppendingPathComponent:
@"Library/Application Support/obs-studio/plugin_config/mac-virtualcam/placeholder.png"];
NSString *customPlaceHolder = customUrl.path;
if ([fileManager isReadableFileAtPath:customPlaceHolder])
placeHolderPath = customPlaceHolder;
DLog(@"PlaceHolder:%@", placeHolderPath);
NSImage *placeholderImage = [[NSImage alloc]
initWithContentsOfFile:placeHolderPath];
NSImage *placeholderImage = [[NSImage alloc] initWithContentsOfFile:placeHolderPath];
NSBitmapImageRep *rep = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:NULL
pixelsWide:(NSInteger)
self.testCardSize.width
pixelsHigh:(NSInteger)self.testCardSize
.height
NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
pixelsWide:(NSInteger) self.testCardSize.width
pixelsHigh:(NSInteger) self.testCardSize.height
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
@ -196,10 +176,8 @@
bitsPerPixel:0];
rep.size = self.testCardSize;
double hScale =
placeholderImage.size.width / self.testCardSize.width;
double vScale =
placeholderImage.size.height / self.testCardSize.height;
double hScale = placeholderImage.size.width / self.testCardSize.width;
double vScale = placeholderImage.size.height / self.testCardSize.height;
double scaling = fmax(hScale, vScale);
@ -210,25 +188,18 @@
double topOffset = (self.testCardSize.height - newHeight) / 2;
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext
setCurrentContext:
[NSGraphicsContext
graphicsContextWithBitmapImageRep:rep]];
[NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:rep]];
NSColor *backgroundColor = [NSColor blackColor];
[backgroundColor set];
NSRectFill(NSMakeRect(0, 0, self.testCardSize.width,
self.testCardSize.height));
NSRectFill(NSMakeRect(0, 0, self.testCardSize.width, self.testCardSize.height));
[placeholderImage drawInRect:NSMakeRect(leftOffset, topOffset,
newWidth, newHeight)
fromRect:NSZeroRect
[placeholderImage drawInRect:NSMakeRect(leftOffset, topOffset, newWidth, newHeight) fromRect:NSZeroRect
operation:NSCompositingOperationCopy
fraction:1.0];
[NSGraphicsContext restoreGraphicsState];
NSImage *testCardImage =
[[NSImage alloc] initWithSize:self.testCardSize];
NSImage *testCardImage = [[NSImage alloc] initWithSize:self.testCardSize];
[testCardImage addRepresentation:rep];
_testCardImage = testCardImage;
@ -236,8 +207,7 @@
return _testCardImage;
}
- (CMSimpleQueueRef)copyBufferQueueWithAlteredProc:
(CMIODeviceStreamQueueAlteredProc)alteredProc
- (CMSimpleQueueRef)copyBufferQueueWithAlteredProc:(CMIODeviceStreamQueueAlteredProc)alteredProc
alteredRefCon:(void *)alteredRefCon
{
self.alteredProc = alteredProc;
@ -255,16 +225,11 @@
int height = (int) self.testCardSize.height;
NSDictionary *options = [NSDictionary
dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES],
kCVPixelBufferCGImageCompatibilityKey,
[NSNumber numberWithBool:YES],
kCVPixelBufferCGBitmapContextCompatibilityKey, nil];
dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
[NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey, nil];
CVPixelBufferRef pxbuffer = NULL;
CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, width,
height, kCVPixelFormatType_32ARGB,
(__bridge CFDictionaryRef)options,
&pxbuffer);
CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_32ARGB,
(__bridge CFDictionaryRef) options, &pxbuffer);
NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);
@ -273,27 +238,18 @@
NSParameterAssert(pxdata != NULL);
CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(
pxdata, width, height, 8,
CGContextRef context = CGBitmapContextCreate(pxdata, width, height, 8,
CVPixelBufferGetBytesPerRowOfPlane(pxbuffer, 0), rgbColorSpace,
kCGImageAlphaPremultipliedFirst | kCGImageByteOrder32Big);
CFRelease(rgbColorSpace);
NSParameterAssert(context);
NSGraphicsContext *nsContext = [NSGraphicsContext
graphicsContextWithCGContext:context
flipped:NO];
NSGraphicsContext *nsContext = [NSGraphicsContext graphicsContextWithCGContext:context flipped:NO];
[NSGraphicsContext setCurrentContext:nsContext];
NSRect rect = NSMakeRect(0, 0, self.testCardImage.size.width,
self.testCardImage.size.height);
CGImageRef image = [self.testCardImage CGImageForProposedRect:&rect
context:nsContext
hints:nil];
CGContextDrawImage(context,
CGRectMake(0, 0, CGImageGetWidth(image),
CGImageGetHeight(image)),
image);
NSRect rect = NSMakeRect(0, 0, self.testCardImage.size.width, self.testCardImage.size.height);
CGImageRef image = [self.testCardImage CGImageForProposedRect:&rect context:nsContext hints:nil];
CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image);
// DrawDialWithFrame(
// NSMakeRect(0, 0, width, height),
@ -313,30 +269,24 @@
return;
}
CVPixelBufferRef pixelBuffer =
[self createPixelBufferWithTestAnimation];
CVPixelBufferRef pixelBuffer = [self createPixelBufferWithTestAnimation];
uint64_t hostTime = clock_gettime_nsec_np(CLOCK_UPTIME_RAW);
CMSampleTimingInfo timingInfo =
CMSampleTimingInfoForTimestamp(hostTime, (uint32_t)self.fps, 1);
CMSampleTimingInfo timingInfo = CMSampleTimingInfoForTimestamp(hostTime, (uint32_t) self.fps, 1);
OSStatus err = CMIOStreamClockPostTimingEvent(
timingInfo.presentationTimeStamp, hostTime, true, self.clock);
OSStatus err = CMIOStreamClockPostTimingEvent(timingInfo.presentationTimeStamp, hostTime, true, self.clock);
if (err != noErr) {
DLog(@"CMIOStreamClockPostTimingEvent err %d", err);
}
CMFormatDescriptionRef format;
CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault,
pixelBuffer, &format);
CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer, &format);
self.sequenceNumber = CMIOGetNextSequenceNumber(self.sequenceNumber);
CMSampleBufferRef buffer;
err = CMIOSampleBufferCreateForImageBuffer(
kCFAllocatorDefault, pixelBuffer, format, &timingInfo,
self.sequenceNumber, kCMIOSampleBufferNoDiscontinuities,
&buffer);
err = CMIOSampleBufferCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer, format, &timingInfo,
self.sequenceNumber, kCMIOSampleBufferNoDiscontinuities, &buffer);
CFRelease(pixelBuffer);
CFRelease(format);
if (err != noErr) {
@ -362,12 +312,10 @@
}
OSStatus err = noErr;
CMSampleTimingInfo timingInfo = CMSampleTimingInfoForTimestamp(
timestamp, fpsNumerator, fpsDenominator);
CMSampleTimingInfo timingInfo = CMSampleTimingInfoForTimestamp(timestamp, fpsNumerator, fpsDenominator);
err = CMIOStreamClockPostTimingEvent(
timingInfo.presentationTimeStamp,
clock_gettime_nsec_np(CLOCK_UPTIME_RAW), true, self.clock);
err = CMIOStreamClockPostTimingEvent(timingInfo.presentationTimeStamp, clock_gettime_nsec_np(CLOCK_UPTIME_RAW),
true, self.clock);
if (err != noErr) {
DLog(@"CMIOStreamClockPostTimingEvent err %d", err);
}
@ -378,18 +326,14 @@
// Generate the video format description from that pixel buffer
CMVideoFormatDescriptionRef format;
err = CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault,
frame, &format);
err = CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, frame, &format);
if (err != noErr) {
DLog(@"CMVideoFormatDescriptionCreateForImageBuffer err %d",
err);
DLog(@"CMVideoFormatDescriptionCreateForImageBuffer err %d", err);
return;
}
err = CMIOSampleBufferCreateForImageBuffer(
kCFAllocatorDefault, frame, format, &timingInfo,
self.sequenceNumber, kCMIOSampleBufferNoDiscontinuities,
&sampleBuffer);
err = CMIOSampleBufferCreateForImageBuffer(kCFAllocatorDefault, frame, format, &timingInfo, self.sequenceNumber,
kCMIOSampleBufferNoDiscontinuities, &sampleBuffer);
CFRelease(format);
@ -409,19 +353,16 @@
// Inform the clients that the queue has been altered
if (self.alteredProc != NULL) {
(self.alteredProc)(self.objectId, sampleBuffer,
self.alteredRefCon);
(self.alteredProc)(self.objectId, sampleBuffer, self.alteredRefCon);
}
}
- (CMVideoFormatDescriptionRef)getFormatDescription
{
CMVideoFormatDescriptionRef formatDescription;
OSStatus err = CMVideoFormatDescriptionCreate(
kCFAllocatorDefault,
kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange,
(int32_t)self.testCardSize.width,
(int32_t)self.testCardSize.height, NULL, &formatDescription);
OSStatus err = CMVideoFormatDescriptionCreate(kCFAllocatorDefault, kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange,
(int32_t) self.testCardSize.width, (int32_t) self.testCardSize.height,
NULL, &formatDescription);
if (err != noErr) {
DLog(@"Error %d from CMVideoFormatDescriptionCreate", err);
}
@ -488,8 +429,7 @@
*dataUsed = sizeof(CFStringRef);
break;
case kCMIOObjectPropertyElementName:
*static_cast<CFStringRef *>(data) =
CFSTR("OBS Virtual Camera Stream Element");
*static_cast<CFStringRef *>(data) = CFSTR("OBS Virtual Camera Stream Element");
*dataUsed = sizeof(CFStringRef);
break;
case kCMIOObjectPropertyManufacturer:
@ -506,15 +446,12 @@
*dataUsed = sizeof(UInt32);
break;
case kCMIOStreamPropertyFormatDescriptions:
*static_cast<CFArrayRef *>(
data) = (__bridge_retained CFArrayRef)[NSArray
arrayWithObject:(__bridge_transfer NSObject *)
[self getFormatDescription]];
*static_cast<CFArrayRef *>(data) = (__bridge_retained CFArrayRef)
[NSArray arrayWithObject:(__bridge_transfer NSObject *) [self getFormatDescription]];
*dataUsed = sizeof(CFArrayRef);
break;
case kCMIOStreamPropertyFormatDescription:
*static_cast<CMVideoFormatDescriptionRef *>(data) =
[self getFormatDescription];
*static_cast<CMVideoFormatDescriptionRef *>(data) = [self getFormatDescription];
*dataUsed = sizeof(CMVideoFormatDescriptionRef);
break;
case kCMIOStreamPropertyFrameRateRanges:
@ -570,9 +507,7 @@
case kCMIOStreamPropertyLatency:
case kCMIOStreamPropertyInitialPresentationTimeStampForLinkedAndSyncedAudio:
case kCMIOStreamPropertyOutputBuffersNeededForThrottledPlayback:
DLog(@"TODO: %@",
[OBSDALObjectStore
StringFromPropertySelector:address.mSelector]);
DLog(@"TODO: %@", [OBSDALObjectStore StringFromPropertySelector:address.mSelector]);
return false;
default:
return false;
@ -596,7 +531,6 @@
qualifierData:(nonnull const void *)qualifierData
dataSize:(UInt32)dataSize
data:(nonnull const void *)data
{
}
{}
@end

View file

@ -49,8 +49,7 @@
// these APIs (which are, interestingly, not deprecated)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
self.port = [[NSMachBootstrapServer sharedInstance]
servicePortWithName:@MACH_SERVICE_NAME];
self.port = [[NSMachBootstrapServer sharedInstance] servicePortWithName:@MACH_SERVICE_NAME];
#pragma clang diagnostic pop
if (self.port == nil) {
// This probably means another instance is running.
@ -71,21 +70,18 @@
switch (message.msgid) {
case MachMsgIdConnect:
if (message.sendPort != nil) {
blog(LOG_DEBUG,
"mach server received connect message from port %d!",
blog(LOG_DEBUG, "mach server received connect message from port %d!",
((NSMachPort *) message.sendPort).machPort);
[self.clientPorts addObject:message.sendPort];
}
break;
default:
blog(LOG_ERROR, "Unexpected mach message ID %u",
(unsigned)message.msgid);
blog(LOG_ERROR, "Unexpected mach message ID %u", (unsigned) message.msgid);
break;
}
}
- (void)sendMessageToClientsWithMsgId:(uint32_t)msgId
components:(nullable NSArray *)components
- (void)sendMessageToClientsWithMsgId:(uint32_t)msgId components:(nullable NSArray *)components
{
if ([self.clientPorts count] <= 0) {
return;
@ -95,26 +91,18 @@
for (NSPort *port in self.clientPorts) {
@try {
NSPortMessage *message = [[NSPortMessage alloc]
initWithSendPort:port
receivePort:nil
NSPortMessage *message = [[NSPortMessage alloc] initWithSendPort:port receivePort:nil
components:components];
message.msgid = msgId;
if (![port isValid] ||
![message
sendBeforeDate:
[NSDate dateWithTimeIntervalSinceNow:
1.0]]) {
blog(LOG_DEBUG,
"failed to send message to %d, removing it from the clients!",
if (![port isValid] || ![message sendBeforeDate:[NSDate dateWithTimeIntervalSinceNow:1.0]]) {
blog(LOG_DEBUG, "failed to send message to %d, removing it from the clients!",
((NSMachPort *) port).machPort);
[port invalidate];
[removedPorts addObject:port];
}
} @catch (NSException *exception) {
blog(LOG_DEBUG,
"failed to send message (exception) to %d, removing it from the clients!",
blog(LOG_DEBUG, "failed to send message (exception) to %d, removing it from the clients!",
((NSMachPort *) port).machPort);
[port invalidate];
@ -136,15 +124,9 @@
}
@autoreleasepool {
NSData *timestampData = [NSData
dataWithBytes:&timestamp
length:sizeof(timestamp)];
NSData *fpsNumeratorData = [NSData
dataWithBytes:&fpsNumerator
length:sizeof(fpsNumerator)];
NSData *fpsDenominatorData = [NSData
dataWithBytes:&fpsDenominator
length:sizeof(fpsDenominator)];
NSData *timestampData = [NSData dataWithBytes:&timestamp length:sizeof(timestamp)];
NSData *fpsNumeratorData = [NSData dataWithBytes:&fpsNumerator length:sizeof(fpsNumerator)];
NSData *fpsDenominatorData = [NSData dataWithBytes:&fpsDenominator length:sizeof(fpsDenominator)];
IOSurfaceRef surface = CVPixelBufferGetIOSurface(frame);
#ifndef __aarch64__
@ -152,26 +134,19 @@
#endif
if (!surface) {
blog(LOG_ERROR,
"unable to access IOSurface associated with CVPixelBuffer");
blog(LOG_ERROR, "unable to access IOSurface associated with CVPixelBuffer");
return;
}
mach_port_t framePort = IOSurfaceCreateMachPort(surface);
if (!framePort) {
blog(LOG_ERROR,
"unable to allocate mach port for IOSurface");
blog(LOG_ERROR, "unable to allocate mach port for IOSurface");
return;
}
[self sendMessageToClientsWithMsgId:MachMsgIdFrame
components:@[
[NSMachPort
portWithMachPort:framePort
options:NSMachPortDeallocateNone],
timestampData,
fpsNumeratorData,
[self sendMessageToClientsWithMsgId:MachMsgIdFrame components:@[
[NSMachPort portWithMachPort:framePort options:NSMachPortDeallocateNone], timestampData, fpsNumeratorData,
fpsDenominatorData
]];
@ -185,8 +160,7 @@
- (void)stop
{
blog(LOG_DEBUG, "sending stop message to %lu clients",
self.clientPorts.count);
blog(LOG_DEBUG, "sending stop message to %lu clients", self.clientPorts.count);
[self sendMessageToClientsWithMsgId:MachMsgIdStop components:nil];
}

View file

@ -39,8 +39,7 @@ struct virtualcam_data {
OBSDALMachServer *machServer;
};
@interface SystemExtensionActivationDelegate
: NSObject <OSSystemExtensionRequestDelegate> {
@interface SystemExtensionActivationDelegate : NSObject <OSSystemExtensionRequestDelegate> {
@private
struct virtualcam_data *_vcam;
}
@ -64,64 +63,49 @@ struct virtualcam_data {
return self;
}
- (OSSystemExtensionReplacementAction)
request:(nonnull OSSystemExtensionRequest *)request
actionForReplacingExtension:
(nonnull OSSystemExtensionProperties *)existing
- (OSSystemExtensionReplacementAction)request:(nonnull OSSystemExtensionRequest *)request
actionForReplacingExtension:(nonnull OSSystemExtensionProperties *)existing
withExtension:(nonnull OSSystemExtensionProperties *)ext
{
NSString *extVersion =
[NSString stringWithFormat:@"%@.%@", [ext bundleShortVersion],
[ext bundleVersion]];
NSString *existingVersion = [NSString
stringWithFormat:@"%@.%@", [existing bundleShortVersion],
[existing bundleVersion]];
NSString *extVersion = [NSString stringWithFormat:@"%@.%@", [ext bundleShortVersion], [ext bundleVersion]];
NSString *existingVersion =
[NSString stringWithFormat:@"%@.%@", [existing bundleShortVersion], [existing bundleVersion]];
if ([extVersion compare:existingVersion
options:NSNumericSearch] == NSOrderedDescending) {
if ([extVersion compare:existingVersion options:NSNumericSearch] == NSOrderedDescending) {
return OSSystemExtensionReplacementActionReplace;
} else {
return OSSystemExtensionReplacementActionCancel;
}
}
- (void)request:(nonnull OSSystemExtensionRequest *)request
didFailWithError:(nonnull NSError *)error
- (void)request:(nonnull OSSystemExtensionRequest *)request didFailWithError:(nonnull NSError *)error
{
NSString *errorMessage;
int severity;
switch (error.code) {
case OSSystemExtensionErrorRequestCanceled:
errorMessage =
@"macOS Camera Extension installation request cancelled.";
errorMessage = @"macOS Camera Extension installation request cancelled.";
severity = LOG_INFO;
break;
case OSSystemExtensionErrorUnsupportedParentBundleLocation:
self.lastErrorMessage = [NSString
stringWithUTF8String:
obs_module_text(
"Error.SystemExtension.WrongLocation")];
self.lastErrorMessage =
[NSString stringWithUTF8String:obs_module_text("Error.SystemExtension.WrongLocation")];
errorMessage = self.lastErrorMessage;
severity = LOG_WARNING;
break;
default:
self.lastErrorMessage = error.localizedDescription;
errorMessage = [NSString
stringWithFormat:
@"OSSystemExtensionErrorCode %ld (\"%s\")",
error.code,
errorMessage = [NSString stringWithFormat:@"OSSystemExtensionErrorCode %ld (\"%s\")", error.code,
error.localizedDescription.UTF8String];
severity = LOG_ERROR;
break;
}
blog(severity, "mac-camera-extension error: %s",
errorMessage.UTF8String);
blog(severity, "mac-camera-extension error: %s", errorMessage.UTF8String);
}
- (void)request:(nonnull OSSystemExtensionRequest *)request
didFinishWithResult:(OSSystemExtensionRequestResult)result
- (void)request:(nonnull OSSystemExtensionRequest *)request didFinishWithResult:(OSSystemExtensionRequestResult)result
{
self.installed = YES;
blog(LOG_INFO, "macOS Camera Extension activated successfully.");
@ -138,8 +122,7 @@ struct virtualcam_data {
static void install_cmio_system_extension(struct virtualcam_data *vcam)
{
OSSystemExtensionRequest *request = [OSSystemExtensionRequest
activationRequestForExtension:
@"com.obsproject.obs-studio.mac-camera-extension"
activationRequestForExtension:@"com.obsproject.obs-studio.mac-camera-extension"
queue:dispatch_get_main_queue()];
request.delegate = vcam->extensionDelegate;
@ -156,35 +139,25 @@ static dal_plugin_status check_dal_plugin()
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *dalPluginFileName = [OBSDalDestination
stringByAppendingString:@"/obs-mac-virtualcam.plugin"];
NSString *dalPluginFileName = [OBSDalDestination stringByAppendingString:@"/obs-mac-virtualcam.plugin"];
BOOL dalPluginInstalled =
[fileManager fileExistsAtPath:dalPluginFileName];
BOOL dalPluginInstalled = [fileManager fileExistsAtPath:dalPluginFileName];
if (dalPluginInstalled) {
NSDictionary *dalPluginInfoPlist = [NSDictionary
dictionaryWithContentsOfURL:
[NSURL fileURLWithPath:
[OBSDalDestination
stringByAppendingString:
@"/obs-mac-virtualcam.plugin/Contents/Info.plist"]]];
[NSURL fileURLWithPath:[OBSDalDestination
stringByAppendingString:@"/obs-mac-virtualcam.plugin/Contents/Info.plist"]]];
NSString *dalPluginVersion = [dalPluginInfoPlist
valueForKey:@"CFBundleShortVersionString"];
NSString *dalPluginBuild =
[dalPluginInfoPlist valueForKey:@"CFBundleVersion"];
NSString *dalPluginVersion = [dalPluginInfoPlist valueForKey:@"CFBundleShortVersionString"];
NSString *dalPluginBuild = [dalPluginInfoPlist valueForKey:@"CFBundleVersion"];
NSString *obsVersion = [[[NSBundle mainBundle] infoDictionary]
objectForKey:@"CFBundleShortVersionString"];
NSString *obsBuild = [[[NSBundle mainBundle] infoDictionary]
objectForKey:(NSString *)kCFBundleVersionKey];
NSString *obsVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
NSString *obsBuild = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *) kCFBundleVersionKey];
BOOL dalPluginUpdateNeeded =
!([dalPluginVersion isEqualToString:obsVersion] &&
[dalPluginBuild isEqualToString:obsBuild]);
!([dalPluginVersion isEqualToString:obsVersion] && [dalPluginBuild isEqualToString:obsBuild]);
return dalPluginUpdateNeeded ? OBSDalPluginNeedsUpdate
: OBSDalPluginInstalled;
return dalPluginUpdateNeeded ? OBSDalPluginNeedsUpdate : OBSDalPluginInstalled;
}
return OBSDalPluginNotInstalled;
@ -193,8 +166,7 @@ static dal_plugin_status check_dal_plugin()
static bool install_dal_plugin(bool update)
{
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL dalPluginDirExists =
[fileManager fileExistsAtPath:OBSDalDestination];
BOOL dalPluginDirExists = [fileManager fileExistsAtPath:OBSDalDestination];
NSURL *bundleURL = [[NSBundle mainBundle] bundleURL];
NSString *pluginPath = @"Contents/Resources/obs-mac-virtualcam.plugin";
@ -203,44 +175,27 @@ static bool install_dal_plugin(bool update)
NSString *dalPluginSourcePath = [pluginUrl path];
NSString *createPluginDirCmd =
(!dalPluginDirExists)
? [NSString stringWithFormat:@"mkdir -p '%@' && ",
OBSDalDestination]
: @"";
NSString *deleteOldPluginCmd =
(update) ? [NSString stringWithFormat:@"rm -rf '%@' && ",
OBSDalDestination]
: @"";
NSString *copyPluginCmd = [NSString
stringWithFormat:@"cp -R '%@' '%@'", dalPluginSourcePath,
OBSDalDestination];
(!dalPluginDirExists) ? [NSString stringWithFormat:@"mkdir -p '%@' && ", OBSDalDestination] : @"";
NSString *deleteOldPluginCmd = (update) ? [NSString stringWithFormat:@"rm -rf '%@' && ", OBSDalDestination] : @"";
NSString *copyPluginCmd = [NSString stringWithFormat:@"cp -R '%@' '%@'", dalPluginSourcePath, OBSDalDestination];
if ([fileManager fileExistsAtPath:dalPluginSourcePath]) {
NSString *copyCmd = [NSString
stringWithFormat:
@"do shell script \"%@%@%@\" with administrator privileges",
createPluginDirCmd, deleteOldPluginCmd,
copyPluginCmd];
NSString *copyCmd = [NSString stringWithFormat:@"do shell script \"%@%@%@\" with administrator privileges",
createPluginDirCmd, deleteOldPluginCmd, copyPluginCmd];
NSDictionary *errorDict;
NSAppleScript *scriptObject =
[[NSAppleScript alloc] initWithSource:copyCmd];
NSAppleScript *scriptObject = [[NSAppleScript alloc] initWithSource:copyCmd];
[scriptObject executeAndReturnError:&errorDict];
if (errorDict != nil) {
const char *errorMessage = [[errorDict
objectForKey:@"NSAppleScriptErrorMessage"]
UTF8String];
const char *errorMessage = [[errorDict objectForKey:@"NSAppleScriptErrorMessage"] UTF8String];
blog(LOG_INFO,
"[macOS] VirtualCam DAL Plugin Installation status: %s",
errorMessage);
blog(LOG_INFO, "[macOS] VirtualCam DAL Plugin Installation status: %s", errorMessage);
return false;
} else {
return true;
}
} else {
blog(LOG_INFO,
"[macOS] VirtualCam DAL Plugin not shipped with OBS");
blog(LOG_INFO, "[macOS] VirtualCam DAL Plugin not shipped with OBS");
return false;
}
}
@ -248,8 +203,7 @@ static bool install_dal_plugin(bool update)
static bool uninstall_dal_plugin()
{
NSAppleScript *scriptObject = [[NSAppleScript alloc]
initWithSource:
[NSString
initWithSource:[NSString
stringWithFormat:
@"do shell script \"rm -rf %@/obs-mac-virtualcam.plugin\" with administrator privileges",
OBSDalDestination]];
@ -258,35 +212,27 @@ static bool uninstall_dal_plugin()
[scriptObject executeAndReturnError:&errorDict];
if (errorDict) {
blog(LOG_INFO,
"[macOS] VirtualCam DAL Plugin could not be uninstalled: %s",
[[errorDict objectForKey:NSAppleScriptErrorMessage]
UTF8String]);
blog(LOG_INFO, "[macOS] VirtualCam DAL Plugin could not be uninstalled: %s",
[[errorDict objectForKey:NSAppleScriptErrorMessage] UTF8String]);
return false;
} else {
return true;
}
}
FourCharCode convert_video_format_to_mac(enum video_format format,
enum video_range_type range)
FourCharCode convert_video_format_to_mac(enum video_format format, enum video_range_type range)
{
switch (format) {
case VIDEO_FORMAT_I420:
return (range == VIDEO_RANGE_FULL)
? kCVPixelFormatType_420YpCbCr8PlanarFullRange
return (range == VIDEO_RANGE_FULL) ? kCVPixelFormatType_420YpCbCr8PlanarFullRange
: kCVPixelFormatType_420YpCbCr8Planar;
case VIDEO_FORMAT_NV12:
return (range == VIDEO_RANGE_FULL)
? kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
return (range == VIDEO_RANGE_FULL) ? kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
: kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
case VIDEO_FORMAT_UYVY:
return (range == VIDEO_RANGE_FULL)
? kCVPixelFormatType_422YpCbCr8FullRange
: kCVPixelFormatType_422YpCbCr8;
return (range == VIDEO_RANGE_FULL) ? kCVPixelFormatType_422YpCbCr8FullRange : kCVPixelFormatType_422YpCbCr8;
case VIDEO_FORMAT_P010:
return (range == VIDEO_RANGE_FULL)
? kCVPixelFormatType_420YpCbCr10BiPlanarFullRange
return (range == VIDEO_RANGE_FULL) ? kCVPixelFormatType_420YpCbCr10BiPlanarFullRange
: kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange;
default:
// Zero indicates that the format is not supported on macOS
@ -302,20 +248,16 @@ static const char *virtualcam_output_get_name(void *type_data)
return obs_module_text("Plugin_Name");
}
static void *virtualcam_output_create(obs_data_t *settings,
obs_output_t *output)
static void *virtualcam_output_create(obs_data_t *settings, obs_output_t *output)
{
UNUSED_PARAMETER(settings);
struct virtualcam_data *vcam =
(struct virtualcam_data *)bzalloc(sizeof(*vcam));
struct virtualcam_data *vcam = (struct virtualcam_data *) bzalloc(sizeof(*vcam));
vcam->output = output;
if (cmio_extension_supported()) {
vcam->extensionDelegate =
[[SystemExtensionActivationDelegate alloc]
initWithVcam:vcam];
vcam->extensionDelegate = [[SystemExtensionActivationDelegate alloc] initWithVcam:vcam];
install_cmio_system_extension(vcam);
} else {
vcam->machServer = [[OBSDALMachServer alloc] init];
@ -346,33 +288,22 @@ static bool virtualcam_output_start(void *data)
if (cmio_extension_supported()) {
if (dal_status != OBSDalPluginNotInstalled) {
if (!uninstall_dal_plugin()) {
obs_output_set_last_error(
vcam->output,
obs_module_text(
"Error.DAL.NotUninstalled"));
obs_output_set_last_error(vcam->output, obs_module_text("Error.DAL.NotUninstalled"));
return false;
}
}
SystemExtensionActivationDelegate *delegate =
vcam->extensionDelegate;
SystemExtensionActivationDelegate *delegate = vcam->extensionDelegate;
if (!delegate.installed) {
if (delegate.lastErrorMessage) {
obs_output_set_last_error(
vcam->output,
[NSString
stringWithFormat:
@"%s\n\n%@",
obs_module_text(
"Error.SystemExtension.InstallationError"),
[NSString stringWithFormat:@"%s\n\n%@", obs_module_text("Error.SystemExtension.InstallationError"),
delegate.lastErrorMessage]
.UTF8String);
} else {
obs_output_set_last_error(
vcam->output,
obs_module_text(
"Error.SystemExtension.NotInstalled"));
obs_output_set_last_error(vcam->output, obs_module_text("Error.SystemExtension.NotInstalled"));
}
return false;
@ -388,16 +319,14 @@ static bool virtualcam_output_start(void *data)
}
if (!success) {
obs_output_set_last_error(vcam->output,
"Error.DAL.NotInstalled");
obs_output_set_last_error(vcam->output, "Error.DAL.NotInstalled");
return false;
}
}
obs_get_video_info(&vcam->videoInfo);
FourCharCode video_format = convert_video_format_to_mac(
vcam->videoInfo.output_format, vcam->videoInfo.range);
FourCharCode video_format = convert_video_format_to_mac(vcam->videoInfo.output_format, vcam->videoInfo.range);
struct video_scale_info conversion = {};
conversion.width = vcam->videoInfo.output_width;
@ -407,13 +336,11 @@ static bool virtualcam_output_start(void *data)
if (!video_format) {
// Selected output format is not supported natively by CoreVideo, CPU conversion necessary
blog(LOG_WARNING,
"Selected output format (%s) not supported by CoreVideo, enabling CPU transcoding...",
blog(LOG_WARNING, "Selected output format (%s) not supported by CoreVideo, enabling CPU transcoding...",
get_video_format_name(vcam->videoInfo.output_format));
conversion.format = VIDEO_FORMAT_NV12;
video_format = convert_video_format_to_mac(conversion.format,
conversion.range);
video_format = convert_video_format_to_mac(conversion.format, conversion.range);
} else {
conversion.format = vcam->videoInfo.output_format;
}
@ -426,13 +353,11 @@ static bool virtualcam_output_start(void *data)
(id) kCVPixelBufferHeightKey: @(vcam->videoInfo.output_height),
(id) kCVPixelBufferIOSurfacePropertiesKey: @ {}
};
CVReturn status = CVPixelBufferPoolCreate(
kCFAllocatorDefault, (__bridge CFDictionaryRef)pAttr,
CVReturn status = CVPixelBufferPoolCreate(kCFAllocatorDefault, (__bridge CFDictionaryRef) pAttr,
(__bridge CFDictionaryRef) pbAttr, &vcam->pool);
if (status != kCVReturnSuccess) {
blog(LOG_ERROR,
"unable to allocate pixel buffer pool (error %d)", status);
blog(LOG_ERROR, "unable to allocate pixel buffer pool (error %d)", status);
return false;
}
@ -440,40 +365,30 @@ static bool virtualcam_output_start(void *data)
UInt32 size;
UInt32 used;
CMIOObjectPropertyAddress address{
.mSelector = kCMIOHardwarePropertyDevices,
CMIOObjectPropertyAddress address {.mSelector = kCMIOHardwarePropertyDevices,
.mScope = kCMIOObjectPropertyScopeGlobal,
.mElement = kCMIOObjectPropertyElementMain};
CMIOObjectGetPropertyDataSize(kCMIOObjectSystemObject, &address,
0, NULL, &size);
CMIOObjectGetPropertyDataSize(kCMIOObjectSystemObject, &address, 0, NULL, &size);
size_t num_devices = size / sizeof(CMIOObjectID);
CMIOObjectID cmio_devices[num_devices];
CMIOObjectGetPropertyData(kCMIOObjectSystemObject, &address, 0,
NULL, size, &used, &cmio_devices);
CMIOObjectGetPropertyData(kCMIOObjectSystemObject, &address, 0, NULL, size, &used, &cmio_devices);
vcam->deviceID = 0;
NSString *OBSVirtualCamUUID = [[NSBundle
bundleWithIdentifier:@"com.obsproject.mac-virtualcam"]
NSString *OBSVirtualCamUUID = [[NSBundle bundleWithIdentifier:@"com.obsproject.mac-virtualcam"]
objectForInfoDictionaryKey:@"OBSCameraDeviceUUID"];
for (size_t i = 0; i < num_devices; i++) {
CMIOObjectID cmio_device = cmio_devices[i];
address.mSelector = kCMIODevicePropertyDeviceUID;
UInt32 device_name_size;
CMIOObjectGetPropertyDataSize(cmio_device, &address, 0,
NULL, &device_name_size);
CMIOObjectGetPropertyDataSize(cmio_device, &address, 0, NULL, &device_name_size);
CFStringRef uid;
CMIOObjectGetPropertyData(cmio_device, &address, 0,
NULL, device_name_size, &used,
&uid);
CMIOObjectGetPropertyData(cmio_device, &address, 0, NULL, device_name_size, &used, &uid);
const char *uid_string = CFStringGetCStringPtr(
uid, kCFStringEncodingUTF8);
if (uid_string &&
strcmp(uid_string, OBSVirtualCamUUID.UTF8String) ==
0) {
const char *uid_string = CFStringGetCStringPtr(uid, kCFStringEncodingUTF8);
if (uid_string && strcmp(uid_string, OBSVirtualCamUUID.UTF8String) == 0) {
vcam->deviceID = cmio_device;
CFRelease(uid);
break;
@ -483,40 +398,28 @@ static bool virtualcam_output_start(void *data)
}
if (!vcam->deviceID) {
obs_output_set_last_error(
vcam->output,
obs_module_text(
"Error.SystemExtension.CameraUnavailable"));
obs_output_set_last_error(vcam->output, obs_module_text("Error.SystemExtension.CameraUnavailable"));
return false;
}
address.mSelector = kCMIODevicePropertyStreams;
CMIOObjectGetPropertyDataSize(vcam->deviceID, &address, 0, NULL,
&size);
CMIOObjectGetPropertyDataSize(vcam->deviceID, &address, 0, NULL, &size);
CMIOStreamID stream_ids[(size / sizeof(CMIOStreamID))];
CMIOObjectGetPropertyData(vcam->deviceID, &address, 0, NULL,
size, &used, &stream_ids);
CMIOObjectGetPropertyData(vcam->deviceID, &address, 0, NULL, size, &used, &stream_ids);
vcam->streamID = stream_ids[1];
CMIOStreamCopyBufferQueue(
vcam->streamID, [](CMIOStreamID, void *, void *) {},
NULL, &vcam->queue);
CMVideoFormatDescriptionCreate(kCFAllocatorDefault,
video_format,
vcam->videoInfo.output_width,
vcam->videoInfo.output_height,
NULL, &vcam->formatDescription);
vcam->streamID, [](CMIOStreamID, void *, void *) {
}, NULL, &vcam->queue);
CMVideoFormatDescriptionCreate(kCFAllocatorDefault, video_format, vcam->videoInfo.output_width,
vcam->videoInfo.output_height, NULL, &vcam->formatDescription);
OSStatus result =
CMIODeviceStartStream(vcam->deviceID, vcam->streamID);
OSStatus result = CMIODeviceStartStream(vcam->deviceID, vcam->streamID);
if (result != noErr) {
obs_output_set_last_error(
vcam->output,
obs_module_text(
"Error.SystemExtension.CameraNotStarted"));
obs_output_set_last_error(vcam->output, obs_module_text("Error.SystemExtension.CameraNotStarted"));
return false;
}
} else {
@ -551,12 +454,10 @@ static void virtualcam_output_raw_video(void *data, struct video_data *frame)
struct virtualcam_data *vcam = (struct virtualcam_data *) data;
CVPixelBufferRef frameRef = nil;
CVReturn status = CVPixelBufferPoolCreatePixelBuffer(
kCFAllocatorDefault, vcam->pool, &frameRef);
CVReturn status = CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, vcam->pool, &frameRef);
if (status != kCVReturnSuccess) {
blog(LOG_ERROR, "unable to allocate pixel buffer (error %d)",
status);
blog(LOG_ERROR, "unable to allocate pixel buffer (error %d)", status);
return;
}
@ -589,27 +490,20 @@ static void virtualcam_output_raw_video(void *data, struct video_data *frame)
uint8_t *src = frame->data[plane];
if (!src) {
blog(LOG_WARNING,
"Video data from OBS contains less planes than CVPixelBuffer");
blog(LOG_WARNING, "Video data from OBS contains less planes than CVPixelBuffer");
break;
}
uint8_t *dst =
(uint8_t *)CVPixelBufferGetBaseAddressOfPlane(
frameRef, plane);
uint8_t *dst = (uint8_t *) CVPixelBufferGetBaseAddressOfPlane(frameRef, plane);
size_t destBytesPerRow =
CVPixelBufferGetBytesPerRowOfPlane(frameRef,
plane);
size_t destBytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(frameRef, plane);
size_t srcBytesPerRow = frame->linesize[plane];
size_t height =
CVPixelBufferGetHeightOfPlane(frameRef, plane);
size_t height = CVPixelBufferGetHeightOfPlane(frameRef, plane);
if (destBytesPerRow == srcBytesPerRow) {
memcpy(dst, src, destBytesPerRow * height);
} else {
for (int line = 0; (size_t)line < height;
line++) {
for (int line = 0; (size_t) line < height; line++) {
memcpy(dst, src, srcBytesPerRow);
src += srcBytesPerRow;
dst += destBytesPerRow;
@ -622,20 +516,14 @@ static void virtualcam_output_raw_video(void *data, struct video_data *frame)
if (cmio_extension_supported()) {
CMSampleBufferRef sampleBuffer;
CMSampleTimingInfo timingInfo{
.presentationTimeStamp =
CMTimeMake(frame->timestamp, NSEC_PER_SEC)};
CMSampleTimingInfo timingInfo {.presentationTimeStamp = CMTimeMake(frame->timestamp, NSEC_PER_SEC)};
CMSampleBufferCreateForImageBuffer(kCFAllocatorDefault,
frameRef, true, NULL, NULL,
vcam->formatDescription,
CMSampleBufferCreateForImageBuffer(kCFAllocatorDefault, frameRef, true, NULL, NULL, vcam->formatDescription,
&timingInfo, &sampleBuffer);
CMSimpleQueueEnqueue(vcam->queue, sampleBuffer);
} else {
// Share pixel buffer with clients
[vcam->machServer sendPixelBuffer:frameRef
timestamp:frame->timestamp
fpsNumerator:vcam->videoInfo.fps_num
[vcam->machServer sendPixelBuffer:frameRef timestamp:frame->timestamp fpsNumerator:vcam->videoInfo.fps_num
fpsDenominator:vcam->videoInfo.fps_den];
}

View file

@ -23,10 +23,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
void EditorWidget::buildEffectContainer(AEffect *effect)
{
NSView *view =
[[NSView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300)];
cocoaViewContainer =
QWidget::createWindowContainer(QWindow::fromWinId(WId(view)));
NSView *view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300)];
cocoaViewContainer = QWidget::createWindowContainer(QWindow::fromWinId(WId(view)));
cocoaViewContainer->move(0, 0);
cocoaViewContainer->resize(300, 300);
cocoaViewContainer->show();
@ -39,16 +37,13 @@ void EditorWidget::buildEffectContainer(AEffect *effect)
VstRect *vstRect = nullptr;
effect->dispatcher(effect, effEditGetRect, 0, 0, &vstRect, 0);
if (vstRect) {
NSRect frame = NSMakeRect(vstRect->left, vstRect->top,
vstRect->right, vstRect->bottom);
NSRect frame = NSMakeRect(vstRect->left, vstRect->top, vstRect->right, vstRect->bottom);
[view setFrame:frame];
cocoaViewContainer->resize(vstRect->right - vstRect->left,
vstRect->bottom - vstRect->top);
cocoaViewContainer->resize(vstRect->right - vstRect->left, vstRect->bottom - vstRect->top);
setFixedSize(vstRect->right - vstRect->left,
vstRect->bottom - vstRect->top);
setFixedSize(vstRect->right - vstRect->left, vstRect->bottom - vstRect->top);
}
effect->dispatcher(effect, effEditOpen, 0, 0, view, 0);

View file

@ -22,17 +22,13 @@ AEffect *VSTPlugin::loadEffect()
AEffect *newEffect = NULL;
// Create a path to the bundle
CFStringRef pluginPathStringRef = CFStringCreateWithCString(
NULL, pluginPath.c_str(), kCFStringEncodingUTF8);
CFURLRef bundleUrl = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
pluginPathStringRef,
kCFURLPOSIXPathStyle,
true);
CFStringRef pluginPathStringRef = CFStringCreateWithCString(NULL, pluginPath.c_str(), kCFStringEncodingUTF8);
CFURLRef bundleUrl =
CFURLCreateWithFileSystemPath(kCFAllocatorDefault, pluginPathStringRef, kCFURLPOSIXPathStyle, true);
if (bundleUrl == NULL) {
CFRelease(pluginPathStringRef);
blog(LOG_WARNING,
"Couldn't make URL reference for VST plug-in");
blog(LOG_WARNING, "Couldn't make URL reference for VST plug-in");
return NULL;
}
@ -46,15 +42,12 @@ AEffect *VSTPlugin::loadEffect()
}
vstPluginMain mainEntryPoint = NULL;
mainEntryPoint = (vstPluginMain)CFBundleGetFunctionPointerForName(
bundle, CFSTR("VSTPluginMain"));
mainEntryPoint = (vstPluginMain) CFBundleGetFunctionPointerForName(bundle, CFSTR("VSTPluginMain"));
// VST plugins previous to the 2.4 SDK used main_macho for the
// entry point name.
if (mainEntryPoint == NULL) {
mainEntryPoint =
(vstPluginMain)CFBundleGetFunctionPointerForName(
bundle, CFSTR("main_macho"));
mainEntryPoint = (vstPluginMain) CFBundleGetFunctionPointerForName(bundle, CFSTR("main_macho"));
}
if (mainEntryPoint == NULL) {

View file

@ -30,12 +30,10 @@ static void add_path_fonts(NSFileManager *file_manager, NSString *path)
files = [file_manager contentsOfDirectoryAtPath:path error:nil];
for (NSString *file in files) {
NSString *full_path =
[path stringByAppendingPathComponent:file];
NSString *full_path = [path stringByAppendingPathComponent:file];
BOOL is_dir = FALSE;
bool folder_exists = [file_manager fileExistsAtPath:full_path
isDirectory:&is_dir];
bool folder_exists = [file_manager fileExistsAtPath:full_path isDirectory:&is_dir];
if (folder_exists && is_dir) {
add_path_fonts(file_manager, full_path);
@ -49,18 +47,13 @@ void load_os_font_list(void)
{
@autoreleasepool {
BOOL is_dir;
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSLibraryDirectory, NSAllDomainsMask, true);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSAllDomainsMask, true);
for (NSString *path in paths) {
NSFileManager *file_manager =
[NSFileManager defaultManager];
NSString *font_path =
[path stringByAppendingPathComponent:@"Fonts"];
NSFileManager *file_manager = [NSFileManager defaultManager];
NSString *font_path = [path stringByAppendingPathComponent:@"Fonts"];
bool folder_exists = [file_manager
fileExistsAtPath:font_path
isDirectory:&is_dir];
bool folder_exists = [file_manager fileExistsAtPath:font_path isDirectory:&is_dir];
if (folder_exists && is_dir)
add_path_fonts(file_manager, font_path);
@ -77,20 +70,16 @@ static uint32_t add_font_checksum(uint32_t checksum, const char *path)
return checksum;
}
static uint32_t add_font_checksum_path(uint32_t checksum,
NSFileManager *file_manager,
NSString *path)
static uint32_t add_font_checksum_path(uint32_t checksum, NSFileManager *file_manager, NSString *path)
{
NSArray *files = NULL;
files = [file_manager contentsOfDirectoryAtPath:path error:nil];
for (NSString *file in files) {
NSString *full_path =
[path stringByAppendingPathComponent:file];
NSString *full_path = [path stringByAppendingPathComponent:file];
checksum = add_font_checksum(
checksum, full_path.fileSystemRepresentation);
checksum = add_font_checksum(checksum, full_path.fileSystemRepresentation);
}
return checksum;
@ -102,22 +91,16 @@ uint32_t get_font_checksum(void)
@autoreleasepool {
BOOL is_dir;
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSLibraryDirectory, NSAllDomainsMask, true);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSAllDomainsMask, true);
for (NSString *path in paths) {
NSFileManager *file_manager =
[NSFileManager defaultManager];
NSString *font_path =
[path stringByAppendingPathComponent:@"Fonts"];
NSFileManager *file_manager = [NSFileManager defaultManager];
NSString *font_path = [path stringByAppendingPathComponent:@"Fonts"];
bool folder_exists = [file_manager
fileExistsAtPath:font_path
isDirectory:&is_dir];
bool folder_exists = [file_manager fileExistsAtPath:font_path isDirectory:&is_dir];
if (folder_exists && is_dir)
checksum = add_font_checksum_path(
checksum, file_manager, font_path);
checksum = add_font_checksum_path(checksum, file_manager, font_path);
}
}

View file

@ -16,23 +16,23 @@ static const int cy = 600;
/* --------------------------------------------------- */
template<typename T, typename D_T, D_T D>
struct OBSUniqueHandle : std::unique_ptr<T, std::function<D_T>> {
template<typename T, typename D_T, D_T D> struct OBSUniqueHandle : std::unique_ptr<T, std::function<D_T>> {
using base = std::unique_ptr<T, std::function<D_T>>;
explicit OBSUniqueHandle(T *obj = nullptr) : base(obj, D) {}
operator T *() { return base::get(); }
explicit OBSUniqueHandle(T *obj = nullptr) : base(obj, D)
{}
operator T *()
{
return base::get();
}
};
#define DECLARE_DELETER(x) decltype(x), x
using SourceContext =
OBSUniqueHandle<obs_source, DECLARE_DELETER(obs_source_release)>;
using SourceContext = OBSUniqueHandle<obs_source, DECLARE_DELETER(obs_source_release)>;
using SceneContext =
OBSUniqueHandle<obs_scene, DECLARE_DELETER(obs_scene_release)>;
using SceneContext = OBSUniqueHandle<obs_scene, DECLARE_DELETER(obs_scene_release)>;
using DisplayContext =
OBSUniqueHandle<obs_display, DECLARE_DELETER(obs_display_destroy)>;
using DisplayContext = OBSUniqueHandle<obs_display, DECLARE_DELETER(obs_display_destroy)>;
#undef DECLARE_DELETER
@ -78,8 +78,7 @@ static SceneContext SetupScene()
/* ------------------------------------------------------ */
/* create source */
SourceContext source{
obs_source_create("random", "a test source", nullptr, nullptr)};
SourceContext source {obs_source_create("random", "a test source", nullptr, nullptr)};
if (!source)
throw "Couldn't create random test source";
@ -116,10 +115,7 @@ static SceneContext SetupScene()
try {
NSRect content_rect = NSMakeRect(0, 0, cx, cy);
win = [[NSWindow alloc]
initWithContentRect:content_rect
styleMask:NSTitledWindowMask |
NSClosableWindowMask
win = [[NSWindow alloc] initWithContentRect:content_rect styleMask:NSTitledWindowMask | NSClosableWindowMask
backing:NSBackingStoreBuffered
defer:NO];
if (!win)
@ -144,11 +140,9 @@ static SceneContext SetupScene()
scene = SetupScene();
obs_display_add_draw_callback(
display.get(),
[](void *, uint32_t, uint32_t) {
display.get(), [](void *, uint32_t, uint32_t) {
obs_render_main_texture();
},
nullptr);
}, nullptr);
} catch (char const *error) {
NSLog(@"%s\n", error);