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>
This commit is contained in:
Yoann Lopes
2016-07-11 16:07:21 +02:00
committed by Yoann Lopes
parent 87abe0bad1
commit 528588f9f1

View File

@@ -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)