diff options
-rw-r--r-- | examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneBasic.qml | 2 | ||||
-rw-r--r-- | src/multimedia/video/qvideosurfaceformat.cpp | 15 | ||||
-rw-r--r-- | src/multimedia/video/qvideosurfaceformat.h | 2 | ||||
-rw-r--r-- | src/qtmultimediaquicktools/qsgvideonode_rgb.cpp | 26 | ||||
-rw-r--r-- | src/qtmultimediaquicktools/qsgvideonode_yuv.cpp | 123 |
5 files changed, 50 insertions, 118 deletions
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneBasic.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneBasic.qml index 6c9c3ae2a..b5ea072ba 100644 --- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneBasic.qml +++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneBasic.qml @@ -60,7 +60,7 @@ Scene { id: content autoStart: parent.autoStart started: parent.started - anchors.centerIn: parent + anchors.fill: parent width: parent.contentWidth contentType: parent.contentType source: parent.source1 diff --git a/src/multimedia/video/qvideosurfaceformat.cpp b/src/multimedia/video/qvideosurfaceformat.cpp index 774a72c30..5271a12db 100644 --- a/src/multimedia/video/qvideosurfaceformat.cpp +++ b/src/multimedia/video/qvideosurfaceformat.cpp @@ -486,7 +486,7 @@ QString QVideoSurfaceFormat::vertexShaderFileName() const } } -QString QVideoSurfaceFormat::pixelShaderFileName() const +QString QVideoSurfaceFormat::fragmentShaderFileName() const { switch (d->pixelFormat) { case Format_Invalid: @@ -608,17 +608,13 @@ QByteArray QVideoSurfaceFormat::uniformData(const QMatrix4x4 &transform, float o QByteArray buf(16*4 + 4, Qt::Uninitialized); char *data = buf.data(); memcpy(data, transform.constData(), 64); - memcpy(data + 64, colorMatrix(d->ycbcrColorSpace).constData(), 64); - memcpy(data + 64 + 64, &opacity, 4); - memcpy(data + 64 + 64, &opacity, 4); - memcpy(data + 64 + 64, &opacity, 4); - memcpy(data + 64 + 64, &opacity, 4); + memcpy(data + 64, &opacity, 4); return buf; } case Format_YUV420P: case Format_YUV422P: case Format_YV12: { - static constexpr float pw[] = { 1, 1, 0 }; + static constexpr float pw[] = { 1, 1, 1 }; planeWidth = pw; break; } @@ -643,8 +639,9 @@ QByteArray QVideoSurfaceFormat::uniformData(const QMatrix4x4 &transform, float o QByteArray buf(64*2 + 4 + 3*4, Qt::Uninitialized); char *data = buf.data(); memcpy(data, transform.constData(), 64); - memcpy(data + 64, &opacity, 4); - memcpy(data + 64 + 4, planeWidth, 3*4); + memcpy(data + 64, colorMatrix(d->ycbcrColorSpace).constData(), 64); + memcpy(data + 64 + 64, &opacity, 4); + memcpy(data + 64 + 64 + 4, planeWidth, 3*4); return buf; } diff --git a/src/multimedia/video/qvideosurfaceformat.h b/src/multimedia/video/qvideosurfaceformat.h index c81416945..41b5c8292 100644 --- a/src/multimedia/video/qvideosurfaceformat.h +++ b/src/multimedia/video/qvideosurfaceformat.h @@ -165,7 +165,7 @@ public: QSize sizeHint() const; QString vertexShaderFileName() const; - QString pixelShaderFileName() const; + QString fragmentShaderFileName() const; QByteArray uniformData(const QMatrix4x4 &transform, float opacity) const; static PixelFormat pixelFormatFromImageFormat(QImage::Format format); diff --git a/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp b/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp index 7a3321c8c..064cf43b0 100644 --- a/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp +++ b/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp @@ -71,10 +71,11 @@ QSGVideoNode *QSGVideoNodeFactory_RGB::createNode(const QVideoSurfaceFormat &for class QSGVideoMaterialRhiShader_RGB : public QSGMaterialShader { public: - QSGVideoMaterialRhiShader_RGB() + QSGVideoMaterialRhiShader_RGB(const QVideoSurfaceFormat &format) + : m_format(format) { - setShaderFileName(VertexStage, QStringLiteral(":/qtmultimedia/shaders/rgba.vert.qsb")); - setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimedia/shaders/rgba.frag.qsb")); + setShaderFileName(VertexStage, format.vertexShaderFileName()); + setShaderFileName(FragmentStage, format.fragmentShaderFileName()); } bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, @@ -82,6 +83,7 @@ public: void updateSampledImage(RenderState &state, int binding, QSGTexture **texture, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override; + QVideoSurfaceFormat m_format; }; class QSGVideoMaterial_RGB : public QSGMaterial @@ -101,7 +103,7 @@ public: } [[nodiscard]] QSGMaterialShader *createShader(QSGRendererInterface::RenderMode) const override { - return new QSGVideoMaterialRhiShader_RGB; + return new QSGVideoMaterialRhiShader_RGB(m_format); } int compare(const QSGMaterial *other) const override { @@ -133,23 +135,19 @@ bool QSGVideoMaterialRhiShader_RGB::updateUniformData(RenderState &state, QSGMat { Q_UNUSED(oldMaterial); - bool changed = false; - QByteArray *buf = state.uniformData(); - - if (state.isMatrixDirty()) { - memcpy(buf->data(), state.combinedMatrix().constData(), 64); - changed = true; - } + if (!state.isMatrixDirty() && !state.isOpacityDirty()) + return false; if (state.isOpacityDirty()) { auto m = static_cast<QSGVideoMaterial_RGB *>(newMaterial); m->m_opacity = state.opacity(); m->updateBlending(); - memcpy(buf->data() + 64, &m->m_opacity, 4); - changed = true; } - return changed; + QByteArray *buf = state.uniformData(); + *buf = m_format.uniformData(state.combinedMatrix(), state.opacity()); + + return true; } void QSGVideoMaterialRhiShader_RGB::updateSampledImage(RenderState &state, int binding, QSGTexture **texture, diff --git a/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp b/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp index cd4e0b251..d305e52a7 100644 --- a/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp +++ b/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp @@ -69,9 +69,11 @@ QSGVideoNode *QSGVideoNodeFactory_YUV::createNode(const QVideoSurfaceFormat &for class QSGVideoMaterialRhiShader_YUV : public QSGMaterialShader { public: - QSGVideoMaterialRhiShader_YUV() + QSGVideoMaterialRhiShader_YUV(const QVideoSurfaceFormat &format) + : m_format(format) { - setShaderFileName(VertexStage, QStringLiteral(":/qtmultimedia/shaders/yuv.vert.qsb")); + setShaderFileName(VertexStage, m_format.vertexShaderFileName()); + setShaderFileName(FragmentStage, m_format.fragmentShaderFileName()); } bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, @@ -83,6 +85,7 @@ public: virtual void mapFrame(QSGVideoMaterial_YUV *) = 0; protected: + QVideoSurfaceFormat m_format; float m_planeWidth[3] = {0, 0, 0}; QMatrix4x4 m_colorMatrix; }; @@ -90,81 +93,39 @@ protected: class QSGVideoMaterialRhiShader_UYVY : public QSGVideoMaterialRhiShader_YUV { public: - QSGVideoMaterialRhiShader_UYVY() - { - setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimedia/shaders/uyvy.frag.qsb")); - } - + QSGVideoMaterialRhiShader_UYVY(const QVideoSurfaceFormat &format) + : QSGVideoMaterialRhiShader_YUV(format) + {} void mapFrame(QSGVideoMaterial_YUV *m) override; }; -class QSGVideoMaterialRhiShader_YUYV : public QSGVideoMaterialRhiShader_UYVY -{ -public: - QSGVideoMaterialRhiShader_YUYV() - { - setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimedia/shaders/yuyv.frag.qsb")); - } -}; - class QSGVideoMaterialRhiShader_YUV_YV : public QSGVideoMaterialRhiShader_YUV { public: - QSGVideoMaterialRhiShader_YUV_YV() - { - setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimedia/shaders/yuv_yv.frag.qsb")); - } - + QSGVideoMaterialRhiShader_YUV_YV(const QVideoSurfaceFormat &format) + : QSGVideoMaterialRhiShader_YUV(format) + {} void mapFrame(QSGVideoMaterial_YUV *m) override; }; class QSGVideoMaterialRhiShader_NV12 : public QSGVideoMaterialRhiShader_YUV { public: - QSGVideoMaterialRhiShader_NV12() - { - setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimedia/shaders/nv12.frag.qsb")); - } - + QSGVideoMaterialRhiShader_NV12(const QVideoSurfaceFormat &format) + : QSGVideoMaterialRhiShader_YUV(format) + {} void mapFrame(QSGVideoMaterial_YUV *m) override; }; -class QSGVideoMaterialRhiShader_NV21 : public QSGVideoMaterialRhiShader_NV12 -{ -public: - QSGVideoMaterialRhiShader_NV21() - { - setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimedia/shaders/nv21.frag.qsb")); - } -}; - class QSGVideoMaterialRhiShader_P010 : public QSGVideoMaterialRhiShader_YUV { public: - QSGVideoMaterialRhiShader_P010() = default; - + QSGVideoMaterialRhiShader_P010(const QVideoSurfaceFormat &format) + : QSGVideoMaterialRhiShader_YUV(format) + {} void mapFrame(QSGVideoMaterial_YUV *m) override; }; - -class QSGVideoMaterialRhiShader_P010LE : public QSGVideoMaterialRhiShader_P010 -{ -public: - QSGVideoMaterialRhiShader_P010LE() - { - setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimedia/shaders/p010le.frag.qsb")); - } -}; - -class QSGVideoMaterialRhiShader_P010BE : public QSGVideoMaterialRhiShader_P010 -{ -public: - QSGVideoMaterialRhiShader_P010BE() - { - setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimedia/shaders/p010be.frag.qsb")); - } -}; - class QSGVideoMaterial_YUV : public QSGMaterial { public: @@ -194,21 +155,18 @@ public: [[nodiscard]] QSGMaterialShader *createShader(QSGRendererInterface::RenderMode) const override { switch (m_format.pixelFormat()) { case QVideoSurfaceFormat::Format_NV12: - return new QSGVideoMaterialRhiShader_NV12; case QVideoSurfaceFormat::Format_NV21: - return new QSGVideoMaterialRhiShader_NV21; + return new QSGVideoMaterialRhiShader_NV12(m_format); case QVideoSurfaceFormat::Format_UYVY: - return new QSGVideoMaterialRhiShader_UYVY; case QVideoSurfaceFormat::Format_YUYV: - return new QSGVideoMaterialRhiShader_YUYV; + return new QSGVideoMaterialRhiShader_UYVY(m_format); case QVideoSurfaceFormat::Format_P010LE: case QVideoSurfaceFormat::Format_P016LE: - return new QSGVideoMaterialRhiShader_P010LE; case QVideoSurfaceFormat::Format_P010BE: case QVideoSurfaceFormat::Format_P016BE: - return new QSGVideoMaterialRhiShader_P010BE; + return new QSGVideoMaterialRhiShader_P010(m_format); default: // Currently: YUV420P, YUV422P and YV12 - return new QSGVideoMaterialRhiShader_YUV_YV; + return new QSGVideoMaterialRhiShader_YUV_YV(m_format); } } @@ -248,45 +206,24 @@ bool QSGVideoMaterialRhiShader_YUV::updateUniformData(RenderState &state, QSGMat Q_UNUSED(oldMaterial); auto m = static_cast<QSGVideoMaterial_YUV *>(newMaterial); - bool changed = false; - QByteArray *buf = state.uniformData(); - - if (state.isMatrixDirty()) { - memcpy(buf->data(), state.combinedMatrix().constData(), 64); - changed = true; - } + m->m_frameMutex.lock(); + mapFrame(m); + m->m_frameMutex.unlock(); - if (m->m_colorMatrix != m_colorMatrix) { - memcpy(buf->data() + 64, m->m_colorMatrix.constData(), 64); - changed = true; - } - m_colorMatrix = m->m_colorMatrix; + if (!state.isMatrixDirty() && !state.isOpacityDirty() && m->m_colorMatrix == m_colorMatrix) + return false; if (state.isOpacityDirty()) { m->m_opacity = state.opacity(); m->updateBlending(); - memcpy(buf->data() + 64 + 64, &m->m_opacity, 4); - changed = true; } - m->m_frameMutex.lock(); - mapFrame(m); - m->m_frameMutex.unlock(); + m_colorMatrix = m->m_colorMatrix; - if (!qFuzzyCompare(m->m_planeWidth[0], m_planeWidth[0]) - || !qFuzzyCompare(m->m_planeWidth[1], m_planeWidth[1]) - || !qFuzzyCompare(m->m_planeWidth[2], m_planeWidth[2])) - { - memcpy(buf->data() + 64 + 64 + 4, &m->m_planeWidth[0], 4); - memcpy(buf->data() + 64 + 64 + 4 + 4, &m->m_planeWidth[1], 4); - memcpy(buf->data() + 64 + 64 + 4 + 4 + 4, &m->m_planeWidth[2], 4); - changed = true; - } - m_planeWidth[0] = m->m_planeWidth[0]; - m_planeWidth[1] = m->m_planeWidth[1]; - m_planeWidth[2] = m->m_planeWidth[2]; + QByteArray *buf = state.uniformData(); + *buf = m_format.uniformData(state.combinedMatrix(), state.opacity()); - return changed; + return true; } void QSGVideoMaterialRhiShader_YUV::updateSampledImage(RenderState &state, int binding, QSGTexture **texture, |