mac-syphon: Update Syphon, use obs-deps framework

Updates the syphon to use the Syphon.framework from obs-deps instead of
the submodule.
The submodule however was not updated in 9 years and additionally had
custom patches, compared to the obs-deps release that's built on the
current git commit of Syphon, meaning that some code changes are
necessary. It would be nice to split the code and cmake changes into
multiple commits (where the first would update the submodule and contain
the plugin code changes, and the second switch the cmake away from the
submodule to the obs-deps release), but it really doesn't make sense to
update the submodule first if it gets removed anyways.

Adds a subclass for SyphonClientBase that is responsible for receiving
the frames. This has the advantage that it doesn't need an OpenGL
context like the existing SyphonOpenGLClient, and can just return an
IOSurface directly (without some kind of middleman).
This commit is contained in:
gxalpha 2023-06-10 04:28:08 +02:00 committed by Ryan Foster
parent d31d271b43
commit 6e7e4acb93
5 changed files with 73 additions and 85 deletions

View file

@ -65,6 +65,13 @@ function(set_target_properties_obs target)
PROPERTY XCODE_EMBED_FRAMEWORKS ${SPARKLE})
endif()
if(TARGET mac-syphon)
set_property(
TARGET ${target}
APPEND
PROPERTY XCODE_EMBED_FRAMEWORKS ${SYPHON})
endif()
get_property(obs_executables GLOBAL PROPERTY _OBS_EXECUTABLES)
add_dependencies(${target} ${obs_executables})
foreach(executable IN LISTS obs_executables)

View file

@ -11,76 +11,19 @@ else()
target_enable_feature(mac-syphon "Syphon sharing support")
endif()
find_library(COCOA Cocoa)
find_library(IOSURF IOSurface)
find_library(SCRIPTINGBRIDGE ScriptingBridge)
mark_as_advanced(COCOA IOSURF SCRIPTINGBRIDGE)
add_library(syphon-framework STATIC EXCLUDE_FROM_ALL )
add_library(Syphon::Framework ALIAS syphon-framework)
target_sources(
syphon-framework
PRIVATE syphon-framework/Syphon_Prefix.pch
syphon-framework/Syphon.h
syphon-framework/SyphonBuildMacros.h
syphon-framework/SyphonCFMessageReceiver.m
syphon-framework/SyphonCFMessageReceiver.h
syphon-framework/SyphonCFMessageSender.h
syphon-framework/SyphonCFMessageSender.m
syphon-framework/SyphonClient.m
syphon-framework/SyphonClient.h
syphon-framework/SyphonClientConnectionManager.m
syphon-framework/SyphonClientConnectionManager.h
syphon-framework/SyphonDispatch.c
syphon-framework/SyphonDispatch.h
syphon-framework/SyphonIOSurfaceImage.m
syphon-framework/SyphonIOSurfaceImage.h
syphon-framework/SyphonImage.m
syphon-framework/SyphonImage.h
syphon-framework/SyphonMachMessageReceiver.m
syphon-framework/SyphonMachMessageReceiver.h
syphon-framework/SyphonMachMessageSender.m
syphon-framework/SyphonMachMessageSender.h
syphon-framework/SyphonMessageQueue.m
syphon-framework/SyphonMessageQueue.h
syphon-framework/SyphonMessageReceiver.m
syphon-framework/SyphonMessageReceiver.h
syphon-framework/SyphonMessageSender.m
syphon-framework/SyphonMessageSender.h
syphon-framework/SyphonMessaging.m
syphon-framework/SyphonMessaging.h
syphon-framework/SyphonOpenGLFunctions.c
syphon-framework/SyphonOpenGLFunctions.h
syphon-framework/SyphonPrivate.m
syphon-framework/SyphonPrivate.h
syphon-framework/SyphonServer.m
syphon-framework/SyphonServer.h
syphon-framework/SyphonServerConnectionManager.m
syphon-framework/SyphonServerConnectionManager.h
syphon-framework/SyphonServerDirectory.m
syphon-framework/SyphonServerDirectory.h)
target_compile_options(
syphon-framework
PRIVATE -include "${CMAKE_CURRENT_SOURCE_DIR}/syphon-framework/Syphon_Prefix.pch" -Wno-error=deprecated-declarations
PUBLIC -Wno-error=newline-eof -Wno-error=deprecated-implementations)
target_compile_definitions(syphon-framework PUBLIC "SYPHON_UNIQUE_CLASS_NAME_PREFIX=OBS_")
target_link_libraries(syphon-framework PUBLIC OpenGL::GL ${COCOA} ${IOSURF})
set_target_properties(syphon-framework PROPERTIES FOLDER "plugins/mac-syphon" PREFIX "")
find_library(SYPHON Syphon)
mark_as_advanced(SYPHON)
add_library(mac-syphon MODULE)
add_library(OBS::syphon ALIAS mac-syphon)
target_sources(mac-syphon PRIVATE syphon.m plugin-main.c)
target_sources(mac-syphon PRIVATE syphon.m plugin-main.c SyphonOBSClient.h SyphonOBSClient.m)
target_compile_options(mac-syphon PRIVATE -include "${CMAKE_CURRENT_SOURCE_DIR}/syphon-framework/Syphon_Prefix.pch"
-fobjc-arc)
target_link_libraries(mac-syphon PRIVATE OBS::libobs Syphon::Framework ${SCRIPTINGBRIDGE})
target_compile_options(mac-syphon PRIVATE -fobjc-arc)
target_link_libraries(
mac-syphon
PRIVATE OBS::libobs "$<LINK_LIBRARY:FRAMEWORK,AppKit.framework>" "$<LINK_LIBRARY:FRAMEWORK,IOSurface.framework>"
"$<LINK_LIBRARY:FRAMEWORK,ScriptingBridge.framework>" "$<LINK_LIBRARY:FRAMEWORK,${SYPHON}>")
set_target_properties_obs(
mac-syphon

View file

@ -0,0 +1,11 @@
#import <Syphon/Syphon.h>
#import <Syphon/SyphonSubclassing.h>
#import <IOSurface/IOSurface.h>
@interface SyphonOBSClient : SyphonClientBase
- (id)initWithServerDescription:(NSDictionary<NSString *, id> *)description
options:(NSDictionary<NSString *, id> *)options
newFrameHandler:(void (^)(SyphonOBSClient *))handler;
- (IOSurfaceRef)newFrameImage;
@end

View file

@ -0,0 +1,17 @@
#import "SyphonOBSClient.h"
@implementation SyphonOBSClient
- (id)initWithServerDescription:(NSDictionary<NSString *, id> *)description
options:(NSDictionary<NSString *, id> *)options
newFrameHandler:(void (^)(SyphonOBSClient *))handler
{
self = [super initWithServerDescription:description options:options newFrameHandler:handler];
return self;
}
- (IOSurfaceRef)newFrameImage
{
return [self newSurface];
}
@end

View file

@ -1,13 +1,17 @@
#import <Cocoa/Cocoa.h>
#import <AppKit/AppKit.h>
#import <IOSurface/IOSurface.h>
#import <ScriptingBridge/ScriptingBridge.h>
#import "syphon-framework/Syphon.h"
#include <obs-module.h>
#include <AvailabilityMacros.h>
#import <Syphon/Syphon.h>
#import <obs-module.h>
#import <AvailabilityMacros.h>
#import "SyphonOBSClient.h"
#define LOG(level, message, ...) blog(level, "%s: " message, obs_source_get_name(s->source), ##__VA_ARGS__)
struct syphon {
SYPHON_CLIENT_UNIQUE_CLASS_NAME *client;
SyphonOBSClient *client;
IOSurfaceRef ref;
gs_samplerstate_t *sampler;
@ -101,10 +105,21 @@ static inline NSDictionary *find_by_uuid(NSArray *arr, NSString *uuid)
return nil;
}
/* If you see this and think "surely these must be defined in some type of
* public header!": They don't. Or at least I couldnt't find anything. The
* definitions inside of Syphon are only in SyphonPrivate.h/m, and nowhere
* else. When we had Syphon as a submodule we abused this by using extern, but
* now that we use a prebuilt framework and as such no longer can acceess the
* private headers and sources directly, that's no longer possible. Other
* projects sometimes copy SyphonPrivate.h entirely (with the full definitions
* of everything), but for our purpose these strings are enough. */
const NSString *SyphonServerDescriptionDictionaryVersionKey = @"SyphonServerDescriptionDictionaryVersionKey";
const NSString *SyphonSurfaceType = @"SyphonSurfaceType";
const NSString *SyphonSurfaceTypeIOSurface = @"SyphonSurfaceTypeIOSurface";
const NSString *SyphonServerDescriptionSurfacesKey = @"SyphonServerDescriptionSurfacesKey";
static inline void check_version(syphon_t s, NSDictionary *desc)
{
extern const NSString *SyphonServerDescriptionDictionaryVersionKey;
NSNumber *version = desc[SyphonServerDescriptionDictionaryVersionKey];
if (!version)
return LOG(LOG_WARNING, "Server description does not contain "
@ -119,10 +134,6 @@ static inline void check_version(syphon_t s, NSDictionary *desc)
static inline void check_description(syphon_t s, NSDictionary *desc)
{
extern const NSString *SyphonSurfaceType;
extern const NSString *SyphonSurfaceTypeIOSurface;
extern const NSString *SyphonServerDescriptionSurfacesKey;
NSArray *surfaces = desc[SyphonServerDescriptionSurfacesKey];
if (!surfaces)
return LOG(LOG_WARNING, "Server description does not contain "
@ -145,9 +156,9 @@ 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, SyphonOBSClient *client)
{
IOSurfaceRef ref = [client IOSurface];
IOSurfaceRef ref = [client newFrameImage];
if (!ref)
return;
@ -196,11 +207,10 @@ 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) {
handle_new_frame(s, client);
}];
s->client = [[SyphonOBSClient alloc] initWithServerDescription:desc options:nil
newFrameHandler:^(SyphonOBSClient *client) {
handle_new_frame(s, client);
}];
s->active = true;
}
@ -254,7 +264,7 @@ static inline void handle_announce(syphon_t s, NSNotification *note)
if (!note)
return;
update_from_announce(s, note.object);
update_from_announce(s, note.userInfo);
update_properties(s);
}
@ -278,7 +288,7 @@ static inline void handle_retire(syphon_t s, NSNotification *note)
if (!note)
return;
update_from_retire(s, note.object);
update_from_retire(s, note.userInfo);
update_properties(s);
}