summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/multimedia/qmultimediautils.cpp27
-rw-r--r--src/multimedia/qmultimediautils_p.h12
-rw-r--r--src/multimedia/video/qvideowindow.cpp11
-rw-r--r--tests/auto/unit/multimedia/qmultimediautils/tst_qmultimediautils.cpp71
4 files changed, 119 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;
diff --git a/tests/auto/unit/multimedia/qmultimediautils/tst_qmultimediautils.cpp b/tests/auto/unit/multimedia/qmultimediautils/tst_qmultimediautils.cpp
index 0acd41696..8ed54ac64 100644
--- a/tests/auto/unit/multimedia/qmultimediautils/tst_qmultimediautils.cpp
+++ b/tests/auto/unit/multimedia/qmultimediautils/tst_qmultimediautils.cpp
@@ -4,6 +4,7 @@
#include <QtTest/QtTest>
#include <QDebug>
#include <private/qmultimediautils_p.h>
+#include <qvideoframeformat.h>
class tst_QMultimediaUtils : public QObject
{
@@ -21,6 +22,13 @@ private slots:
void qRotatedFrameSize_returnsSizeAccordinglyToRotation();
void qMediaFromUserInput_addsFilePrefix_whenCalledWithLocalFile();
+
+ void qGetRequiredSwapChainFormat_returnsSdr_whenMaxLuminanceIsBelowSdrThreshold_data();
+ void qGetRequiredSwapChainFormat_returnsSdr_whenMaxLuminanceIsBelowSdrThreshold();
+ void qGetRequiredSwapChainFormat_returnsHdr_whenMaxLuminanceIsBelowHdrThreshold_data();
+ void qGetRequiredSwapChainFormat_returnsHdr_whenMaxLuminanceIsBelowHdrThreshold();
+
+ void qShouldUpdateSwapChainFormat_returnsFalse_whenSwapChainIsNullPointer();
};
void tst_QMultimediaUtils::fraction_of_0()
@@ -109,5 +117,68 @@ void tst_QMultimediaUtils::qMediaFromUserInput_addsFilePrefix_whenCalledWithLoca
QUrl::fromLocalFile(QDir::currentPath() + u"/foo/bar/baz"_s));
}
+void tst_QMultimediaUtils::
+ qGetRequiredSwapChainFormat_returnsSdr_whenMaxLuminanceIsBelowSdrThreshold_data()
+{
+ QTest::addColumn<float>("maxLuminance");
+
+ QTest::newRow("0") << 0.0f;
+ QTest::newRow("80") << 80.0f;
+ QTest::newRow("100") << 100.0f;
+}
+
+void tst_QMultimediaUtils::
+ qGetRequiredSwapChainFormat_returnsSdr_whenMaxLuminanceIsBelowSdrThreshold()
+{
+ // Arrange
+ QFETCH(float, maxLuminance);
+
+ QVideoFrameFormat format;
+ format.setMaxLuminance(maxLuminance);
+
+ // Act
+ QRhiSwapChain::Format requiredSwapChainFormat = qGetRequiredSwapChainFormat(format);
+
+ // Assert
+ QCOMPARE(requiredSwapChainFormat, QRhiSwapChain::Format::SDR);
+}
+
+void tst_QMultimediaUtils::
+ qGetRequiredSwapChainFormat_returnsHdr_whenMaxLuminanceIsBelowHdrThreshold_data()
+{
+ QTest::addColumn<float>("maxLuminance");
+
+ QTest::newRow("101") << 101.0f;
+ QTest::newRow("300") << 300.0f;
+ QTest::newRow("1600") << 1600.0f;
+}
+
+void tst_QMultimediaUtils::
+ qGetRequiredSwapChainFormat_returnsHdr_whenMaxLuminanceIsBelowHdrThreshold()
+{
+ // Arrange
+ QVideoFrameFormat format;
+ format.setMaxLuminance(300.0f);
+
+ // Act
+ QRhiSwapChain::Format requiredSwapChainFormat = qGetRequiredSwapChainFormat(format);
+
+ // Assert
+ QCOMPARE(requiredSwapChainFormat, QRhiSwapChain::Format::HDRExtendedSrgbLinear);
+}
+
+void tst_QMultimediaUtils::qShouldUpdateSwapChainFormat_returnsFalse_whenSwapChainIsNullPointer()
+{
+ // Arrange
+ QRhiSwapChain *swapChain = nullptr;
+ QRhiSwapChain::Format requiredSwapChainFormat = QRhiSwapChain::Format::SDR;
+
+ // Act
+ bool shouldUpdate = qShouldUpdateSwapChainFormat(swapChain, requiredSwapChainFormat);
+
+ // Assert
+ QCOMPARE(shouldUpdate, false);
+}
+
QTEST_MAIN(tst_QMultimediaUtils)
#include "tst_qmultimediautils.moc"