diff options
author | Lauri Laanmets <lauri@laanmets.ee> | 2024-01-23 10:27:44 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2024-03-06 18:34:59 +0000 |
commit | 5da455d8f70080d4f2468da43899060f6d97daf3 (patch) | |
tree | 48666723a1f093b3d3326326200ae08d865357f5 | |
parent | c33e6f69b0ebe8c1f66bf454150273380fd96aaa (diff) |
Support multi-lens (dual, triple) logical cameras on Apple devices
Use 'AVCaptureDeviceDiscoverySession' to discover all multi-lens camera
types that automatically switch between lenses.
Use [AVCaptureDevice defaultDeviceWithDeviceType] to try to find most
"powerful" camera type as default.
Pick-to: 6.6 6.5 6.2
Task-number: QTBUG-121422
Change-Id: I04aa9a64ee459359d117b928baaaf0970df7ce21
Reviewed-by: Artem Dyomin <artem.dyomin@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
(cherry picked from commit 681b93eb85c5460d2415960c6fba21cb0281cd64)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/plugins/multimedia/darwin/camera/qavfcamerabase.mm | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/src/plugins/multimedia/darwin/camera/qavfcamerabase.mm b/src/plugins/multimedia/darwin/camera/qavfcamerabase.mm index 15c79d544..9d99de0b9 100644 --- a/src/plugins/multimedia/darwin/camera/qavfcamerabase.mm +++ b/src/plugins/multimedia/darwin/camera/qavfcamerabase.mm @@ -8,6 +8,7 @@ #include "qavfhelpers_p.h" #include <private/qplatformmediaintegration_p.h> #include <QtCore/qset.h> +#include <QtCore/qsystemdetection.h> QT_USE_NAMESPACE @@ -137,12 +138,57 @@ void QAVFVideoDevices::updateCameraDevices() QList<QCameraDevice> cameras; - AVCaptureDevice *defaultDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; - NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; + // List of all capture device types that we want to discover. Seems that this is the + // only way to discover all types. This filter is mandatory and has no "unspecified" + // option like AVCaptureDevicePosition(Unspecified) has. Order of the list is important + // because discovered devices will be in the same order and we want the first one found + // to be our default device. + NSArray *discoveryDevices = @[ +#ifdef Q_OS_IOS + AVCaptureDeviceTypeBuiltInTripleCamera, // We always prefer triple camera. + AVCaptureDeviceTypeBuiltInDualCamera, // If triple is not available, we prefer + // dual with wide + tele lens. + AVCaptureDeviceTypeBuiltInDualWideCamera, // Dual with wide and ultrawide is still + // better than single. +#endif + AVCaptureDeviceTypeBuiltInWideAngleCamera, // This is the most common single camera type. + // We prefer that over tele and ultra-wide. +#ifdef Q_OS_IOS + AVCaptureDeviceTypeBuiltInTelephotoCamera, // Cannot imagine how, but if only tele and + // ultrawide are available, we prefer tele. + AVCaptureDeviceTypeBuiltInUltraWideCamera, +#endif + ]; + +#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_14_0, __IPHONE_17_0, __TVOS_NA, __WATCHOS_NA) + if (@available(macOS 14, iOS 17, *)) { + discoveryDevices = [discoveryDevices arrayByAddingObjectsFromArray: @[ + AVCaptureDeviceTypeExternal, + AVCaptureDeviceTypeContinuityCamera + ]]; + } else +#endif + { +#ifdef Q_OS_MACOS + QT_WARNING_PUSH + QT_WARNING_DISABLE_DEPRECATED + discoveryDevices = [discoveryDevices arrayByAddingObjectsFromArray: @[ + AVCaptureDeviceTypeExternalUnknown + ]]; + QT_WARNING_POP +#endif + } + // Create discovery session to discover all possible camera types of the system. + // Both "hard" and "soft" types. + AVCaptureDeviceDiscoverySession *discoverySession = [AVCaptureDeviceDiscoverySession + discoverySessionWithDeviceTypes:discoveryDevices + mediaType:AVMediaTypeVideo + position:AVCaptureDevicePositionUnspecified]; + NSArray<AVCaptureDevice *> *videoDevices = discoverySession.devices; for (AVCaptureDevice *device in videoDevices) { auto info = std::make_unique<QCameraDevicePrivate>(); - if (defaultDevice && [defaultDevice.uniqueID isEqualToString:device.uniqueID]) + if ([videoDevices[0].uniqueID isEqualToString:device.uniqueID]) info->isDefault = true; info->id = QByteArray([[device uniqueID] UTF8String]); info->description = QString::fromNSString([device localizedName]); |