Commit 528588f9 authored by Yoann Lopes's avatar Yoann Lopes Committed by Yoann Lopes
Browse files

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: default avatarChristian Stromme <christian.stromme@qt.io>
Reviewed-by: default avatarRuslan Vorobei <zvorobei@gmail.com>
Showing with 15 additions and 8 deletions
...@@ -662,7 +662,7 @@ void DSCameraSession::onFrameAvailable(const char *frameData, long len) ...@@ -662,7 +662,7 @@ void DSCameraSession::onFrameAvailable(const char *frameData, long len)
QMutexLocker locker(&m_captureMutex); QMutexLocker locker(&m_captureMutex);
if (m_currentImageId != -1 && !m_capturedFrame.isValid()) { if (m_currentImageId != -1 && !m_capturedFrame.isValid()) {
m_capturedFrame = m_currentFrame; 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); QMetaObject::invokeMethod(this, "presentFrame", Qt::QueuedConnection);
...@@ -679,6 +679,9 @@ void DSCameraSession::presentFrame() ...@@ -679,6 +679,9 @@ void DSCameraSession::presentFrame()
m_presentMutex.unlock(); m_presentMutex.unlock();
QImage captureImage;
int captureId;
m_captureMutex.lock(); m_captureMutex.lock();
if (m_capturedFrame.isValid()) { if (m_capturedFrame.isValid()) {
...@@ -686,27 +689,31 @@ void DSCameraSession::presentFrame() ...@@ -686,27 +689,31 @@ void DSCameraSession::presentFrame()
m_capturedFrame.map(QAbstractVideoBuffer::ReadOnly); m_capturedFrame.map(QAbstractVideoBuffer::ReadOnly);
QImage image = QImage(m_capturedFrame.bits(), captureImage = QImage(m_capturedFrame.bits(),
m_previewSize.width(), m_previewSize.height(), m_previewSize.width(), m_previewSize.height(),
QImage::Format_RGB32); 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(); m_capturedFrame.unmap();
emit imageCaptured(m_currentImageId, image); captureId = m_currentImageId;
QtConcurrent::run(this, &DSCameraSession::saveCapturedImage, QtConcurrent::run(this, &DSCameraSession::saveCapturedImage,
m_currentImageId, image, m_imageCaptureFileName); m_currentImageId, captureImage, m_imageCaptureFileName);
m_imageCaptureFileName.clear(); m_imageCaptureFileName.clear();
m_currentImageId = -1; m_currentImageId = -1;
updateReadyForCapture();
m_capturedFrame = QVideoFrame(); m_capturedFrame = QVideoFrame();
} }
m_captureMutex.unlock(); m_captureMutex.unlock();
if (!captureImage.isNull())
emit imageCaptured(captureId, captureImage);
updateReadyForCapture();
} }
void DSCameraSession::saveCapturedImage(int id, const QImage &image, const QString &path) void DSCameraSession::saveCapturedImage(int id, const QImage &image, const QString &path)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment