summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtem Dyomin <artem.dyomin@qt.io>2022-11-25 15:09:14 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-11-30 10:23:07 +0000
commitc738ea76d832506654ec40862af90be7d78c504c (patch)
tree896a1ae4d7b661f44a6ca11f1d3a553ded6bcb82
parent74558be2f0a8f7622f696753faf83a2d9947c8e4 (diff)
downloadqtmultimedia-c738ea76d832506654ec40862af90be7d78c504c.tar.gz
Fix ffmpeg camera crash on macOS (double releasing of an object)
The reason for the crash is 'autorelease' and 'release' in the destructor. In applications, QMacAutoReleasePool releases it 2nd time. The application crashed after a few camera changes. So we should use only one approach. The suggestion is to manage the object manually for both backends in order to make the behavior more predictable. The added test checks the case. Change-Id: I80a644acd94ae469a16fd95ba971441c78e7a700 Reviewed-by: Doris Verria <doris.verria@qt.io> (cherry picked from commit d73cc0bce893b81de3f84c570110c8969b9ee468) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/plugins/multimedia/darwin/camera/avfcamerarenderer.mm4
-rw-r--r--src/plugins/multimedia/ffmpeg/qavfcamera.mm2
-rw-r--r--tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp31
3 files changed, 35 insertions, 2 deletions
diff --git a/src/plugins/multimedia/darwin/camera/avfcamerarenderer.mm b/src/plugins/multimedia/darwin/camera/avfcamerarenderer.mm
index 871234f9f..0bcb7274b 100644
--- a/src/plugins/multimedia/darwin/camera/avfcamerarenderer.mm
+++ b/src/plugins/multimedia/darwin/camera/avfcamerarenderer.mm
@@ -87,6 +87,8 @@ AVFCameraRenderer::~AVFCameraRenderer()
{
[m_cameraSession->captureSession() removeOutput:m_videoDataOutput];
[m_viewfinderFramesDelegate release];
+ [m_videoDataOutput release];
+
if (m_delegateQueue)
dispatch_release(m_delegateQueue);
#ifdef Q_OS_IOS
@@ -123,7 +125,7 @@ void AVFCameraRenderer::configureAVCaptureSession(AVFCameraSession *cameraSessio
m_needsHorizontalMirroring = false;
- m_videoDataOutput = [[[AVCaptureVideoDataOutput alloc] init] autorelease];
+ m_videoDataOutput = [[AVCaptureVideoDataOutput alloc] init];
// Configure video output
m_delegateQueue = dispatch_queue_create("vf_queue", nullptr);
diff --git a/src/plugins/multimedia/ffmpeg/qavfcamera.mm b/src/plugins/multimedia/ffmpeg/qavfcamera.mm
index cb7cfdaec..d6ec94a0e 100644
--- a/src/plugins/multimedia/ffmpeg/qavfcamera.mm
+++ b/src/plugins/multimedia/ffmpeg/qavfcamera.mm
@@ -220,7 +220,7 @@ void QAVFCamera::updateVideoInput()
attachVideoInputDevice();
if (!m_videoDataOutput) {
- m_videoDataOutput = [[[AVCaptureVideoDataOutput alloc] init] autorelease];
+ m_videoDataOutput = [[AVCaptureVideoDataOutput alloc] init];
// Configure video output
m_delegateQueue = dispatch_queue_create("vf_queue", nullptr);
diff --git a/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp b/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp
index 066d97fa7..05dd1def1 100644
--- a/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp
+++ b/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp
@@ -22,6 +22,10 @@
#include <qmediaplayer.h>
#include <qaudiooutput.h>
+#ifdef Q_OS_DARWIN
+#include <QtCore/private/qcore_mac_p.h>
+#endif
+
QT_USE_NAMESPACE
/*
@@ -58,6 +62,8 @@ private slots:
void testNativeMetadata();
+ void multipleCameraSet();
+
private:
bool noCamera = false;
};
@@ -672,6 +678,31 @@ void tst_QCameraBackend::testNativeMetadata()
QFile(fileName).remove();
}
+void tst_QCameraBackend::multipleCameraSet()
+{
+ if (noCamera)
+ QSKIP("No camera available");
+
+ QMediaCaptureSession session;
+ QCameraDevice device = QMediaDevices::defaultVideoInput();
+
+ QMediaRecorder recorder;
+ session.setRecorder(&recorder);
+
+ for (int i = 0; i < 5; ++i) {
+#ifdef Q_OS_DARWIN
+ QMacAutoReleasePool releasePool;
+#endif
+
+ QCamera camera(device);
+ session.setCamera(&camera);
+
+ camera.start();
+
+ QTest::qWait(100);
+ }
+}
+
QTEST_MAIN(tst_QCameraBackend)
#include "tst_qcamerabackend.moc"