summaryrefslogtreecommitdiffstats
path: root/src/multimedia/video/qvideoframe.cpp
diff options
context:
space:
mode:
authorArtem Dyomin <artem.dyomin@qt.io>2023-07-27 12:40:24 +0200
committerArtem Dyomin <artem.dyomin@qt.io>2023-07-27 14:00:50 +0000
commit60bf900d56cec69057677fa6069c5a96220c6d97 (patch)
treee65ebcdbdc7f49923c1134e2d5a59f6af4b45414 /src/multimedia/video/qvideoframe.cpp
parenta2880974497bfe1ee3c17803fca4643a6ef3855e (diff)
Fix QVideoFrame::toImage thread-safety
* toImage is const and it's expected to be thread-safe * since video frames are often emitted from separate threads, there might be collisions with 2 images created in parallel. * Even though QImage assignment is thread safe, let's avoid possible parallel rendering to different images. Pick-to: 6.6 6.5 6.2 Task-number: QTBUG-111975 Change-Id: Ib26982e3a1df888dbf70c3c0ff73392d4dc81c80 Reviewed-by: Pavel Dubsky <pavel.dubsky@qt.io> Reviewed-by: Artem Dyomin <artem.dyomin@qt.io>
Diffstat (limited to 'src/multimedia/video/qvideoframe.cpp')
-rw-r--r--src/multimedia/video/qvideoframe.cpp13
1 files changed, 9 insertions, 4 deletions
diff --git a/src/multimedia/video/qvideoframe.cpp b/src/multimedia/video/qvideoframe.cpp
index 503a29f70..b626ad573 100644
--- a/src/multimedia/video/qvideoframe.cpp
+++ b/src/multimedia/video/qvideoframe.cpp
@@ -17,6 +17,8 @@
#include <qvariant.h>
#include <rhi/qrhi.h>
+#include <mutex>
+
#include <QDebug>
QT_BEGIN_NAMESPACE
@@ -46,6 +48,8 @@ public:
QVideoFrame::RotationAngle rotationAngle = QVideoFrame::Rotation0;
bool mirrored = false;
QImage image;
+ std::once_flag imageOnceFlag;
+
private:
Q_DISABLE_COPY(QVideoFramePrivate)
};
@@ -676,11 +680,12 @@ QImage QVideoFrame::toImage() const
{
if (!isValid())
return {};
- if (!d->image.isNull())
- return d->image;
- d->image = qImageFromVideoFrame(*this, rotationAngle(), mirrored(),
- surfaceFormat().scanLineDirection() != QVideoFrameFormat::TopToBottom);
+ std::call_once(d->imageOnceFlag, [this]() {
+ const bool mirrorY = surfaceFormat().scanLineDirection() != QVideoFrameFormat::TopToBottom;
+ d->image = qImageFromVideoFrame(*this, rotationAngle(), mirrored(), mirrorY);
+ });
+
return d->image;
}