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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user