summaryrefslogtreecommitdiffstats
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-11 16:07:42 +0100
commit7d9713412ba3db914f984be16aeba6be820d68a4 (patch)
treeb81370356929cc94197782679e3dee2f877bffff
parentac0e44288d305fb22d9396f97f7ee0b1d371e917 (diff)
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 Pick-to: 6.4 Change-Id: I42772edb4c26481283d1bd321914bf40284efde9 Reviewed-by: Lars Knoll <lars@knoll.priv.no>
-rw-r--r--src/plugins/multimedia/darwin/camera/qavfcamerabase.mm59
1 files changed, 34 insertions, 25 deletions
diff --git a/src/plugins/multimedia/darwin/camera/qavfcamerabase.mm b/src/plugins/multimedia/darwin/camera/qavfcamerabase.mm
index b40c1133e..5edf7de26 100644
--- a/src/plugins/multimedia/darwin/camera/qavfcamerabase.mm
+++ b/src/plugins/multimedia/darwin/camera/qavfcamerabase.mm
@@ -630,14 +630,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;
}
void QAVFCameraBase::setTorchMode(QCamera::TorchMode mode)
@@ -727,42 +723,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 ([captureDevice isFlashAvailable]) {
+ 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 ([captureDevice isTorchAvailable]) {
+ 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;
}
}
}