mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-07-14 15:24:07 +00:00
mac-capture: Disable all SCK modes besides WindowCapture on macOS 12
SCK has too many open issues on macOS 12 to enable full functionality on that version. Window Capture has the biggest performance uplift and so far the least amount of quirks, so leave this variant (with the "Beta" qualifier) for macOS versions before Ventura.
This commit is contained in:
parent
8e8148a2d5
commit
7cedd324e1
|
@ -24,4 +24,5 @@ Crop.size.height="Crop bottom"
|
|||
SCK.Name="macOS Screen Capture"
|
||||
SCK.Name.Beta="macOS Screen Capture (BETA)"
|
||||
SCK.AudioUnavailable="Audio capture requires macOS 13 or newer."
|
||||
SCK.CaptureTypeUnavailable="Selected capture type requires macOS 13 or newer."
|
||||
SCK.Method="Method"
|
||||
|
|
|
@ -69,6 +69,8 @@ struct screen_capture {
|
|||
NSString *application_id;
|
||||
};
|
||||
|
||||
#pragma mark -
|
||||
|
||||
static void destroy_screen_stream(struct screen_capture *sc)
|
||||
{
|
||||
if (sc->disp) {
|
||||
|
@ -365,33 +367,9 @@ static bool init_screen_stream(struct screen_capture *sc)
|
|||
case ScreenCaptureDisplayStream: {
|
||||
SCDisplay *target_display = get_target_display();
|
||||
|
||||
if (@available(macOS 13.0, *)) {
|
||||
content_filter = [[SCContentFilter alloc]
|
||||
initWithDisplay:target_display
|
||||
excludingWindows:[[NSArray alloc] init]];
|
||||
} else {
|
||||
NSArray *excluded = [sc->shareable_content.applications
|
||||
filteredArrayUsingPredicate:
|
||||
[NSPredicate predicateWithBlock:^BOOL(
|
||||
SCRunningApplication
|
||||
*application,
|
||||
NSDictionary<
|
||||
NSString *,
|
||||
id>
|
||||
*_Nullable bindings
|
||||
__attribute__((
|
||||
unused))) {
|
||||
return [application
|
||||
.bundleIdentifier
|
||||
isEqualToString:
|
||||
@"com.apple.controlcenter"];
|
||||
}]];
|
||||
|
||||
content_filter = [[SCContentFilter alloc]
|
||||
initWithDisplay:target_display
|
||||
excludingApplications:excluded
|
||||
exceptingWindows:[[NSArray alloc] init]];
|
||||
}
|
||||
content_filter = [[SCContentFilter alloc]
|
||||
initWithDisplay:target_display
|
||||
excludingWindows:[[NSArray alloc] init]];
|
||||
|
||||
set_display_mode(sc, target_display);
|
||||
} break;
|
||||
|
@ -464,13 +442,22 @@ static bool init_screen_stream(struct screen_capture *sc)
|
|||
[sc->stream_properties setShowsCursor:!sc->hide_cursor];
|
||||
[sc->stream_properties setColorSpaceName:kCGColorSpaceDisplayP3];
|
||||
[sc->stream_properties setPixelFormat:'l10r'];
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 130000
|
||||
|
||||
if (@available(macOS 13.0, *)) {
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 130000
|
||||
[sc->stream_properties setCapturesAudio:TRUE];
|
||||
[sc->stream_properties setExcludesCurrentProcessAudio:TRUE];
|
||||
[sc->stream_properties setChannelCount:2];
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
if (sc->capture_type != ScreenCaptureWindowStream) {
|
||||
sc->disp = NULL;
|
||||
os_event_init(&sc->disp_finished, OS_EVENT_TYPE_MANUAL);
|
||||
os_event_init(&sc->stream_start_completed,
|
||||
OS_EVENT_TYPE_MANUAL);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
sc->disp = [[SCStream alloc] initWithFilter:content_filter
|
||||
configuration:sc->stream_properties
|
||||
|
@ -491,7 +478,7 @@ static bool init_screen_stream(struct screen_capture *sc)
|
|||
}
|
||||
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 130000
|
||||
if (__builtin_available(macOS 13.0, *)) {
|
||||
if (@available(macOS 13.0, *)) {
|
||||
did_add_output = [sc->disp
|
||||
addStreamOutput:sc->capture_delegate
|
||||
type:SCStreamOutputTypeAudio
|
||||
|
@ -577,8 +564,8 @@ static void *screen_capture_create(obs_data_t *settings, obs_source_t *source)
|
|||
sc->show_empty_names = obs_data_get_bool(settings, "show_empty_names");
|
||||
sc->show_hidden_windows =
|
||||
obs_data_get_bool(settings, "show_hidden_windows");
|
||||
sc->window = obs_data_get_int(settings, "window");
|
||||
sc->capture_type = obs_data_get_int(settings, "type");
|
||||
sc->window = (CGWindowID)obs_data_get_int(settings, "window");
|
||||
sc->capture_type = (unsigned int)obs_data_get_int(settings, "type");
|
||||
|
||||
os_sem_init(&sc->shareable_content_available, 1);
|
||||
screen_capture_build_content_list(
|
||||
|
@ -591,7 +578,7 @@ static void *screen_capture_create(obs_data_t *settings, obs_source_t *source)
|
|||
if (!sc->effect)
|
||||
goto fail;
|
||||
|
||||
sc->display = obs_data_get_int(settings, "display");
|
||||
sc->display = (CGDirectDisplayID)obs_data_get_int(settings, "display");
|
||||
sc->application_id = [[NSString alloc]
|
||||
initWithUTF8String:obs_data_get_string(settings,
|
||||
"application")];
|
||||
|
@ -699,10 +686,11 @@ static void screen_capture_defaults(obs_data_t *settings)
|
|||
}
|
||||
}
|
||||
|
||||
obs_data_set_default_int(settings, "type", 0);
|
||||
obs_data_set_default_int(settings, "display", initial_display);
|
||||
obs_data_set_default_int(settings, "window", kCGNullWindowID);
|
||||
|
||||
obs_data_set_default_obj(settings, "application", NULL);
|
||||
obs_data_set_default_int(settings, "type", ScreenCaptureDisplayStream);
|
||||
obs_data_set_default_int(settings, "window", kCGNullWindowID);
|
||||
obs_data_set_default_bool(settings, "show_cursor", true);
|
||||
obs_data_set_default_bool(settings, "show_empty_names", false);
|
||||
obs_data_set_default_bool(settings, "show_hidden_windows", false);
|
||||
|
@ -713,7 +701,8 @@ static void screen_capture_update(void *data, obs_data_t *settings)
|
|||
struct screen_capture *sc = data;
|
||||
|
||||
CGWindowID old_window_id = sc->window;
|
||||
CGWindowID new_window_id = obs_data_get_int(settings, "window");
|
||||
CGWindowID new_window_id =
|
||||
(CGWindowID)obs_data_get_int(settings, "window");
|
||||
|
||||
if (new_window_id > 0 && new_window_id != old_window_id)
|
||||
sc->window = new_window_id;
|
||||
|
@ -766,6 +755,8 @@ static void screen_capture_update(void *data, obs_data_t *settings)
|
|||
obs_leave_graphics();
|
||||
}
|
||||
|
||||
#pragma mark - obs_properties
|
||||
|
||||
static bool build_display_list(struct screen_capture *sc,
|
||||
obs_properties_t *props)
|
||||
{
|
||||
|
@ -894,7 +885,8 @@ static bool content_settings_changed(void *data, obs_properties_t *props,
|
|||
{
|
||||
struct screen_capture *sc = data;
|
||||
|
||||
unsigned int capture_type_id = obs_data_get_int(settings, "type");
|
||||
unsigned int capture_type_id =
|
||||
(unsigned int)obs_data_get_int(settings, "type");
|
||||
obs_property_t *display_list = obs_properties_get(props, "display");
|
||||
obs_property_t *window_list = obs_properties_get(props, "window");
|
||||
obs_property_t *app_list = obs_properties_get(props, "application");
|
||||
|
@ -902,6 +894,9 @@ static bool content_settings_changed(void *data, obs_properties_t *props,
|
|||
obs_property_t *hidden =
|
||||
obs_properties_get(props, "show_hidden_windows");
|
||||
|
||||
obs_property_t *capture_type_error =
|
||||
obs_properties_get(props, "capture_type_info");
|
||||
|
||||
if (sc->capture_type != capture_type_id) {
|
||||
switch (capture_type_id) {
|
||||
case 0: {
|
||||
|
@ -910,6 +905,11 @@ static bool content_settings_changed(void *data, obs_properties_t *props,
|
|||
obs_property_set_visible(app_list, false);
|
||||
obs_property_set_visible(empty, false);
|
||||
obs_property_set_visible(hidden, false);
|
||||
|
||||
if (capture_type_error) {
|
||||
obs_property_set_visible(capture_type_error,
|
||||
true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
|
@ -918,6 +918,11 @@ static bool content_settings_changed(void *data, obs_properties_t *props,
|
|||
obs_property_set_visible(app_list, false);
|
||||
obs_property_set_visible(empty, true);
|
||||
obs_property_set_visible(hidden, true);
|
||||
|
||||
if (capture_type_error) {
|
||||
obs_property_set_visible(capture_type_error,
|
||||
false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
|
@ -926,21 +931,26 @@ static bool content_settings_changed(void *data, obs_properties_t *props,
|
|||
obs_property_set_visible(window_list, false);
|
||||
obs_property_set_visible(empty, false);
|
||||
obs_property_set_visible(hidden, true);
|
||||
|
||||
if (capture_type_error) {
|
||||
obs_property_set_visible(capture_type_error,
|
||||
true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sc->show_empty_names = obs_data_get_bool(settings, "show_empty_names");
|
||||
sc->show_hidden_windows =
|
||||
obs_data_get_bool(settings, "show_hidden_windows");
|
||||
|
||||
screen_capture_build_content_list(
|
||||
sc, capture_type_id == ScreenCaptureDisplayStream);
|
||||
build_display_list(sc, props);
|
||||
build_window_list(sc, props);
|
||||
build_application_list(sc, props);
|
||||
|
||||
sc->show_empty_names = obs_data_get_bool(settings, "show_empty_names");
|
||||
sc->show_hidden_windows =
|
||||
obs_data_get_bool(settings, "show_hidden_windows");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -949,9 +959,11 @@ static obs_properties_t *screen_capture_properties(void *data)
|
|||
struct screen_capture *sc = data;
|
||||
|
||||
obs_properties_t *props = obs_properties_create();
|
||||
|
||||
obs_property_t *capture_type = obs_properties_add_list(
|
||||
props, "type", obs_module_text("SCK.Method"),
|
||||
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
|
||||
|
||||
obs_property_list_add_int(capture_type,
|
||||
obs_module_text("DisplayCapture"), 0);
|
||||
obs_property_list_add_int(capture_type,
|
||||
|
@ -982,9 +994,6 @@ static obs_properties_t *screen_capture_properties(void *data)
|
|||
props, "show_hidden_windows",
|
||||
obs_module_text("WindowUtils.ShowHidden"));
|
||||
|
||||
obs_properties_add_bool(props, "show_cursor",
|
||||
obs_module_text("DisplayCapture.ShowCursor"));
|
||||
|
||||
if (sc) {
|
||||
obs_property_set_modified_callback2(
|
||||
hidden, content_settings_changed, sc);
|
||||
|
@ -1020,12 +1029,48 @@ static obs_properties_t *screen_capture_properties(void *data)
|
|||
empty, content_settings_changed, sc);
|
||||
}
|
||||
|
||||
obs_properties_add_bool(props, "show_cursor",
|
||||
obs_module_text("DisplayCapture.ShowCursor"));
|
||||
|
||||
if (@available(macOS 13.0, *))
|
||||
;
|
||||
else
|
||||
obs_properties_add_text(props, "audio_info",
|
||||
obs_module_text("SCK.AudioUnavailable"),
|
||||
OBS_TEXT_INFO);
|
||||
else {
|
||||
obs_property_t *audio_warning = obs_properties_add_text(
|
||||
props, "audio_info",
|
||||
obs_module_text("SCK.AudioUnavailable"), OBS_TEXT_INFO);
|
||||
obs_property_text_set_info_type(audio_warning,
|
||||
OBS_TEXT_INFO_WARNING);
|
||||
|
||||
obs_property_t *capture_type_error = obs_properties_add_text(
|
||||
props, "capture_type_info",
|
||||
obs_module_text("SCK.CaptureTypeUnavailable"),
|
||||
OBS_TEXT_INFO);
|
||||
|
||||
obs_property_text_set_info_type(capture_type_error,
|
||||
OBS_TEXT_INFO_ERROR);
|
||||
|
||||
if (sc) {
|
||||
switch (sc->capture_type) {
|
||||
case ScreenCaptureDisplayStream: {
|
||||
obs_property_set_visible(capture_type_error,
|
||||
true);
|
||||
break;
|
||||
}
|
||||
case ScreenCaptureWindowStream: {
|
||||
obs_property_set_visible(capture_type_error,
|
||||
false);
|
||||
break;
|
||||
}
|
||||
case ScreenCaptureApplicationStream: {
|
||||
obs_property_set_visible(capture_type_error,
|
||||
true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
obs_property_set_visible(capture_type_error, false);
|
||||
}
|
||||
}
|
||||
|
||||
return props;
|
||||
}
|
||||
|
@ -1053,6 +1098,8 @@ enum gs_color_space screen_capture_video_get_color_space(
|
|||
return GS_CS_SRGB_16F;
|
||||
}
|
||||
|
||||
#pragma mark - obs_source_info
|
||||
|
||||
struct obs_source_info screen_capture_info = {
|
||||
.id = "screen_capture",
|
||||
.type = OBS_SOURCE_TYPE_INPUT,
|
||||
|
@ -1077,6 +1124,8 @@ struct obs_source_info screen_capture_info = {
|
|||
.video_get_color_space = screen_capture_video_get_color_space,
|
||||
};
|
||||
|
||||
#pragma mark - ScreenCaptureDelegate
|
||||
|
||||
@implementation ScreenCaptureDelegate
|
||||
|
||||
- (void)stream:(SCStream *)stream
|
||||
|
|
Loading…
Reference in a new issue