summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2021-03-25 18:04:03 +0100
committerLars Knoll <lars.knoll@qt.io>2021-04-07 14:51:17 +0000
commitf66c18bc51989ae5388b333c2b2804dd7b6e3f1a (patch)
tree537f8ed94945053648f44160c4cbcdd0c7963eac /src
parent0ce875a4e302afc5b67ec63d35051d90e486db79 (diff)
Use the infra in QVideoSurfaceFormat to get shaders and uniforms
frame mapping is still done in qtmultimediaquicktools, but once that's moved as well, we can radically simplify the rendering code there. Change-Id: Ia56c8b62c5726f1bfea0b0c4c46a81e103141e9e Reviewed-by: Doris Verria <doris.verria@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/multimedia/video/qvideosurfaceformat.cpp15
-rw-r--r--src/multimedia/video/qvideosurfaceformat.h2
-rw-r--r--src/qtmultimediaquicktools/qsgvideonode_rgb.cpp26
-rw-r--r--src/qtmultimediaquicktools/qsgvideonode_yuv.cpp123
4 files changed, 49 insertions, 117 deletions
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,