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