* [FFmpeg-devel] [PATCH] avdevice/avfoundation: fix macOS/iOS/tvOS SDK conditional checks
@ 2024-04-17 15:12 Marvin Scholz
2024-04-17 16:04 ` Thilo Borgmann via ffmpeg-devel
2024-04-24 10:39 ` Martin Storsjö
0 siblings, 2 replies; 3+ messages in thread
From: Marvin Scholz @ 2024-04-17 15:12 UTC (permalink / raw)
To: ffmpeg-devel
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)
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [FFmpeg-devel] [PATCH] avdevice/avfoundation: fix macOS/iOS/tvOS SDK conditional checks
2024-04-17 15:12 [FFmpeg-devel] [PATCH] avdevice/avfoundation: fix macOS/iOS/tvOS SDK conditional checks Marvin Scholz
@ 2024-04-17 16:04 ` Thilo Borgmann via ffmpeg-devel
2024-04-24 10:39 ` Martin Storsjö
1 sibling, 0 replies; 3+ messages in thread
From: Thilo Borgmann via ffmpeg-devel @ 2024-04-17 16:04 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Thilo Borgmann
Hi,
On 17.04.24 17:12, Marvin Scholz wrote:
> 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(-)
this is probably the extension to what we started at FOSDEM, right?
LGTM if tested. Please apply, I can't in the next couple of days.
Thanks,
Thilo
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [FFmpeg-devel] [PATCH] avdevice/avfoundation: fix macOS/iOS/tvOS SDK conditional checks
2024-04-17 15:12 [FFmpeg-devel] [PATCH] avdevice/avfoundation: fix macOS/iOS/tvOS SDK conditional checks Marvin Scholz
2024-04-17 16:04 ` Thilo Borgmann via ffmpeg-devel
@ 2024-04-24 10:39 ` Martin Storsjö
1 sibling, 0 replies; 3+ messages in thread
From: Martin Storsjö @ 2024-04-24 10:39 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Wed, 17 Apr 2024, Marvin Scholz wrote:
> 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.
As these things are pretty hard to think straight about, it could be good
with a more concrete example of what this achieves. I.e. if building with
-mmacosx-version-min=10.13, we can still use the macOS 10.15 specific
APIs, if they were available at build time, via the runtime check.
>
> 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(-)
The diff is pretty hard to read as is, but when applied and viewed with
"git show -w", it becomes clearer.
The changes from TARGET_OS_IPHONE to TARGET_OS_IOS is pretty subtle, iirc
TARGET_OS_IPHONE was any non-desktop platform (ios/tvos/watchos etc),
while TARGET_OS_IOS specifically is iOS. The change looks right, but it
might be good to spell this out as well.
Specifically also, that TARGET_OS_IPHONE covers a whole class of OSes,
while TARGET_OS_IOS is one OS - but the version defines for that OS are
__IPHONE_OS_VERSION_MIN_REQUIRED and __IPHONE_OS_VERSION_MAX_ALLOWED.
> + /* 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.
> + */
This sentence gets somewhat warped up at some point, so I don't think it
exactly means and is understandable as you meant it.
What about this:
If the targeted macOS is new enough, use of older APIs will cause
deprecation warnings. Due to the availability check, we actually
won't ever execute the code in such builds, but the compiler will
still warn about it, unless we actually ifdef out the reference.
Outside of what the patch does, I see the existing file uses this
construct in a few places:
#if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
I think it would seem more consistent to update this to use TARGET_OS_OSX
instead of negating TARGET_OS_IPHONE - or is there something I'm missing?
As for alternative ways of doing this, that would be less unwieldy - I
have something like this in mind:
#define SDK_AT_LEAST(macos, ios, tvos) \
(TARGET_OS_OSX && MAC_OS_X_VERSION_MAX_ALLOWED >= macos) || \
(TARGET_OS_IOS && __IPHONE_OS_VERSION_MAX_ALLOWED >= ios) || \
(TARGET_OS_TV && __TV_OS_VERSION_MAX_ALLOWED >= tvos)
#if SDK_AT_LEAST(__MAC_10_15, __IPHONE_10_0, __TVOS_17_0)
We could add similar macros for both SDK_AT_LEAST and
TARGET_VERSION_AT_LEAST, and variants for different combinations of
macos/ios/tvos for when we don't want to specify all of them.
We can't use defined(macos) etc within this context though, so if we want
to go this way, we'd need to start out with ifdefs for all the defines we
use, like this:
#ifndef __MAC_10_15
#define __MAC_10_15 <constant value>
#endif
There's of course a bit of fragility here, we need to make sure that we
actually copypaste the exact right value here. But on the other hand, we
even could make it intentionally something else, e.g. like this:
#ifndef __MAC_10_15
// If the SDK doesn't define this constant, the SDK doesn't support this
version anyway, and we won't end up selecting it, so just use a dummy
value instead.
#define __MAC_10_15 99999999
#endif
What do you think, does any of that seem like it would make the code more
manageable?
// Martin
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2024-04-24 10:39 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-17 15:12 [FFmpeg-devel] [PATCH] avdevice/avfoundation: fix macOS/iOS/tvOS SDK conditional checks Marvin Scholz
2024-04-17 16:04 ` Thilo Borgmann via ffmpeg-devel
2024-04-24 10:39 ` Martin Storsjö
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git