summaryrefslogtreecommitdiffstats
path: root/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qtmultimediaquicktools/qsgvideonode_yuv.cpp')
-rw-r--r--src/qtmultimediaquicktools/qsgvideonode_yuv.cpp407
1 files changed, 0 insertions, 407 deletions
diff --git a/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp b/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp
deleted file mode 100644
index bce757584..000000000
--- a/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp
+++ /dev/null
@@ -1,407 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include "qsgvideonode_yuv_p.h"
-#include "qsgvideotexture_p.h"
-#include <QtCore/qmutex.h>
-#include <QtQuick/qsgmaterial.h>
-
-QT_BEGIN_NAMESPACE
-
-QList<QVideoFrame::PixelFormat> QSGVideoNodeFactory_YUV::supportedPixelFormats(
- QAbstractVideoBuffer::HandleType handleType) const
-{
- QList<QVideoFrame::PixelFormat> formats;
-
- if (handleType == QAbstractVideoBuffer::NoHandle) {
- formats << QVideoFrame::Format_YUV420P << QVideoFrame::Format_YV12 << QVideoFrame::Format_YUV422P
- << QVideoFrame::Format_NV12 << QVideoFrame::Format_NV21
- << QVideoFrame::Format_UYVY << QVideoFrame::Format_YUYV;
- } else if (handleType == QAbstractVideoBuffer::GLTextureHandle) {
- formats << QVideoFrame::Format_NV12 << QVideoFrame::Format_NV21;
- } else if (handleType == QAbstractVideoBuffer::MTLTextureHandle) {
- formats << QVideoFrame::Format_NV12 << QVideoFrame::Format_NV21;
- }
-
- return formats;
-}
-
-QSGVideoNode *QSGVideoNodeFactory_YUV::createNode(const QVideoSurfaceFormat &format)
-{
- if (supportedPixelFormats(format.handleType()).contains(format.pixelFormat()))
- return new QSGVideoNode_YUV(format);
-
- return 0;
-}
-
-class QSGVideoMaterialRhiShader_YUV : public QSGMaterialShader
-{
-public:
- QSGVideoMaterialRhiShader_YUV()
- {
- setShaderFileName(VertexStage, QStringLiteral(":/qtmultimediaquicktools/shaders/yuv.vert.qsb"));
- }
-
- bool updateUniformData(RenderState &state, QSGMaterial *newMaterial,
- QSGMaterial *oldMaterial) override;
-
- void updateSampledImage(RenderState &state, int binding, QSGTexture **texture,
- QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
-
- virtual void mapFrame(QSGVideoMaterial_YUV *) = 0;
-
-protected:
- float m_planeWidth[3] = {0, 0, 0};
- QMatrix4x4 m_colorMatrix;
-};
-
-class QSGVideoMaterialRhiShader_UYVY : public QSGVideoMaterialRhiShader_YUV
-{
-public:
- QSGVideoMaterialRhiShader_UYVY()
- {
- setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimediaquicktools/shaders/uyvy.frag.qsb"));
- }
-
- void mapFrame(QSGVideoMaterial_YUV *m) override;
-};
-
-class QSGVideoMaterialRhiShader_YUYV : public QSGVideoMaterialRhiShader_UYVY
-{
-public:
- QSGVideoMaterialRhiShader_YUYV()
- {
- setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimediaquicktools/shaders/yuyv.frag.qsb"));
- }
-};
-
-class QSGVideoMaterialRhiShader_YUV_YV : public QSGVideoMaterialRhiShader_YUV
-{
-public:
- QSGVideoMaterialRhiShader_YUV_YV()
- {
- setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimediaquicktools/shaders/yuv_yv.frag.qsb"));
- }
-
- void mapFrame(QSGVideoMaterial_YUV *m) override;
-};
-
-class QSGVideoMaterialRhiShader_NV12 : public QSGVideoMaterialRhiShader_YUV
-{
-public:
- QSGVideoMaterialRhiShader_NV12()
- {
- setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimediaquicktools/shaders/nv12.frag.qsb"));
- }
-
- void mapFrame(QSGVideoMaterial_YUV *m) override;
-};
-
-class QSGVideoMaterialRhiShader_NV21 : public QSGVideoMaterialRhiShader_NV12
-{
-public:
- QSGVideoMaterialRhiShader_NV21()
- {
- setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimediaquicktools/shaders/nv21.frag.qsb"));
- }
-};
-
-class QSGVideoMaterial_YUV : public QSGMaterial
-{
-public:
- QSGVideoMaterial_YUV(const QVideoSurfaceFormat &format);
-
- QSGMaterialType *type() const override {
- static QSGMaterialType biPlanarType, biPlanarSwizzleType, triPlanarType, uyvyType, yuyvType;
-
- switch (m_format.pixelFormat()) {
- case QVideoFrame::Format_NV12:
- return &biPlanarType;
- case QVideoFrame::Format_NV21:
- return &biPlanarSwizzleType;
- case QVideoFrame::Format_UYVY:
- return &uyvyType;
- case QVideoFrame::Format_YUYV:
- return &yuyvType;
- default: // Currently: YUV420P, YUV422P and YV12
- return &triPlanarType;
- }
- }
-
- QSGMaterialShader *createShader(QSGRendererInterface::RenderMode) const override {
- switch (m_format.pixelFormat()) {
- case QVideoFrame::Format_NV12:
- return new QSGVideoMaterialRhiShader_NV12;
- case QVideoFrame::Format_NV21:
- return new QSGVideoMaterialRhiShader_NV21;
- case QVideoFrame::Format_UYVY:
- return new QSGVideoMaterialRhiShader_UYVY;
- case QVideoFrame::Format_YUYV:
- return new QSGVideoMaterialRhiShader_YUYV;
- default: // Currently: YUV420P, YUV422P and YV12
- return new QSGVideoMaterialRhiShader_YUV_YV;
- }
- }
-
- int compare(const QSGMaterial *other) const override {
- const QSGVideoMaterial_YUV *m = static_cast<const QSGVideoMaterial_YUV *>(other);
-
- qint64 diff = m_textures[0]->comparisonKey() - m->m_textures[0]->comparisonKey();
- if (!diff)
- diff = m_textures[1]->comparisonKey() - m->m_textures[1]->comparisonKey();
- if (!diff)
- diff = m_textures[2]->comparisonKey() - m->m_textures[2]->comparisonKey();
-
- return diff < 0 ? -1 : (diff > 0 ? 1 : 0);
- }
-
- void updateBlending() {
- setFlag(Blending, !qFuzzyCompare(m_opacity, float(1.0)));
- }
-
- void setCurrentFrame(const QVideoFrame &frame) {
- QMutexLocker lock(&m_frameMutex);
- m_frame = frame;
- }
-
- QVideoSurfaceFormat m_format;
- float m_planeWidth[3];
- float m_opacity;
- QMatrix4x4 m_colorMatrix;
- QVideoFrame m_frame;
- QMutex m_frameMutex;
- QScopedPointer<QSGVideoTexture> m_textures[3];
-};
-
-bool QSGVideoMaterialRhiShader_YUV::updateUniformData(RenderState &state, QSGMaterial *newMaterial,
- QSGMaterial *oldMaterial)
-{
- 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;
- }
-
- if (m->m_colorMatrix != m_colorMatrix) {
- memcpy(buf->data() + 64, m->m_colorMatrix.constData(), 64);
- changed = true;
- }
- m_colorMatrix = m->m_colorMatrix;
-
- 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();
-
- 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];
-
- return changed;
-}
-
-void QSGVideoMaterialRhiShader_YUV::updateSampledImage(RenderState &state, int binding, QSGTexture **texture,
- QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
-{
- Q_UNUSED(oldMaterial);
- if (binding < 1 || binding > 3)
- return;
-
- auto m = static_cast<QSGVideoMaterial_YUV *>(newMaterial);
- *texture = m->m_textures[binding - 1].data();
- (*texture)->commitTextureOperations(state.rhi(), state.resourceUpdateBatch());
-}
-
-void QSGVideoMaterialRhiShader_UYVY::mapFrame(QSGVideoMaterial_YUV *m)
-{
- if (!m->m_frame.isValid() || !m->m_frame.map(QAbstractVideoBuffer::ReadOnly))
- return;
-
- int fw = m->m_frame.width();
- int fh = m->m_frame.height();
-
- m->m_planeWidth[0] = 1;
- m->m_planeWidth[1] = 1;
-
- // Either r,b (YUYV) or g,a (UYVY) values are used as source of UV.
- // Additionally U and V are set per 2 pixels hence only 1/2 of image width is used.
- m->m_textures[0]->setData(QRhiTexture::RG8, m->m_frame.size(),
- m->m_frame.bits(), m->m_frame.bytesPerLine() * fh);
- m->m_textures[1]->setData(QRhiTexture::RGBA8, QSize(fw / 2, fh),
- m->m_frame.bits(), m->m_frame.bytesPerLine() * fh);
-
- m->m_frame.unmap();
-}
-
-void QSGVideoMaterialRhiShader_YUV_YV::mapFrame(QSGVideoMaterial_YUV *m)
-{
- if (!m->m_frame.isValid() || !m->m_frame.map(QAbstractVideoBuffer::ReadOnly))
- return;
-
- int y = 0;
- int u = m->m_frame.pixelFormat() == QVideoFrame::Format_YV12 ? 2 : 1;
- int v = m->m_frame.pixelFormat() == QVideoFrame::Format_YV12 ? 1 : 2;
- int fw = m->m_frame.width();
- int fh = m->m_frame.height();
- int uvHeight = m->m_frame.pixelFormat() == QVideoFrame::Format_YUV422P ? fh : fh / 2;
-
- m->m_planeWidth[0] = float(fw) / m->m_frame.bytesPerLine(y);
- m->m_planeWidth[1] = m->m_planeWidth[2] = float(fw) / (2 * m->m_frame.bytesPerLine(u));
-
- m->m_textures[0]->setData(QRhiTexture::R8, QSize(m->m_frame.bytesPerLine(y), fh),
- m->m_frame.bits(y), m->m_frame.bytesPerLine(y) * fh);
- m->m_textures[1]->setData(QRhiTexture::R8, QSize(m->m_frame.bytesPerLine(u), uvHeight),
- m->m_frame.bits(u), m->m_frame.bytesPerLine(u) * uvHeight);
- m->m_textures[2]->setData(QRhiTexture::R8, QSize(m->m_frame.bytesPerLine(v), uvHeight),
- m->m_frame.bits(v), m->m_frame.bytesPerLine(v) * uvHeight);
-
- m->m_frame.unmap();
-}
-
-void QSGVideoMaterialRhiShader_NV12::mapFrame(QSGVideoMaterial_YUV *m)
-{
- if (!m->m_frame.isValid())
- return;
-
- if (m->m_frame.handleType() == QAbstractVideoBuffer::GLTextureHandle || m->m_frame.handleType() == QAbstractVideoBuffer::MTLTextureHandle) {
- m->m_planeWidth[0] = m->m_planeWidth[1] = 1;
- auto textures = m->m_frame.handle().toList();
- if (!textures.isEmpty()) {
- auto w = m->m_frame.size().width();
- auto h = m->m_frame.size().height();
- m->m_textures[0]->setNativeObject(textures[0].toULongLong(), {w, h});
- m->m_textures[1]->setNativeObject(textures[1].toULongLong(), {w / 2, h / 2});
- } else {
- qWarning() << "NV12/NV21 requires 2 textures";
- }
-
- return;
- }
-
- if (!m->m_frame.map(QAbstractVideoBuffer::ReadOnly))
- return;
-
- int y = 0;
- int uv = 1;
- int fw = m->m_frame.width();
- int fh = m->m_frame.height();
-
- m->m_planeWidth[0] = m->m_planeWidth[1] = qreal(fw) / m->m_frame.bytesPerLine(y);
-
- m->m_textures[0]->setData(QRhiTexture::R8, m->m_frame.size(),
- m->m_frame.bits(y), m->m_frame.bytesPerLine(y) * fh);
- m->m_textures[1]->setData(QRhiTexture::RG8, QSize(m->m_frame.bytesPerLine(uv) / 2 , fh / 2),
- m->m_frame.bits(uv), m->m_frame.bytesPerLine(uv) * fh / 2);
-
- m->m_frame.unmap();
-}
-
-QSGVideoMaterial_YUV::QSGVideoMaterial_YUV(const QVideoSurfaceFormat &format) :
- m_format(format),
- m_opacity(1.0)
-{
- m_textures[0].reset(new QSGVideoTexture);
- m_textures[1].reset(new QSGVideoTexture);
- m_textures[2].reset(new QSGVideoTexture);
-
- switch (format.yCbCrColorSpace()) {
- case QVideoSurfaceFormat::YCbCr_JPEG:
- m_colorMatrix = QMatrix4x4(
- 1.0f, 0.000f, 1.402f, -0.701f,
- 1.0f, -0.344f, -0.714f, 0.529f,
- 1.0f, 1.772f, 0.000f, -0.886f,
- 0.0f, 0.000f, 0.000f, 1.0000f);
- break;
- case QVideoSurfaceFormat::YCbCr_BT709:
- case QVideoSurfaceFormat::YCbCr_xvYCC709:
- m_colorMatrix = QMatrix4x4(
- 1.164f, 0.000f, 1.793f, -0.5727f,
- 1.164f, -0.534f, -0.213f, 0.3007f,
- 1.164f, 2.115f, 0.000f, -1.1302f,
- 0.0f, 0.000f, 0.000f, 1.0000f);
- break;
- default: //BT 601:
- m_colorMatrix = QMatrix4x4(
- 1.164f, 0.000f, 1.596f, -0.8708f,
- 1.164f, -0.392f, -0.813f, 0.5296f,
- 1.164f, 2.017f, 0.000f, -1.081f,
- 0.0f, 0.000f, 0.000f, 1.0000f);
- }
-
- setFlag(Blending, false);
-}
-
-QSGVideoNode_YUV::QSGVideoNode_YUV(const QVideoSurfaceFormat &format) :
- m_format(format)
-{
- setFlag(QSGNode::OwnsMaterial);
- m_material = new QSGVideoMaterial_YUV(format);
- setMaterial(m_material);
-}
-
-QSGVideoNode_YUV::~QSGVideoNode_YUV()
-{
-}
-
-void QSGVideoNode_YUV::setCurrentFrame(const QVideoFrame &frame, FrameFlags)
-{
- m_material->setCurrentFrame(frame);
- markDirty(DirtyMaterial);
-}
-
-QT_END_NAMESPACE