From c599e85c50858d57de92ba4316011ea3872b95a3 Mon Sep 17 00:00:00 2001 From: Tim Blechmann Date: Wed, 24 Apr 2024 13:45:25 +0800 Subject: GStreamer: QGstreamerImageCapture - add mutex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `probeBuffer` and `saveBufferToImage` are called from gstreamer threads. We therefore need to guard all members with a mutex that are accessed from both the owning thread and the gstreamer thread. Pick-to: 6.5 6.7 Change-Id: If9ba7fd761c7756b1eb8cc83f757a80c6a4cac8e Reviewed-by: Jøger Hansegård Reviewed-by: Artem Dyomin --- .../gstreamer/mediacapture/qgstreamerimagecapture.cpp | 15 +++++++++++++-- .../gstreamer/mediacapture/qgstreamerimagecapture_p.h | 3 +++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamerimagecapture.cpp b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamerimagecapture.cpp index 5ef797d6e..2f8a1d776 100644 --- a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamerimagecapture.cpp +++ b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamerimagecapture.cpp @@ -81,6 +81,7 @@ QGstreamerImageCapture::~QGstreamerImageCapture() bool QGstreamerImageCapture::isReadyForCapture() const { + QMutexLocker guard(&m_mutex); return m_session && !passImage && cameraActive; } @@ -107,6 +108,7 @@ int QGstreamerImageCapture::doCapture(const QString &fileName) QMetaObject::invokeMethod(this, std::forward(fn), Qt::QueuedConnection); }; + QMutexLocker guard(&m_mutex); if (!m_session) { invokeDeferred([this] { emit error(-1, QImageCapture::ResourceError, @@ -161,6 +163,8 @@ void QGstreamerImageCapture::setResolution(const QSize &resolution) bool QGstreamerImageCapture::probeBuffer(GstBuffer *buffer) { + QMutexLocker guard(&m_mutex); + if (!passImage) return false; qCDebug(qLcImageCaptureGst) << "probe buffer"; @@ -214,6 +218,7 @@ bool QGstreamerImageCapture::probeBuffer(GstBuffer *buffer) void QGstreamerImageCapture::setCaptureSession(QPlatformMediaCaptureSession *session) { + QMutexLocker guard(&m_mutex); QGstreamerMediaCapture *captureSession = static_cast(session); if (m_session == captureSession) return; @@ -241,7 +246,10 @@ void QGstreamerImageCapture::setCaptureSession(QPlatformMediaCaptureSession *ses void QGstreamerImageCapture::setMetaData(const QMediaMetaData &m) { - QPlatformImageCapture::setMetaData(m); + { + QMutexLocker guard(&m_mutex); + QPlatformImageCapture::setMetaData(m); + } // ensure taginject injects this metaData applyMetaDataToTagSetter(m, muxer); @@ -259,9 +267,11 @@ void QGstreamerImageCapture::cameraActiveChanged(bool active) void QGstreamerImageCapture::onCameraChanged() { + QMutexLocker guard(&m_mutex); if (m_session->camera()) { cameraActiveChanged(m_session->camera()->isActive()); - connect(m_session->camera(), &QPlatformCamera::activeChanged, this, &QGstreamerImageCapture::cameraActiveChanged); + connect(m_session->camera(), &QPlatformCamera::activeChanged, this, + &QGstreamerImageCapture::cameraActiveChanged); } else { cameraActiveChanged(false); } @@ -276,6 +286,7 @@ gboolean QGstreamerImageCapture::saveImageFilter(GstElement *, GstBuffer *buffer void QGstreamerImageCapture::saveBufferToImage(GstBuffer *buffer) { + QMutexLocker guard(&m_mutex); passImage = false; if (pendingImages.isEmpty()) diff --git a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamerimagecapture_p.h b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamerimagecapture_p.h index 7be44a239..4b2220d12 100644 --- a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamerimagecapture_p.h +++ b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamerimagecapture_p.h @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -65,6 +66,8 @@ private: void saveBufferToImage(GstBuffer *buffer); + mutable QRecursiveMutex + m_mutex; // guard all elements accessed from probeBuffer/saveBufferToImage QGstreamerMediaCapture *m_session = nullptr; int m_lastId = 0; QImageEncoderSettings m_settings; -- cgit v1.2.3