diff options
author | Doris Verria <doris.verria@qt.io> | 2023-01-27 14:29:40 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2023-01-30 09:28:07 +0000 |
commit | 35f8f9c95d34dc24ffb741e32a203e8448da33fc (patch) | |
tree | 62f560632143387abb3cb13ae7cb0af11c3e135c | |
parent | 8b3364b5b486234904f0aeddb2d0d71be56e2bfc (diff) | |
download | qtmultimedia-35f8f9c95d34dc24ffb741e32a203e8448da33fc.tar.gz |
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
Change-Id: If3a4f17f51b5cb38174815b54f03961584b756b9
Reviewed-by: Artem Dyomin <artem.dyomin@qt.io>
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
(cherry picked from commit f4afbf6c573f8d863f456f25b6cc9ac37e4de5c7)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-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 cb43f234b..e4ace6084 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; }; |