diff options
-rw-r--r-- | src/multimedia/qmultimediautils.cpp | 27 | ||||
-rw-r--r-- | src/multimedia/qmultimediautils_p.h | 12 | ||||
-rw-r--r-- | src/multimedia/video/qvideowindow.cpp | 11 | ||||
-rw-r--r-- | tests/auto/unit/multimedia/qmultimediautils/tst_qmultimediautils.cpp | 71 |
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" |