summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@theqtcompany.com>2016-07-11 16:07:21 +0200
committerYoann Lopes <yoann.lopes@qt.io>2016-08-12 11:14:30 +0000
commit528588f9f106f25bbf95f632e79106774319079a (patch)
treee64471d217bda97d579c81045ac6a30aff4f30a7
parent87abe0bad1945decd71345633be0509b29ab9396 (diff)
DirectShow: fix possible deadlock when capturing camera image
Don't emit signals while mutexes are locked. Task-number: QTBUG-41573 Change-Id: I287b031a579cbec1cd178501df4426ceff9e9142 Reviewed-by: Christian Stromme <christian.stromme@qt.io> Reviewed-by: Ruslan Vorobei <zvorobei@gmail.com>
-rw-r--r--src/plugins/directshow/camera/dscamerasession.cpp23
1 files changed, 15 insertions, 8 deletions
diff --git a/src/plugins/directshow/camera/dscamerasession.cpp b/src/plugins/directshow/camera/dscamerasession.cpp
index 3421f2cd..1cb91cd4 100644
--- a/src/plugins/directshow/camera/dscamerasession.cpp
+++ b/src/plugins/directshow/camera/dscamerasession.cpp
@@ -662,7 +662,7 @@ void DSCameraSession::onFrameAvailable(const char *frameData, long len)
QMutexLocker locker(&m_captureMutex);
if (m_currentImageId != -1 && !m_capturedFrame.isValid()) {
m_capturedFrame = m_currentFrame;
- emit imageExposed(m_currentImageId);
+ QMetaObject::invokeMethod(this, "imageExposed", Qt::QueuedConnection, Q_ARG(int, m_currentImageId));
}
QMetaObject::invokeMethod(this, "presentFrame", Qt::QueuedConnection);
@@ -679,6 +679,9 @@ void DSCameraSession::presentFrame()
m_presentMutex.unlock();
+ QImage captureImage;
+ int captureId;
+
m_captureMutex.lock();
if (m_capturedFrame.isValid()) {
@@ -686,27 +689,31 @@ void DSCameraSession::presentFrame()
m_capturedFrame.map(QAbstractVideoBuffer::ReadOnly);
- QImage image = QImage(m_capturedFrame.bits(),
- m_previewSize.width(), m_previewSize.height(),
- QImage::Format_RGB32);
+ captureImage = QImage(m_capturedFrame.bits(),
+ m_previewSize.width(), m_previewSize.height(),
+ QImage::Format_RGB32);
- image = image.mirrored(m_needsHorizontalMirroring); // also causes a deep copy of the data
+ captureImage = captureImage.mirrored(m_needsHorizontalMirroring); // also causes a deep copy of the data
m_capturedFrame.unmap();
- emit imageCaptured(m_currentImageId, image);
+ captureId = m_currentImageId;
QtConcurrent::run(this, &DSCameraSession::saveCapturedImage,
- m_currentImageId, image, m_imageCaptureFileName);
+ m_currentImageId, captureImage, m_imageCaptureFileName);
m_imageCaptureFileName.clear();
m_currentImageId = -1;
- updateReadyForCapture();
m_capturedFrame = QVideoFrame();
}
m_captureMutex.unlock();
+
+ if (!captureImage.isNull())
+ emit imageCaptured(captureId, captureImage);
+
+ updateReadyForCapture();
}
void DSCameraSession::saveCapturedImage(int id, const QImage &image, const QString &path)