diff options
author | Artem Dyomin <artem.dyomin@qt.io> | 2024-01-23 16:05:40 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2024-01-23 20:26:07 +0000 |
commit | 56c37105e39303aeb1a27418b80be0953f9b08ea (patch) | |
tree | 1c81c6e0acea6aae9699ddb8c44f96e889bb47d5 /src | |
parent | b4ccc09abb258f57ca8b1d456369067136673a5a (diff) |
Implement fixing of QImage by QImageVideoBuffer
Many of QImage formats are not mapped to QVideoFrame formats without
conversions. Let's consider this and ensure
a correct video frame format.
Eglfs screen capture is to be fixed in the next commits.
The relevant unit test is added to the patch.
Pick-to: 6.6 6.5
Change-Id: Ic4a490392ec2b6aa63e752badea7269a07d93af9
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
(cherry picked from commit f9edbcb7fedcd7e2e2c274dcda1979e304245b32)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/multimedia/video/qimagevideobuffer.cpp | 53 | ||||
-rw-r--r-- | src/multimedia/video/qimagevideobuffer_p.h | 2 | ||||
-rw-r--r-- | src/plugins/multimedia/ffmpeg/qgrabwindowsurfacecapture.cpp | 5 |
3 files changed, 57 insertions, 3 deletions
diff --git a/src/multimedia/video/qimagevideobuffer.cpp b/src/multimedia/video/qimagevideobuffer.cpp index 293d17252..bc825004e 100644 --- a/src/multimedia/video/qimagevideobuffer.cpp +++ b/src/multimedia/video/qimagevideobuffer.cpp @@ -2,11 +2,57 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qimagevideobuffer_p.h" +#include "qvideoframeformat.h" QT_BEGIN_NAMESPACE +namespace { + +QImage::Format fixImageFormat(QImage::Format format) +{ + switch (format) { + case QImage::Format_ARGB32_Premultiplied: + case QImage::Format_ARGB8565_Premultiplied: + case QImage::Format_ARGB6666_Premultiplied: + case QImage::Format_ARGB8555_Premultiplied: + case QImage::Format_ARGB4444_Premultiplied: + case QImage::Format_RGBA8888_Premultiplied: + case QImage::Format_A2BGR30_Premultiplied: + case QImage::Format_A2RGB30_Premultiplied: + case QImage::Format_RGBA64_Premultiplied: + case QImage::Format_RGBA16FPx4_Premultiplied: + case QImage::Format_RGBA32FPx4_Premultiplied: + return QImage::Format_ARGB32_Premultiplied; + case QImage::Format_ARGB32: + case QImage::Format_RGBA8888: + case QImage::Format_Alpha8: + case QImage::Format_RGBA64: + case QImage::Format_RGBA16FPx4: + case QImage::Format_RGBA32FPx4: + return QImage::Format_ARGB32; + case QImage::Format_Invalid: + return QImage::Format_Invalid; + default: + return QImage::Format_RGB32; + } +} + +QImage fixImage(QImage image) +{ + if (image.format() == QImage::Format_Invalid) + return image; + + const auto frameFormat = QVideoFrameFormat::pixelFormatFromImageFormat(image.format()); + if (frameFormat != QVideoFrameFormat::Format_Invalid) + return image; + + return image.convertToFormat(fixImageFormat(image.format())); +} + +} // namespace + QImageVideoBuffer::QImageVideoBuffer(QImage image) - : QAbstractVideoBuffer(QVideoFrame::NoHandle), m_image(std::move(image)) + : QAbstractVideoBuffer(QVideoFrame::NoHandle), m_image(fixImage(std::move(image))) { } @@ -36,4 +82,9 @@ void QImageVideoBuffer::unmap() m_mapMode = QVideoFrame::NotMapped; } +QImage QImageVideoBuffer::underlyingImage() const +{ + return m_image; +} + QT_END_NAMESPACE diff --git a/src/multimedia/video/qimagevideobuffer_p.h b/src/multimedia/video/qimagevideobuffer_p.h index 83fc21d4f..e5467563a 100644 --- a/src/multimedia/video/qimagevideobuffer_p.h +++ b/src/multimedia/video/qimagevideobuffer_p.h @@ -31,6 +31,8 @@ public: void unmap() override; + QImage underlyingImage() const; + private: QVideoFrame::MapMode m_mapMode = QVideoFrame::NotMapped; QImage m_image; diff --git a/src/plugins/multimedia/ffmpeg/qgrabwindowsurfacecapture.cpp b/src/plugins/multimedia/ffmpeg/qgrabwindowsurfacecapture.cpp index 8ed3aecd9..4e87a0559 100644 --- a/src/plugins/multimedia/ffmpeg/qgrabwindowsurfacecapture.cpp +++ b/src/plugins/multimedia/ffmpeg/qgrabwindowsurfacecapture.cpp @@ -125,7 +125,8 @@ private: setFrameRate(screen->refreshRate()); QPixmap p = screen->grabWindow(wid); - QImage img = p.toImage(); + auto buffer = std::make_unique<QImageVideoBuffer>(p.toImage()); + const auto img = buffer->underlyingImage(); QVideoFrameFormat format(img.size(), QVideoFrameFormat::pixelFormatFromImageFormat(img.format())); @@ -138,7 +139,7 @@ private: return {}; } - return QVideoFrame(new QImageVideoBuffer(std::move(img)), format); + return QVideoFrame(buffer.release(), format); } private: |