effects warning returns NSString, change comparator args

This commit is contained in:
jcm 2024-06-23 08:56:04 -05:00
parent 9aeb2444cf
commit 57f097481d
3 changed files with 51 additions and 44 deletions

View file

@ -15,7 +15,6 @@
#import <obs.h> #import <obs.h>
#import <pthread.h> #import <pthread.h>
#import <media-io/video-io.h> #import <media-io/video-io.h>
#import <obs-module.h>
#pragma mark - Type aliases and type definitions #pragma mark - Type aliases and type definitions
@ -163,10 +162,10 @@ typedef struct av_capture_info {
/// - Returns: New [NSString](https://developer.apple.com/documentation/foundation/nsstring?language=objc) instance created from user setting if setting represented a valid C character pointer. /// - Returns: New [NSString](https://developer.apple.com/documentation/foundation/nsstring?language=objc) instance created from user setting if setting represented a valid C character pointer.
+ (NSString *)stringFromSettings:(void *)settings withSetting:(NSString *)setting withDefault:(NSString *)defaultValue; + (NSString *)stringFromSettings:(void *)settings withSetting:(NSString *)setting withDefault:(NSString *)defaultValue;
/// Generates a localized warning C string for display in the properties window concerning macOS system effects that are active on a particular `AVCaptureDevice`. /// Generates an NSString representing the name of the warning to display in the properties window for macOS system effects that are active on a particular `AVCaptureDevice`.
/// - Parameter device: The [AVCaptureDevice](https://developer.apple.com/documentation/avfoundation/avcapturedevice?language=objc) to generate an effects warning string for. /// - Parameter device: The [AVCaptureDevice](https://developer.apple.com/documentation/avfoundation/avcapturedevice?language=objc) to generate an effects warning string for.
/// - Returns: C string containing the localized warning to display to the user. /// - Returns: `nil` if there are no effects active on the device. If effects are found, returns a new [NSString](https://developer.apple.com/documentation/foundation/nsstring?language=objc) instance containing the `libobs` key used to retrieve the appropriate localized warning string.
+ (const char *)effectsWarningForDevice:(AVCaptureDevice *)device; + (NSString *)effectsWarningForDevice:(AVCaptureDevice *)device;
#pragma mark - Format Conversion Helpers #pragma mark - Format Conversion Helpers
@ -352,35 +351,35 @@ typedef struct av_capture_info {
/// Compare two `AVCaptureDeviceFormat`s for purposes of sorting in the properties window. /// Compare two `AVCaptureDeviceFormat`s for purposes of sorting in the properties window.
static NSComparator const OBSAVCaptureDeviceFormatCompare = static NSComparator const OBSAVCaptureDeviceFormatCompare =
^NSComparisonResult(AVCaptureDeviceFormat *a, AVCaptureDeviceFormat *b) { ^NSComparisonResult(AVCaptureDeviceFormat *lhs, AVCaptureDeviceFormat *rhs) {
CMVideoDimensions aDimensions = CMVideoFormatDescriptionGetDimensions(a.formatDescription); CMVideoDimensions lhsDimensions = CMVideoFormatDescriptionGetDimensions(lhs.formatDescription);
CMVideoDimensions bDimensions = CMVideoFormatDescriptionGetDimensions(b.formatDescription); CMVideoDimensions rhsDimensions = CMVideoFormatDescriptionGetDimensions(rhs.formatDescription);
NSNumber *aWidth = @(aDimensions.width); NSNumber *lhsWidth = @(lhsDimensions.width);
NSNumber *bWidth = @(bDimensions.width); NSNumber *rhsWidth = @(rhsDimensions.width);
NSNumber *aHeight = @(aDimensions.height); NSNumber *lhsHeight = @(lhsDimensions.height);
NSNumber *bHeight = @(bDimensions.height); NSNumber *rhsHeight = @(rhsDimensions.height);
NSNumber *aArea = @(aDimensions.width * aDimensions.height); NSNumber *lhsArea = @(lhsDimensions.width * lhsDimensions.height);
NSNumber *bArea = @(bDimensions.width * bDimensions.height); NSNumber *rhsArea = @(rhsDimensions.width * rhsDimensions.height);
NSNumber *aMaxFrameRate = @(a.videoSupportedFrameRateRanges.firstObject.maxFrameRate); NSNumber *lhsMaxFrameRate = @(lhs.videoSupportedFrameRateRanges.firstObject.maxFrameRate);
NSNumber *bMaxFrameRate = @(b.videoSupportedFrameRateRanges.firstObject.maxFrameRate); NSNumber *rhsMaxFrameRate = @(rhs.videoSupportedFrameRateRanges.firstObject.maxFrameRate);
NSNumber *aFourCC = @(CMFormatDescriptionGetMediaSubType(a.formatDescription)); NSNumber *lhsFourCC = @(CMFormatDescriptionGetMediaSubType(lhs.formatDescription));
NSNumber *bFourCC = @(CMFormatDescriptionGetMediaSubType(b.formatDescription)); NSNumber *rhsFourCC = @(CMFormatDescriptionGetMediaSubType(rhs.formatDescription));
NSNumber *aColorSpace = @([OBSAVCapture colorspaceFromDescription:a.formatDescription]); NSNumber *lhsColorSpace = @([OBSAVCapture colorspaceFromDescription:lhs.formatDescription]);
NSNumber *bColorSpace = @([OBSAVCapture colorspaceFromDescription:b.formatDescription]); NSNumber *rhsColorSpace = @([OBSAVCapture colorspaceFromDescription:rhs.formatDescription]);
NSComparisonResult result; NSComparisonResult result;
result = [aWidth compare:bWidth]; result = [lhsWidth compare:rhsWidth];
if (result == NSOrderedSame) { if (result == NSOrderedSame) {
result = [aArea compare:bArea]; result = [lhsArea compare:rhsArea];
if (result == NSOrderedSame) { if (result == NSOrderedSame) {
result = [aHeight compare:bHeight]; result = [lhsHeight compare:rhsHeight];
if (result == NSOrderedSame) { if (result == NSOrderedSame) {
result = [aMaxFrameRate compare:bMaxFrameRate]; result = [lhsMaxFrameRate compare:rhsMaxFrameRate];
if (result == NSOrderedSame) { if (result == NSOrderedSame) {
result = [aFourCC compare:bFourCC]; result = [lhsFourCC compare:rhsFourCC];
if (result == NSOrderedSame) { if (result == NSOrderedSame) {
result = [aColorSpace compare:bColorSpace]; result = [lhsColorSpace compare:rhsColorSpace];
} }
} }
} }

View file

@ -628,46 +628,46 @@
return result; return result;
} }
+ (const char *)effectsWarningForDevice:(AVCaptureDevice *)device + (NSString *)effectsWarningForDevice:(AVCaptureDevice *)device
{ {
int effectsCount = 0; int effectsCount = 0;
const char *effectWarning = ""; NSString *effectWarning = nil;
if (@available(macOS 12.0, *)) { if (@available(macOS 12.0, *)) {
if (device.portraitEffectActive) { if (device.portraitEffectActive) {
effectWarning = obs_module_text("PortraitEffectWarning"); effectWarning = @"PortraitEffectWarning";
effectsCount++; effectsCount++;
} }
} }
if (@available(macOS 12.3, *)) { if (@available(macOS 12.3, *)) {
if (device.centerStageActive) { if (device.centerStageActive) {
effectWarning = obs_module_text("CenterStageWarning"); effectWarning = @"CenterStageWarning";
effectsCount++; effectsCount++;
} }
} }
if (@available(macOS 13.0, *)) { if (@available(macOS 13.0, *)) {
if (device.studioLightActive) { if (device.studioLightActive) {
effectWarning = obs_module_text("StudioLightWarning"); effectWarning = @"StudioLightWarning";
effectsCount++; effectsCount++;
} }
} }
/* This property is currently unavailable due to an SDK issue: FB13948132 /* This property is currently unavailable due to an SDK issue: FB13948132
if (@available(macOS 14.0, *)) { if (@available(macOS 14.0, *)) {
if (device.reactionEffectGesturesEnabled) { if (device.reactionEffectGesturesEnabled) {
effectWarning = obs_module_text("ReactionsWarning"); effectWarning = @"ReactionsWarning";
effectsCount++; effectsCount++;
} }
} }
*/ */
/* Not available until we are building on Xcode 16. Is there a way to check SDK availability? #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 150000
if (@available(macOS 15.0, *)) { if (@available(macOS 15.0, *)) {
if (device.backgroundReplacementActive) { if (device.backgroundReplacementActive) {
effectWarning = obs_module_text("BackgroundReplacementWarning"); effectWarning = @"BackgroundReplacementWarning";
effectsCount++; effectsCount++;
} }
} }
*/ #endif
if (effectsCount > 1) { if (effectsCount > 1) {
effectWarning = obs_module_text("MultipleEffectsWarning"); effectWarning = @"MultipleEffectsWarning";
} }
return effectWarning; return effectWarning;
} }

View file

@ -80,23 +80,30 @@ static obs_properties_t *av_capture_properties(void *av_capture)
OBSAVCapture *capture = (__bridge OBSAVCapture *) (av_capture); OBSAVCapture *capture = (__bridge OBSAVCapture *) (av_capture);
OBSAVCaptureInfo *capture_info = capture.captureInfo; OBSAVCaptureInfo *capture_info = capture.captureInfo;
AVCaptureDevice *device = capture.deviceInput.device; AVCaptureDevice *device = capture.deviceInput.device;
const char *effects_warning_string = [OBSAVCapture effectsWarningForDevice:device]; NSString *effectsWarningKey = [OBSAVCapture effectsWarningForDevice:device];
bool has_effects = effects_warning_string[0] != '\0'; bool has_effects = effectsWarningKey != nil;
const char *effects_warning_string;
if (has_effects) {
effects_warning_string = obs_module_text(effectsWarningKey.UTF8String);
}
obs_properties_t *properties = obs_properties_create(); obs_properties_t *properties = obs_properties_create();
// Create Properties // Create Properties
obs_property_t *device_list = obs_properties_add_list(properties, "device", obs_module_text("Device"), obs_property_t *device_list = obs_properties_add_list(properties, "device", obs_module_text("Device"),
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
obs_property_t *effects_warning =
obs_properties_add_text(properties, "effects_warning", effects_warning_string, OBS_TEXT_INFO); obs_property_t *effects_warning;
if (has_effects) {
effects_warning = obs_properties_add_text(properties, "effects_warning", effects_warning_string, OBS_TEXT_INFO);
obs_property_text_set_info_type(effects_warning, OBS_TEXT_INFO_WARNING); obs_property_text_set_info_type(effects_warning, OBS_TEXT_INFO_WARNING);
}
obs_property_t *use_preset = obs_properties_add_bool(properties, "use_preset", obs_module_text("UsePreset")); obs_property_t *use_preset = obs_properties_add_bool(properties, "use_preset", obs_module_text("UsePreset"));
obs_property_t *preset_list = obs_properties_add_list(properties, "preset", obs_module_text("Preset"), obs_property_t *preset_list = obs_properties_add_list(properties, "preset", obs_module_text("Preset"),
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
obs_property_t *supported_formats = obs_property_t *supported_formats = obs_properties_add_list(
obs_properties_add_list(properties, "supported_format", "Format", OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); properties, "supported_format", obs_module_text("InputFormat"), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
obs_property_t *use_buffering = obs_properties_add_bool(properties, "buffering", obs_module_text("Buffering")); obs_property_t *use_buffering = obs_properties_add_bool(properties, "buffering", obs_module_text("Buffering"));
obs_property_t *frame_rates = obs_properties_add_frame_rate(properties, "frame_rate", obs_module_text("FrameRate")); obs_property_t *frame_rates = obs_properties_add_frame_rate(properties, "frame_rate", obs_module_text("FrameRate"));
@ -105,8 +112,9 @@ static obs_properties_t *av_capture_properties(void *av_capture)
// Add Property Visibility and Callbacks // Add Property Visibility and Callbacks
configure_property(device_list, true, true, properties_changed, capture); configure_property(device_list, true, true, properties_changed, capture);
//todo fix if (has_effects) {
configure_property(effects_warning, true, has_effects, NULL, NULL); configure_property(effects_warning, true, has_effects, NULL, NULL);
}
configure_property(use_preset, !isFastPath, !isFastPath, (!isFastPath) ? properties_changed_use_preset : NULL, configure_property(use_preset, !isFastPath, !isFastPath, (!isFastPath) ? properties_changed_use_preset : NULL,
capture); capture);