summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtem Dyomin <artem.dyomin@qt.io>2022-11-11 10:17:59 +0100
committerArtem Dyomin <artem.dyomin@qt.io>2022-11-14 12:25:38 +0000
commit3530d4bcfeee6f1c1b123ce53a4c9d4a219d0c71 (patch)
treeb2787be1a33dbfc2091f7b1e3f2eaa0147a1815e
parent1efc666fcf1d920da9257e5a4022be546f1ce175 (diff)
downloadqtmultimedia-3530d4bcfeee6f1c1b123ce53a4c9d4a219d0c71.tar.gz
Fix crash on macos13 with iphone camera
On macos13 new feature has been introduced: possibility using a camera of paired iphone on macos. The feature works but it's a bit buggy: AVCaptureDevice.hasFlash is true but none of flash modes is supported. Setting of not supported flash mode causes exception. The exeptions happens when setting AVCaptureFlashModeOff, but, in theory, it can occur in other corner cases. Documentation recommentds to check if flash mode supported in order to avoid exceptions. So, what's done: - checking of supported flash and torch modes before setting - use captureDevice.isFlashAvailable not only for mac os since ios camera can be paired Task-number: QTBUG-108018 Change-Id: I42772edb4c26481283d1bd321914bf40284efde9 Reviewed-by: Lars Knoll <lars@knoll.priv.no> (cherry picked from commit 7d9713412ba3db914f984be16aeba6be820d68a4)
-rw-r--r--src/plugins/multimedia/darwin/camera/qavfcamerabase.mm77
1 files changed, 51 insertions, 26 deletions
diff --git a/src/plugins/multimedia/darwin/camera/qavfcamerabase.mm b/src/plugins/multimedia/darwin/camera/qavfcamerabase.mm
index b40c1133e..993594814 100644
--- a/src/plugins/multimedia/darwin/camera/qavfcamerabase.mm
+++ b/src/plugins/multimedia/darwin/camera/qavfcamerabase.mm
@@ -92,6 +92,22 @@ bool qt_convert_exposure_mode(AVCaptureDevice *captureDevice, QCamera::ExposureM
#endif // defined(Q_OS_IOS)
+bool isFlashAvailable(AVCaptureDevice* captureDevice) {
+ if (@available(macOS 10.15, *)) {
+ return [captureDevice isFlashAvailable];
+ }
+
+ return true;
+}
+
+bool isTorchAvailable(AVCaptureDevice* captureDevice) {
+ if (@available(macOS 10.15, *)) {
+ return [captureDevice isTorchAvailable];
+ }
+
+ return true;
+}
+
} // Unnamed namespace.
@@ -630,14 +646,10 @@ bool QAVFCameraBase::isFlashReady() const
if (!isFlashModeSupported(flashMode()))
return false;
-#ifdef Q_OS_IOS
// AVCaptureDevice's docs:
// "The flash may become unavailable if, for example,
// the device overheats and needs to cool off."
- return [captureDevice isFlashAvailable];
-#endif
-
- return true;
+ return isFlashAvailable(captureDevice);
}
void QAVFCameraBase::setTorchMode(QCamera::TorchMode mode)
@@ -727,42 +739,55 @@ void QAVFCameraBase::applyFlashSettings()
return;
}
-
const AVFConfigurationLock lock(captureDevice);
if (captureDevice.hasFlash) {
- auto mode = flashMode();
+ const auto mode = flashMode();
+
+ auto setAvFlashModeSafe = [&captureDevice](AVCaptureFlashMode avFlashMode) {
+ // Note, in some cases captureDevice.hasFlash == false even though
+ // no there're no supported flash modes.
+ if ([captureDevice isFlashModeSupported:avFlashMode])
+ captureDevice.flashMode = avFlashMode;
+ else
+ qCDebug(qLcCamera) << "Attempt to setup unsupported flash mode " << avFlashMode;
+ };
+
if (mode == QCamera::FlashOff) {
- captureDevice.flashMode = AVCaptureFlashModeOff;
+ setAvFlashModeSafe(AVCaptureFlashModeOff);
} else {
-#ifdef Q_OS_IOS
- if (![captureDevice isFlashAvailable]) {
+ if (isFlashAvailable(captureDevice)) {
+ if (mode == QCamera::FlashOn)
+ setAvFlashModeSafe(AVCaptureFlashModeOn);
+ else if (mode == QCamera::FlashAuto)
+ setAvFlashModeSafe(AVCaptureFlashModeAuto);
+ } else {
qCDebug(qLcCamera) << Q_FUNC_INFO << "flash is not available at the moment";
- return;
}
-#endif
- if (mode == QCamera::FlashOn)
- captureDevice.flashMode = AVCaptureFlashModeOn;
- else if (mode == QCamera::FlashAuto)
- captureDevice.flashMode = AVCaptureFlashModeAuto;
}
}
if (captureDevice.hasTorch) {
- auto mode = torchMode();
+ const auto mode = torchMode();
+
+ auto setAvTorchModeSafe = [&captureDevice](AVCaptureTorchMode avTorchMode) {
+ if ([captureDevice isTorchModeSupported:avTorchMode])
+ captureDevice.torchMode = avTorchMode;
+ else
+ qCDebug(qLcCamera) << "Attempt to setup unsupported torch mode " << avTorchMode;
+ };
+
if (mode == QCamera::TorchOff) {
- captureDevice.torchMode = AVCaptureTorchModeOff;
+ setAvTorchModeSafe(AVCaptureTorchModeOff);
} else {
-#ifdef Q_OS_IOS
- if (![captureDevice isTorchAvailable]) {
+ if (isTorchAvailable(captureDevice)) {
+ if (mode == QCamera::TorchOn)
+ setAvTorchModeSafe(AVCaptureTorchModeOn);
+ else if (mode == QCamera::TorchAuto)
+ setAvTorchModeSafe(AVCaptureTorchModeAuto);
+ } else {
qCDebug(qLcCamera) << Q_FUNC_INFO << "torch is not available at the moment";
- return;
}
-#endif
- if (mode == QCamera::TorchOn)
- captureDevice.torchMode = AVCaptureTorchModeOn;
- else if (mode == QCamera::TorchAuto)
- captureDevice.torchMode = AVCaptureTorchModeAuto;
}
}
}