diff options
author | Doris Verria <doris.verria@qt.io> | 2023-01-27 14:29:40 +0100 |
---|---|---|
committer | Doris Verria <doris.verria@qt.io> | 2023-01-30 08:56:39 +0000 |
commit | f4afbf6c573f8d863f456f25b6cc9ac37e4de5c7 (patch) | |
tree | e368ab35ff5ee18af1700883843544dcdae25999 /src/plugins | |
parent | f29bf9e033add62da509708e72bfb6359f1e3602 (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.mm | 1 | ||||
-rw-r--r-- | src/plugins/multimedia/darwin/avfvideosink.mm | 1 | ||||
-rw-r--r-- | src/plugins/multimedia/darwin/avfvideosink_p.h | 4 |
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; }; |