summaryrefslogtreecommitdiffstats
path: root/src/multimedia
diff options
context:
space:
mode:
authorPavel Dubsky <pavel.dubsky@qt.io>2024-04-11 13:55:32 +0200
committerPavel Dubsky <pavel.dubsky@qt.io>2024-04-17 12:56:53 +0200
commit38c85f0fb274f9dd989bd7601791209589fab94a (patch)
treed2c2765878790c5f3c6cdad13350cae304bbee66 /src/multimedia
parentf1e64525961e56424651b44c34355518e80af537 (diff)
Enable HDR based on video frame format for QtWidgets
Currently swap chain is configured for SDR or HDR only on creation and there is no support for dynamic change when video is played using QVideoWindow. This change adds check that determines whether video frame contains SDR or HDR content and reconfigures swap chain (and subsequently shaders) if needed. Fixes: QTBUG-120963 Pick-to: 6.7 6.6 6.5 Change-Id: I8eef9b46b3999e00427cc50f82486cea7cd80e09 Reviewed-by: Artem Dyomin <artem.dyomin@qt.io>
Diffstat (limited to 'src/multimedia')
-rw-r--r--src/multimedia/qmultimediautils.cpp27
-rw-r--r--src/multimedia/qmultimediautils_p.h12
-rw-r--r--src/multimedia/video/qvideowindow.cpp11
3 files changed, 48 insertions, 2 deletions
diff --git a/src/multimedia/qmultimediautils.cpp b/src/multimedia/qmultimediautils.cpp
index b08875592..9740b6d60 100644
--- a/src/multimedia/qmultimediautils.cpp
+++ b/src/multimedia/qmultimediautils.cpp
@@ -3,6 +3,7 @@
#include "qmultimediautils_p.h"
#include "qvideoframe.h"
+#include "qvideoframeformat.h"
#include <QtCore/qdir.h>
@@ -70,4 +71,30 @@ QUrl qMediaFromUserInput(QUrl url)
return url;
}
+bool qIsAutoHdrEnabled()
+{
+ static const bool autoHdrEnabled = qEnvironmentVariableIntValue("QT_MEDIA_AUTO_HDR");
+
+ return autoHdrEnabled;
+}
+
+QRhiSwapChain::Format qGetRequiredSwapChainFormat(const QVideoFrameFormat &format)
+{
+ constexpr auto sdrMaxLuminance = 100.0f;
+ const auto formatMaxLuminance = format.maxLuminance();
+
+ return formatMaxLuminance > sdrMaxLuminance ? QRhiSwapChain::HDRExtendedSrgbLinear
+ : QRhiSwapChain::SDR;
+}
+
+bool qShouldUpdateSwapChainFormat(QRhiSwapChain *swapChain,
+ QRhiSwapChain::Format requiredSwapChainFormat)
+{
+ if (!swapChain)
+ return false;
+
+ return qIsAutoHdrEnabled() && swapChain->format() != requiredSwapChainFormat
+ && swapChain->isFormatSupported(requiredSwapChainFormat);
+}
+
QT_END_NAMESPACE
diff --git a/src/multimedia/qmultimediautils_p.h b/src/multimedia/qmultimediautils_p.h
index d95bb9e4b..a5d60e066 100644
--- a/src/multimedia/qmultimediautils_p.h
+++ b/src/multimedia/qmultimediautils_p.h
@@ -20,10 +20,13 @@
#include <QtMultimedia/private/qmaybe_p.h>
#include <QtCore/qsize.h>
#include <QtCore/qurl.h>
+#include <QtGui/rhi/qrhi.h>
QT_BEGIN_NAMESPACE
+class QRhiSwapChain;
class QVideoFrame;
+class QVideoFrameFormat;
struct Fraction {
int numerator;
@@ -47,6 +50,15 @@ Q_MULTIMEDIA_EXPORT QSize qRotatedFrameSize(const QVideoFrame &frame);
Q_MULTIMEDIA_EXPORT QUrl qMediaFromUserInput(QUrl fileName);
+Q_MULTIMEDIA_EXPORT bool qIsAutoHdrEnabled();
+
+Q_MULTIMEDIA_EXPORT QRhiSwapChain::Format
+qGetRequiredSwapChainFormat(const QVideoFrameFormat &format);
+
+Q_MULTIMEDIA_EXPORT bool
+qShouldUpdateSwapChainFormat(QRhiSwapChain *swapChain,
+ QRhiSwapChain::Format requiredSwapChainFormat);
+
QT_END_NAMESPACE
#endif // QMULTIMEDIAUTILS_P_H
diff --git a/src/multimedia/video/qvideowindow.cpp b/src/multimedia/video/qvideowindow.cpp
index c5afdaa7d..9cab23f5f 100644
--- a/src/multimedia/video/qvideowindow.cpp
+++ b/src/multimedia/video/qvideowindow.cpp
@@ -7,6 +7,7 @@
#include <qpainter.h>
#include <private/qguiapplication_p.h>
#include <private/qmemoryvideobuffer_p.h>
+#include <private/qmultimediautils_p.h>
#include <qpa/qplatformintegration.h>
QT_BEGIN_NAMESPACE
@@ -153,8 +154,6 @@ void QVideoWindowPrivate::initRhi()
m_swapChain.reset(m_rhi->newSwapChain());
m_swapChain->setWindow(q);
- if (m_swapChain->isFormatSupported(QRhiSwapChain::HDRExtendedSrgbLinear))
- m_swapChain->setFormat(QRhiSwapChain::HDRExtendedSrgbLinear);
m_renderPass.reset(m_swapChain->newCompatibleRenderPassDescriptor());
m_swapChain->setRenderPassDescriptor(m_renderPass.get());
@@ -344,6 +343,14 @@ void QVideoWindowPrivate::render()
if (!m_hasSwapChain || (m_swapChain->currentPixelSize() != m_swapChain->surfacePixelSize()))
resizeSwapChain();
+ const auto requiredSwapChainFormat =
+ qGetRequiredSwapChainFormat(m_currentFrame.surfaceFormat());
+ if (qShouldUpdateSwapChainFormat(m_swapChain.get(), requiredSwapChainFormat)) {
+ releaseSwapChain();
+ m_swapChain->setFormat(requiredSwapChainFormat);
+ resizeSwapChain();
+ }
+
if (!m_hasSwapChain)
return;