summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorDoris Verria <doris.verria@qt.io>2023-01-27 14:29:40 +0100
committerDoris Verria <doris.verria@qt.io>2023-01-30 08:56:39 +0000
commitf4afbf6c573f8d863f456f25b6cc9ac37e4de5c7 (patch)
treee368ab35ff5ee18af1700883843544dcdae25999 /src/plugins
parentf29bf9e033add62da509708e72bfb6359f1e3602 (diff)
AVFVideoSink: Avoid race condition when updating texture cache
In the main thread, in AVFVideoSinkInterface, we were updating the texture cache by freeing it and replacing it with a newly created one. However, in AVFVideoBuffer::textureHandle, called by the render thread, we were accessing this texture cache to create a new texture. This led to a race condition, where the texture cache may happen to be invalid after being freed. To avoid, add a mutex to the AVFVideoSinkInterface to protect access to the the texture cache. Fixes: QTBUG-110131 Pick-to: 6.5 6.4 Change-Id: If3a4f17f51b5cb38174815b54f03961584b756b9 Reviewed-by: Artem Dyomin <artem.dyomin@qt.io> Reviewed-by: Lars Knoll <lars@knoll.priv.no>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/multimedia/darwin/avfvideobuffer.mm1
-rw-r--r--src/plugins/multimedia/darwin/avfvideosink.mm1
-rw-r--r--src/plugins/multimedia/darwin/avfvideosink_p.h4
3 files changed, 6 insertions, 0 deletions
diff --git a/src/plugins/multimedia/darwin/avfvideobuffer.mm b/src/plugins/multimedia/darwin/avfvideobuffer.mm
index 13776056f..6dab857cc 100644
--- a/src/plugins/multimedia/darwin/avfvideobuffer.mm
+++ b/src/plugins/multimedia/darwin/avfvideobuffer.mm
@@ -136,6 +136,7 @@ quint64 AVFVideoBuffer::textureHandle(int plane) const
height = textureDescription->heightForPlane(height, plane);
// Create a CoreVideo pixel buffer backed Metal texture image from the texture cache.
+ QMutexLocker locker(sink->textureCacheMutex());
auto ret = CVMetalTextureCacheCreateTextureFromImage(
kCFAllocatorDefault,
sink->cvMetalTextureCache,
diff --git a/src/plugins/multimedia/darwin/avfvideosink.mm b/src/plugins/multimedia/darwin/avfvideosink.mm
index 0360039f1..0f321c3d3 100644
--- a/src/plugins/multimedia/darwin/avfvideosink.mm
+++ b/src/plugins/multimedia/darwin/avfvideosink.mm
@@ -100,6 +100,7 @@ void AVFVideoSinkInterface::setVideoSink(AVFVideoSink *sink)
void AVFVideoSinkInterface::setRhi(QRhi *rhi)
{
+ QMutexLocker locker(&m_textureCacheMutex);
if (m_rhi == rhi)
return;
freeTextureCaches();
diff --git a/src/plugins/multimedia/darwin/avfvideosink_p.h b/src/plugins/multimedia/darwin/avfvideosink_p.h
index da0bf2e3a..bc91c2265 100644
--- a/src/plugins/multimedia/darwin/avfvideosink_p.h
+++ b/src/plugins/multimedia/darwin/avfvideosink_p.h
@@ -15,6 +15,7 @@
// We mean it.
//
+#include <QtCore/QMutex>
#include "private/qplatformvideosink_p.h"
Q_FORWARD_DECLARE_OBJC_CLASS(CALayer);
@@ -66,6 +67,8 @@ public:
virtual void setLayer(CALayer *layer);
virtual void setOutputSettings(NSDictionary *settings);
+ QMutex *textureCacheMutex() { return &m_textureCacheMutex; }
+
QRhi *rhi() const { return m_rhi; }
void updateLayerBounds();
@@ -87,6 +90,7 @@ protected:
QRhi *m_rhi = nullptr;
CALayer *m_layer = nullptr;
NSDictionary *m_outputSettings = nullptr;
+ QMutex m_textureCacheMutex;
};