[FFmpeg-devel] [PATCH] avdevice/avfoundation: fix macOS/iOS/tvOS SDK conditional checks
Marvin Scholz
epirat07 at gmail.com
Wed Apr 17 18:12:34 EEST 2024
This fixes the checks to properly use runtime feature detection and
check the SDK version (*_MAX_ALLOWED) instead of the targeted version
for the relevant APIs.
The target is still checked (*_MIN_REQUIRED) to avoid using deprecated
methods when targeting new enough versions.
---
libavdevice/avfoundation.m | 164 ++++++++++++++++++++++++++-----------
1 file changed, 116 insertions(+), 48 deletions(-)
diff --git a/libavdevice/avfoundation.m b/libavdevice/avfoundation.m
index e558ad7d90..a52e7df37b 100644
--- a/libavdevice/avfoundation.m
+++ b/libavdevice/avfoundation.m
@@ -28,6 +28,7 @@
#import <AVFoundation/AVFoundation.h>
#include <pthread.h>
+#include "libavutil/avassert.h"
#include "libavutil/channel_layout.h"
#include "libavutil/mem.h"
#include "libavutil/pixdesc.h"
@@ -764,57 +765,124 @@ static int get_audio_config(AVFormatContext *s)
}
static NSArray* getDevicesWithMediaType(AVMediaType mediaType) {
-#if ((TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000) || (TARGET_OS_OSX && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500))
- NSMutableArray *deviceTypes = nil;
- if (mediaType == AVMediaTypeVideo) {
- deviceTypes = [NSMutableArray arrayWithArray:@[AVCaptureDeviceTypeBuiltInWideAngleCamera]];
- #if (TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000)
- [deviceTypes addObject: AVCaptureDeviceTypeBuiltInDualCamera];
- [deviceTypes addObject: AVCaptureDeviceTypeBuiltInTelephotoCamera];
- #endif
- #if (TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110100)
- [deviceTypes addObject: AVCaptureDeviceTypeBuiltInTrueDepthCamera];
- #endif
- #if (TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 130000)
- [deviceTypes addObject: AVCaptureDeviceTypeBuiltInTripleCamera];
- [deviceTypes addObject: AVCaptureDeviceTypeBuiltInDualWideCamera];
- [deviceTypes addObject: AVCaptureDeviceTypeBuiltInUltraWideCamera];
- #endif
- #if (TARGET_OS_OSX && __MAC_OS_X_VERSION_MIN_REQUIRED >= 130000)
- [deviceTypes addObject: AVCaptureDeviceTypeDeskViewCamera];
- #endif
- #if (TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 150400)
- [deviceTypes addObject: AVCaptureDeviceTypeBuiltInLiDARDepthCamera];
- #endif
- #if (TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 170000 || (TARGET_OS_OSX && __MAC_OS_X_VERSION_MIN_REQUIRED >= 140000))
- [deviceTypes addObject: AVCaptureDeviceTypeContinuityCamera];
- #endif
- } else if (mediaType == AVMediaTypeAudio) {
- #if (TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 170000 || (TARGET_OS_OSX && __MAC_OS_X_VERSION_MIN_REQUIRED >= 140000))
- deviceTypes = [NSMutableArray arrayWithArray:@[AVCaptureDeviceTypeMicrophone]];
- #else
- deviceTypes = [NSMutableArray arrayWithArray:@[AVCaptureDeviceTypeBuiltInMicrophone]];
- #endif
- } else if (mediaType == AVMediaTypeMuxed) {
- #if (TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 170000 || (TARGET_OS_OSX && __MAC_OS_X_VERSION_MIN_REQUIRED >= 140000))
- deviceTypes = [NSMutableArray arrayWithArray:@[AVCaptureDeviceTypeExternal]];
- #elif (TARGET_OS_OSX && __MAC_OS_X_VERSION_MIN_REQUIRED < 140000)
- deviceTypes = [NSMutableArray arrayWithArray:@[AVCaptureDeviceTypeExternalUnknown]];
- #else
+
+#if (TARGET_OS_OSX && defined(__MAC_10_15) && MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_15) || \
+ (TARGET_OS_IOS && defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0) || \
+ (TARGET_OS_TV && defined(__TVOS_17_0) && __TV_OS_VERSION_MAX_ALLOWED >= __TVOS_17_0)
+ if (__builtin_available(macOS 10.15, iOS 10, tvOS 17, *)) {
+
+ NSMutableArray *deviceTypes = nil;
+
+ if (mediaType == AVMediaTypeVideo) {
+ deviceTypes = [NSMutableArray arrayWithArray:@[AVCaptureDeviceTypeBuiltInWideAngleCamera]];
+
+ #if (TARGET_OS_IOS || TARGET_OS_TV)
+ // Devices only available on iOS/tvOS
+ [deviceTypes addObject: AVCaptureDeviceTypeBuiltInDualCamera];
+ [deviceTypes addObject: AVCaptureDeviceTypeBuiltInTelephotoCamera];
+
+ #if (TARGET_OS_IOS && defined(__IPHONE_11_1) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_1) || \
+ (TARGET_OS_TV && defined(__TVOS_17_0) && __TV_OS_VERSION_MAX_ALLOWED >= __TVOS_17_0)
+ if (__builtin_available(iOS 11.1, tvOS 17, *)) {
+ [deviceTypes addObject: AVCaptureDeviceTypeBuiltInTrueDepthCamera];
+ }
+ #endif
+
+ #if (TARGET_OS_IOS && defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0) || \
+ (TARGET_OS_TV && defined(__TVOS_17_0) && __TV_OS_VERSION_MAX_ALLOWED >= __TVOS_17_0)
+ if (__builtin_available(iOS 13.0, tvOS 17, *)) {
+ [deviceTypes addObject: AVCaptureDeviceTypeBuiltInTripleCamera];
+ [deviceTypes addObject: AVCaptureDeviceTypeBuiltInDualWideCamera];
+ [deviceTypes addObject: AVCaptureDeviceTypeBuiltInUltraWideCamera];
+ }
+ #endif
+
+ #if (TARGET_OS_IOS && defined(__IPHONE_15_4) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_15_4) || \
+ (TARGET_OS_TV && defined(__TVOS_17_0) && __TV_OS_VERSION_MAX_ALLOWED >= __TVOS_17_0)
+ if (__builtin_available(iOS 15.4, tvOS 17, *)) {
+ [deviceTypes addObject: AVCaptureDeviceTypeBuiltInLiDARDepthCamera];
+ }
+ #endif
+ #endif
+
+ #if (TARGET_OS_OSX && defined(__MAC_13_0) && MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_13_0)
+ if (__builtin_available(macOS 13.0, *)) {
+ [deviceTypes addObject: AVCaptureDeviceTypeDeskViewCamera];
+ }
+ #endif
+
+ #if (TARGET_OS_OSX && defined(__MAC_14_0) && MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_14_0) || \
+ (TARGET_OS_IOS && defined(__IPHONE_17_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_17_0) || \
+ (TARGET_OS_TV && defined(__TVOS_17_0) && __TV_OS_VERSION_MAX_ALLOWED >= __TVOS_17_0)
+ if (__builtin_available(macOS 14.0, iOS 17, tvOS 17, *)) {
+ [deviceTypes addObject: AVCaptureDeviceTypeContinuityCamera];
+ }
+ #endif
+
+ } else if (mediaType == AVMediaTypeAudio) {
+ #if (TARGET_OS_OSX && defined(__MAC_14_0) && MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_14_0) || \
+ (TARGET_OS_IOS && defined(__IPHONE_17_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_17_0) || \
+ (TARGET_OS_TV && defined(__TVOS_17_0) && __TV_OS_VERSION_MAX_ALLOWED >= __TVOS_17_0)
+ if (__builtin_available(macOS 14.0, iOS 17, tvOS 17, *)) {
+ deviceTypes = [NSMutableArray arrayWithArray:@[AVCaptureDeviceTypeMicrophone]];
+ } else
+ #endif
+ {
+ #if (TARGET_OS_OSX && defined(__MAC_14_0) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_14_0) || \
+ (TARGET_OS_IOS && defined(__IPHONE_17_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_17_0) || \
+ (TARGET_OS_TV && defined(__TVOS_17_0) && __TV_OS_VERSION_MIN_REQUIRED >= __TVOS_17_0)
+ /* If the targeted macOS is new enough, this fallback case can never be reached, so do not
+ * use a deprecated API to avoid compiler warnings.
+ */
+ av_assert0(!"Unreachable reached!");
+ #else
+ deviceTypes = [NSMutableArray arrayWithArray:@[AVCaptureDeviceTypeBuiltInMicrophone]];
+ #endif
+ }
+ } else if (mediaType == AVMediaTypeMuxed) {
+ #if (TARGET_OS_OSX && defined(__MAC_14_0) && MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_14_0) || \
+ (TARGET_OS_IOS && defined(__IPHONE_17_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_17_0) || \
+ (TARGET_OS_TV && defined(__TVOS_17_0) && __TV_OS_VERSION_MAX_ALLOWED >= __TVOS_17_0)
+ if (__builtin_available(macOS 14.0, iOS 17, tvOS 17, *)) {
+ deviceTypes = [NSMutableArray arrayWithArray:@[AVCaptureDeviceTypeExternal]];
+ } else
+ #endif
+ #if (TARGET_OS_OSX && defined(__MAC_14_0) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_14_0)
+ // macOS 10.15+ already guaranteed here by previous check
+ {
+ deviceTypes = [NSMutableArray arrayWithArray:@[AVCaptureDeviceTypeExternalUnknown]];
+ }
+ #else
+ {
+ return nil;
+ }
+ #endif
+ } else {
return nil;
- #endif
- } else {
- return nil;
- }
+ }
+
+ AVCaptureDeviceDiscoverySession *captureDeviceDiscoverySession =
+ [AVCaptureDeviceDiscoverySession
+ discoverySessionWithDeviceTypes:deviceTypes
+ mediaType:mediaType
+ position:AVCaptureDevicePositionUnspecified];
+ return [captureDeviceDiscoverySession devices];
+ } else
+#endif
- AVCaptureDeviceDiscoverySession *captureDeviceDiscoverySession =
- [AVCaptureDeviceDiscoverySession
- discoverySessionWithDeviceTypes:deviceTypes
- mediaType:mediaType
- position:AVCaptureDevicePositionUnspecified];
- return [captureDeviceDiscoverySession devices];
+#if (TARGET_OS_OSX && defined(__MAC_10_15) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_15) || \
+ (TARGET_OS_IOS && defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_10_0) || \
+ (TARGET_OS_TV && defined(__TVOS_17_0) && __TV_OS_VERSION_MIN_REQUIRED >= __TVOS_17_0)
+ {
+ /* If the targeted macOS is new enough, this fallback case can never be reached, so do not
+ * use a deprecated API to avoid compiler warnings.
+ */
+ av_assert0(!"Unreachable reached!");
+ }
#else
- return [AVCaptureDevice devicesWithMediaType:mediaType];
+ {
+ return [AVCaptureDevice devicesWithMediaType:mediaType];
+ }
#endif
}
base-commit: 257bc2a82ab6709ddfc8dd9cf570beefcef7d43f
--
2.39.3 (Apple Git-145)
More information about the ffmpeg-devel
mailing list