summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2021-07-01 08:57:43 +0200
committerLars Knoll <lars.knoll@qt.io>2021-08-03 11:15:53 +0200
commitd6d45cf1fad8e0d246be67255c70945e6daeb849 (patch)
tree85715ad30b4dd7da25c83e9598f7f64cecd1bfb0
parent8111f1a069e8b73602dd6b70b4390cd91fb69846 (diff)
Merge QQuickVideoOutput and it's backend class
They are anyway directly coupled, the additional indirection doesn't do anything but complicate the code. Clean up handling of the RHI pointer for the video sink and properly react to window changes. Change-Id: Ic3be738b8c822ccb2d1a15f428abfe116d567ed6 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
-rw-r--r--src/multimediaquick/CMakeLists.txt1
-rw-r--r--src/multimediaquick/qquickvideooutput.cpp265
-rw-r--r--src/multimediaquick/qquickvideooutput_p.h60
-rw-r--r--src/multimediaquick/qquickvideooutput_render.cpp239
-rw-r--r--src/multimediaquick/qquickvideooutput_render_p.h124
5 files changed, 259 insertions, 430 deletions
diff --git a/src/multimediaquick/CMakeLists.txt b/src/multimediaquick/CMakeLists.txt
index eb85d0047..a7c9d468e 100644
--- a/src/multimediaquick/CMakeLists.txt
+++ b/src/multimediaquick/CMakeLists.txt
@@ -24,7 +24,6 @@ qt_internal_add_qml_module(MultimediaQuickPrivate
qquickimagepreviewprovider.cpp qquickimagepreviewprovider_p.h
# qquickplaylist.cpp qquickplaylist_p.h
qquickvideooutput.cpp qquickvideooutput_p.h
- qquickvideooutput_render.cpp qquickvideooutput_render_p.h
qsgvideonode_p.cpp qsgvideonode_p.h
qsgvideotexture.cpp qsgvideotexture_p.h
qtmultimediaquickglobal_p.h
diff --git a/src/multimediaquick/qquickvideooutput.cpp b/src/multimediaquick/qquickvideooutput.cpp
index 14b9e43d2..7af8b895e 100644
--- a/src/multimediaquick/qquickvideooutput.cpp
+++ b/src/multimediaquick/qquickvideooutput.cpp
@@ -39,13 +39,15 @@
****************************************************************************/
#include "qquickvideooutput_p.h"
-#include "qquickvideooutput_render_p.h"
#include <private/qvideooutputorientationhandler_p.h>
#include <QtMultimedia/qmediaplayer.h>
#include <QtMultimedia/qmediacapturesession.h>
#include <private/qfactoryloader_p.h>
#include <QtCore/qloggingcategory.h>
#include <qvideosink.h>
+#include <QtQuick/QQuickWindow>
+#include <private/qquickwindow_p.h>
+#include <qsgvideonode_p.h>
QT_BEGIN_NAMESPACE
@@ -124,19 +126,20 @@ Q_LOGGING_CATEGORY(qLcVideo, "qt.multimedia.video")
*/
QQuickVideoOutput::QQuickVideoOutput(QQuickItem *parent) :
- QQuickItem(parent),
- m_geometryDirty(true),
- m_orientation(0),
- m_autoOrientation(false),
- m_screenOrientationHandler(nullptr)
+ QQuickItem(parent)
{
setFlag(ItemHasContents, true);
- createBackend();
+
+ m_sink = new QVideoSink(this);
+ qRegisterMetaType<QVideoFrameFormat>();
+ QObject::connect(m_sink, SIGNAL(newVideoFrame(const QVideoFrame &)),
+ this, SLOT(_q_newFrame(const QVideoFrame &)), Qt::QueuedConnection);
+
+ initRhiForSink();
}
QQuickVideoOutput::~QQuickVideoOutput()
{
- m_backend.reset();
}
/*!
@@ -153,17 +156,7 @@ QQuickVideoOutput::~QQuickVideoOutput()
QVideoSink *QQuickVideoOutput::videoSink() const
{
- return m_backend ? m_backend->videoSink() : nullptr;
-}
-
-bool QQuickVideoOutput::createBackend()
-{
- m_backend.reset(new QQuickVideoBackend(this));
-
- // Since new backend has been created needs to update its geometry.
- m_geometryDirty = true;
-
- return true;
+ return m_sink;
}
/*!
@@ -200,10 +193,7 @@ void QQuickVideoOutput::setFillMode(FillMode mode)
void QQuickVideoOutput::_q_newFrame(const QVideoFrame &frame)
{
- if (!m_backend)
- return;
-
- m_backend->present(frame);
+ present(frame);
QSize size = frame.size();
if (!qIsDefaultAspect(m_orientation)) {
size.transpose();
@@ -251,9 +241,7 @@ void QQuickVideoOutput::_q_updateGeometry()
m_contentRect.moveCenter(rect.center());
}
- if (m_backend)
- m_backend->updateGeometry();
-
+ updateGeometry();
if (m_contentRect != oldContentRect)
emit contentRectChanged();
@@ -409,46 +397,21 @@ QRectF QQuickVideoOutput::sourceRect() const
{
// We might have to transpose back
QSizeF size = m_nativeSize;
- if (!qIsDefaultAspect(m_orientation)) {
+ if (!size.isValid())
+ return {};
+
+ if (!qIsDefaultAspect(m_orientation))
size.transpose();
- }
- // No backend? Just assume no viewport.
- if (!m_nativeSize.isValid() || !m_backend) {
- return QRectF(QPointF(), size);
- }
// Take the viewport into account for the top left position.
// m_nativeSize is already adjusted to the viewport, as it originates
// from QVideoFrameFormat::viewport(), which includes pixel aspect ratio
- const QRectF viewport = m_backend->adjustedViewport();
+ const QRectF viewport = adjustedViewport();
Q_ASSERT(viewport.size() == size);
return QRectF(viewport.topLeft(), size);
}
-QSGNode *QQuickVideoOutput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
-{
- _q_updateGeometry();
-
- if (!m_backend)
- return nullptr;
-
- return m_backend->updatePaintNode(oldNode, data);
-}
-
-void QQuickVideoOutput::itemChange(QQuickItem::ItemChange change,
- const QQuickItem::ItemChangeData &changeData)
-{
- if (m_backend)
- m_backend->itemChange(change, changeData);
-}
-
-void QQuickVideoOutput::releaseResources()
-{
- if (m_backend)
- m_backend->releaseResources();
-}
-
void QQuickVideoOutput::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_UNUSED(newGeometry);
@@ -465,8 +428,12 @@ void QQuickVideoOutput::geometryChange(const QRectF &newGeometry, const QRectF &
void QQuickVideoOutput::_q_invalidateSceneGraph()
{
- if (m_backend)
- m_backend->invalidateSceneGraph();
+ invalidateSceneGraph();
+}
+
+void QQuickVideoOutput::_q_sceneGraphInitialized()
+{
+ initRhiForSink();
}
/*!
@@ -494,4 +461,186 @@ void QQuickVideoOutput::setFlushMode(FlushMode mode)
emit flushModeChanged();
}
+void QQuickVideoOutput::releaseResources()
+{
+ // Called on the gui thread when the window is closed or changed.
+ invalidateSceneGraph();
+}
+
+void QQuickVideoOutput::invalidateSceneGraph()
+{
+ // Called on the render thread, e.g. when the context is lost.
+ // QMutexLocker lock(&m_frameMutex);
+ initRhiForSink();
+}
+
+void QQuickVideoOutput::initRhiForSink()
+{
+ QRhi *rhi = m_window ? QQuickWindowPrivate::get(m_window)->rhi : nullptr;
+ m_sink->setRhi(rhi);
+}
+
+void QQuickVideoOutput::itemChange(QQuickItem::ItemChange change,
+ const QQuickItem::ItemChangeData &changeData)
+{
+ if (change != QQuickItem::ItemSceneChange)
+ return;
+
+ if (changeData.window == m_window)
+ return;
+ if (m_window)
+ disconnect(m_window);
+ m_window = changeData.window;
+
+ if (m_window) {
+ // We want to receive the signals in the render thread
+ QObject::connect(m_window, &QQuickWindow::sceneGraphInitialized, this, &QQuickVideoOutput::_q_sceneGraphInitialized,
+ Qt::DirectConnection);
+ QObject::connect(m_window, &QQuickWindow::sceneGraphInvalidated,
+ this, &QQuickVideoOutput::_q_invalidateSceneGraph, Qt::DirectConnection);
+ }
+ initRhiForSink();
+}
+
+QSize QQuickVideoOutput::nativeSize() const
+{
+ return m_surfaceFormat.viewport().size();
+}
+
+void QQuickVideoOutput::updateGeometry()
+{
+ const QRectF viewport = m_surfaceFormat.viewport();
+ const QSizeF frameSize = m_surfaceFormat.frameSize();
+ const QRectF normalizedViewport(viewport.x() / frameSize.width(),
+ viewport.y() / frameSize.height(),
+ viewport.width() / frameSize.width(),
+ viewport.height() / frameSize.height());
+ const QRectF rect(0, 0, width(), height());
+ if (nativeSize().isEmpty()) {
+ m_renderedRect = rect;
+ m_sourceTextureRect = normalizedViewport;
+ } else if (fillMode() == QQuickVideoOutput::Stretch) {
+ m_renderedRect = rect;
+ m_sourceTextureRect = normalizedViewport;
+ } else if (fillMode() == QQuickVideoOutput::PreserveAspectFit) {
+ m_sourceTextureRect = normalizedViewport;
+ m_renderedRect = contentRect();
+ } else if (fillMode() == QQuickVideoOutput::PreserveAspectCrop) {
+ m_renderedRect = rect;
+ const qreal contentHeight = contentRect().height();
+ const qreal contentWidth = contentRect().width();
+
+ // Calculate the size of the source rectangle without taking the viewport into account
+ const qreal relativeOffsetLeft = -contentRect().left() / contentWidth;
+ const qreal relativeOffsetTop = -contentRect().top() / contentHeight;
+ const qreal relativeWidth = rect.width() / contentWidth;
+ const qreal relativeHeight = rect.height() / contentHeight;
+
+ // Now take the viewport size into account
+ const qreal totalOffsetLeft = normalizedViewport.x() + relativeOffsetLeft * normalizedViewport.width();
+ const qreal totalOffsetTop = normalizedViewport.y() + relativeOffsetTop * normalizedViewport.height();
+ const qreal totalWidth = normalizedViewport.width() * relativeWidth;
+ const qreal totalHeight = normalizedViewport.height() * relativeHeight;
+
+ if (qIsDefaultAspect(orientation())) {
+ m_sourceTextureRect = QRectF(totalOffsetLeft, totalOffsetTop,
+ totalWidth, totalHeight);
+ } else {
+ m_sourceTextureRect = QRectF(totalOffsetTop, totalOffsetLeft,
+ totalHeight, totalWidth);
+ }
+ }
+
+ if (m_surfaceFormat.scanLineDirection() == QVideoFrameFormat::BottomToTop) {
+ qreal top = m_sourceTextureRect.top();
+ m_sourceTextureRect.setTop(m_sourceTextureRect.bottom());
+ m_sourceTextureRect.setBottom(top);
+ }
+
+ if (m_surfaceFormat.isMirrored()) {
+ qreal left = m_sourceTextureRect.left();
+ m_sourceTextureRect.setLeft(m_sourceTextureRect.right());
+ m_sourceTextureRect.setRight(left);
+ }
+}
+
+QSGNode *QQuickVideoOutput::updatePaintNode(QSGNode *oldNode,
+ QQuickItem::UpdatePaintNodeData *data)
+{
+ Q_UNUSED(data);
+ _q_updateGeometry();
+
+ QSGVideoNode *videoNode = static_cast<QSGVideoNode *>(oldNode);
+
+ QMutexLocker lock(&m_frameMutex);
+
+ if (m_frameChanged) {
+ if (videoNode && videoNode->pixelFormat() != m_frame.pixelFormat()) {
+ qCDebug(qLcVideo) << "updatePaintNode: deleting old video node because frame format changed";
+ delete videoNode;
+ videoNode = nullptr;
+ }
+
+ if (!m_frame.isValid()) {
+ qCDebug(qLcVideo) << "updatePaintNode: no frames yet";
+ m_frameChanged = false;
+ return nullptr;
+ }
+
+ if (!videoNode) {
+ // Get a node that supports our frame. The surface is irrelevant, our
+ // QSGVideoItemSurface supports (logically) anything.
+ updateGeometry();
+ videoNode = new QSGVideoNode(m_surfaceFormat);
+ qCDebug(qLcVideo) << "updatePaintNode: Video node created. Handle type:" << m_frame.handleType();
+ }
+ }
+
+ if (!videoNode) {
+ m_frameChanged = false;
+ m_frame = QVideoFrame();
+ return nullptr;
+ }
+
+ // Negative rotations need lots of %360
+ videoNode->setTexturedRectGeometry(m_renderedRect, m_sourceTextureRect,
+ qNormalizedOrientation(orientation()));
+ if (m_frameChanged) {
+ videoNode->setCurrentFrame(m_frame);
+
+ if ((flushMode() == QQuickVideoOutput::FirstFrame && !m_frameOnFlush.isValid())
+ || flushMode() == QQuickVideoOutput::LastFrame) {
+ m_frameOnFlush = m_frame;
+ }
+
+ //don't keep the frame for more than really necessary
+ m_frameChanged = false;
+ m_frame = QVideoFrame();
+ }
+ return videoNode;
+}
+
+QRectF QQuickVideoOutput::adjustedViewport() const
+{
+ return m_surfaceFormat.viewport();
+}
+
+void QQuickVideoOutput::present(const QVideoFrame &frame)
+{
+ m_frameMutex.lock();
+ m_surfaceFormat = frame.surfaceFormat();
+ m_frame = frame.isValid() ? frame : m_frameOnFlush;
+ m_frameChanged = true;
+ m_frameMutex.unlock();
+
+ update();
+}
+
+void QQuickVideoOutput::stop()
+{
+ present(QVideoFrame());
+}
+
QT_END_NAMESPACE
+
+#include "moc_qquickvideooutput_p.cpp"
diff --git a/src/multimediaquick/qquickvideooutput_p.h b/src/multimediaquick/qquickvideooutput_p.h
index dd5f4b29f..181f273dc 100644
--- a/src/multimediaquick/qquickvideooutput_p.h
+++ b/src/multimediaquick/qquickvideooutput_p.h
@@ -56,15 +56,17 @@
#include <QtCore/qsharedpointer.h>
#include <QtQuick/qquickitem.h>
#include <QtCore/qpointer.h>
+#include <QtCore/qmutex.h>
#include <private/qtmultimediaquickglobal_p.h>
+#include <qvideoframe.h>
+#include <qvideoframeformat.h>
QT_BEGIN_NAMESPACE
class QQuickVideoBackend;
class QVideoOutputOrientationHandler;
class QVideoSink;
-class QVideoFrame;
class Q_MULTIMEDIAQUICK_EXPORT QQuickVideoOutput : public QQuickItem
{
@@ -134,29 +136,71 @@ protected:
void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
void releaseResources() override;
+private:
+ QSize nativeSize() const;
+ void updateGeometry();
+ QRectF adjustedViewport() const;
+
+ friend class QSGVideoItemSurface;
+ void present(const QVideoFrame &frame);
+ void stop();
+
+ void invalidateSceneGraph();
+
+ void initRhiForSink();
+
private Q_SLOTS:
void _q_newFrame(const QVideoFrame &);
void _q_updateGeometry();
void _q_screenOrientationChanged(int);
void _q_invalidateSceneGraph();
+ void _q_sceneGraphInitialized();
private:
- bool createBackend();
-
QSize m_nativeSize;
- bool m_geometryDirty;
+ bool m_geometryDirty = true;
QRectF m_lastRect; // Cache of last rect to avoid recalculating geometry
QRectF m_contentRect; // Destination pixel coordinates, unclipped
- int m_orientation;
- bool m_autoOrientation;
- QVideoOutputOrientationHandler *m_screenOrientationHandler;
+ int m_orientation = 0;
+ bool m_autoOrientation = false;
+ QVideoOutputOrientationHandler *m_screenOrientationHandler = nullptr;
- QScopedPointer<QQuickVideoBackend> m_backend;
+ QPointer<QQuickWindow> m_window;
+ QVideoSink *m_sink = nullptr;
+ QVideoFrameFormat m_surfaceFormat;
+
+ QVideoFrame m_frame;
+ QVideoFrame m_frameOnFlush;
+ bool m_frameChanged = false;
+ QMutex m_frameMutex;
+ QRectF m_renderedRect; // Destination pixel coordinates, clipped
+ QRectF m_sourceTextureRect; // Source texture coordinates
FlushMode m_flushMode = EmptyFrame;
};
+namespace {
+
+inline bool qIsDefaultAspect(int o)
+{
+ return (o % 180) == 0;
+}
+
+/*
+ * Return the orientation normalized to 0-359
+ */
+inline int qNormalizedOrientation(int o)
+{
+ // Negative orientations give negative results
+ int o2 = o % 360;
+ if (o2 < 0)
+ o2 += 360;
+ return o2;
+}
+
+}
+
QT_END_NAMESPACE
#endif // QQUICKVIDEOOUTPUT_P_H
diff --git a/src/multimediaquick/qquickvideooutput_render.cpp b/src/multimediaquick/qquickvideooutput_render.cpp
deleted file mode 100644
index 042d11c6f..000000000
--- a/src/multimediaquick/qquickvideooutput_render.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Copyright (C) 2016 Research In Motion
-** 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 "qquickvideooutput_render_p.h"
-#include "qquickvideooutput_p.h"
-#include <QtCore/qobject.h>
-#include <QtCore/qloggingcategory.h>
-#include <private/qsgvideonode_p.h>
-#include <qvideosink.h>
-
-#include <QtQuick/QQuickWindow>
-#include <private/qquickwindow_p.h>
-#include <QtCore/QRunnable>
-
-QT_BEGIN_NAMESPACE
-
-Q_DECLARE_LOGGING_CATEGORY(qLcVideo)
-
-QQuickVideoBackend::QQuickVideoBackend(QQuickVideoOutput *parent)
- : q(parent),
- m_frameChanged(false)
-{
-}
-
-QQuickVideoBackend::~QQuickVideoBackend()
-{
- delete m_sink;
-}
-
-void QQuickVideoBackend::releaseResources()
-{
- // Called on the gui thread when the window is closed or changed.
- invalidateSceneGraph();
-}
-
-void QQuickVideoBackend::invalidateSceneGraph()
-{
- // Called on the render thread, e.g. when the context is lost.
-// QMutexLocker lock(&m_frameMutex);
-}
-
-void QQuickVideoBackend::itemChange(QQuickItem::ItemChange change,
- const QQuickItem::ItemChangeData &changeData)
-{
- if (change == QQuickItem::ItemSceneChange) {
- if (changeData.window)
- QObject::connect(changeData.window, SIGNAL(sceneGraphInvalidated()),
- q, SLOT(_q_invalidateSceneGraph()), Qt::DirectConnection);
- }
-}
-
-QSize QQuickVideoBackend::nativeSize() const
-{
- return m_surfaceFormat.viewport().size();
-}
-
-void QQuickVideoBackend::updateGeometry()
-{
- const QRectF viewport = m_surfaceFormat.viewport();
- const QSizeF frameSize = m_surfaceFormat.frameSize();
- const QRectF normalizedViewport(viewport.x() / frameSize.width(),
- viewport.y() / frameSize.height(),
- viewport.width() / frameSize.width(),
- viewport.height() / frameSize.height());
- const QRectF rect(0, 0, q->width(), q->height());
- if (nativeSize().isEmpty()) {
- m_renderedRect = rect;
- m_sourceTextureRect = normalizedViewport;
- } else if (q->fillMode() == QQuickVideoOutput::Stretch) {
- m_renderedRect = rect;
- m_sourceTextureRect = normalizedViewport;
- } else if (q->fillMode() == QQuickVideoOutput::PreserveAspectFit) {
- m_sourceTextureRect = normalizedViewport;
- m_renderedRect = q->contentRect();
- } else if (q->fillMode() == QQuickVideoOutput::PreserveAspectCrop) {
- m_renderedRect = rect;
- const qreal contentHeight = q->contentRect().height();
- const qreal contentWidth = q->contentRect().width();
-
- // Calculate the size of the source rectangle without taking the viewport into account
- const qreal relativeOffsetLeft = -q->contentRect().left() / contentWidth;
- const qreal relativeOffsetTop = -q->contentRect().top() / contentHeight;
- const qreal relativeWidth = rect.width() / contentWidth;
- const qreal relativeHeight = rect.height() / contentHeight;
-
- // Now take the viewport size into account
- const qreal totalOffsetLeft = normalizedViewport.x() + relativeOffsetLeft * normalizedViewport.width();
- const qreal totalOffsetTop = normalizedViewport.y() + relativeOffsetTop * normalizedViewport.height();
- const qreal totalWidth = normalizedViewport.width() * relativeWidth;
- const qreal totalHeight = normalizedViewport.height() * relativeHeight;
-
- if (qIsDefaultAspect(q->orientation())) {
- m_sourceTextureRect = QRectF(totalOffsetLeft, totalOffsetTop,
- totalWidth, totalHeight);
- } else {
- m_sourceTextureRect = QRectF(totalOffsetTop, totalOffsetLeft,
- totalHeight, totalWidth);
- }
- }
-
- if (m_surfaceFormat.scanLineDirection() == QVideoFrameFormat::BottomToTop) {
- qreal top = m_sourceTextureRect.top();
- m_sourceTextureRect.setTop(m_sourceTextureRect.bottom());
- m_sourceTextureRect.setBottom(top);
- }
-
- if (m_surfaceFormat.isMirrored()) {
- qreal left = m_sourceTextureRect.left();
- m_sourceTextureRect.setLeft(m_sourceTextureRect.right());
- m_sourceTextureRect.setRight(left);
- }
-}
-
-QSGNode *QQuickVideoBackend::updatePaintNode(QSGNode *oldNode,
- QQuickItem::UpdatePaintNodeData *data)
-{
- Q_UNUSED(data);
- QSGVideoNode *videoNode = static_cast<QSGVideoNode *>(oldNode);
-
- QMutexLocker lock(&m_frameMutex);
-
- if (m_frameChanged) {
- if (videoNode && videoNode->pixelFormat() != m_frame.pixelFormat()) {
- qCDebug(qLcVideo) << "updatePaintNode: deleting old video node because frame format changed";
- delete videoNode;
- videoNode = nullptr;
- }
-
- if (!m_frame.isValid()) {
- qCDebug(qLcVideo) << "updatePaintNode: no frames yet";
- m_frameChanged = false;
- return nullptr;
- }
-
- if (!videoNode) {
- // Get a node that supports our frame. The surface is irrelevant, our
- // QSGVideoItemSurface supports (logically) anything.
- updateGeometry();
- videoNode = new QSGVideoNode(m_surfaceFormat);
- qCDebug(qLcVideo) << "updatePaintNode: Video node created. Handle type:" << m_frame.handleType();
- }
- }
-
- if (!videoNode) {
- m_frameChanged = false;
- m_frame = QVideoFrame();
- return nullptr;
- }
-
- // Negative rotations need lots of %360
- videoNode->setTexturedRectGeometry(m_renderedRect, m_sourceTextureRect,
- qNormalizedOrientation(q->orientation()));
- if (m_frameChanged) {
- videoNode->setCurrentFrame(m_frame);
-
- if ((q->flushMode() == QQuickVideoOutput::FirstFrame && !m_frameOnFlush.isValid())
- || q->flushMode() == QQuickVideoOutput::LastFrame) {
- m_frameOnFlush = m_frame;
- }
-
- //don't keep the frame for more than really necessary
- m_frameChanged = false;
- m_frame = QVideoFrame();
- }
- return videoNode;
-}
-
-QVideoSink *QQuickVideoBackend::videoSink() const
-{
- if (!m_sink) {
- m_sink = new QVideoSink(q);
- if (q->window())
- m_sink->setRhi(QQuickWindowPrivate::get(q->window())->rhi);
- qRegisterMetaType<QVideoFrameFormat>();
- QObject::connect(m_sink, SIGNAL(newVideoFrame(const QVideoFrame &)),
- q, SLOT(_q_newFrame(const QVideoFrame &)), Qt::QueuedConnection);
- }
- return m_sink;
-}
-
-QRectF QQuickVideoBackend::adjustedViewport() const
-{
- return m_surfaceFormat.viewport();
-}
-
-void QQuickVideoBackend::present(const QVideoFrame &frame)
-{
- m_frameMutex.lock();
- m_surfaceFormat = frame.surfaceFormat();
- m_frame = frame.isValid() ? frame : m_frameOnFlush;
- m_frameChanged = true;
- m_frameMutex.unlock();
-
- q->update();
-}
-
-void QQuickVideoBackend::stop()
-{
- present(QVideoFrame());
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimediaquick/qquickvideooutput_render_p.h b/src/multimediaquick/qquickvideooutput_render_p.h
deleted file mode 100644
index beabd456e..000000000
--- a/src/multimediaquick/qquickvideooutput_render_p.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Copyright (C) 2016 Research In Motion
-** 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$
-**
-****************************************************************************/
-
-#ifndef QQUICKVIDEOOUTPUT_RENDER_P_H
-#define QQUICKVIDEOOUTPUT_RENDER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtQuick/qquickitem.h>
-#include <QtQuick/qsgnode.h>
-#include <private/qsgvideonode_p.h>
-
-#include <QtCore/qmutex.h>
-
-QT_BEGIN_NAMESPACE
-
-class QVideoSink;
-class QObject;
-class QQuickVideoOutput;
-
-class QQuickVideoBackend
-{
-public:
- QQuickVideoBackend(QQuickVideoOutput *parent);
- ~QQuickVideoBackend();
-
- void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &changeData);
- QSize nativeSize() const;
- void updateGeometry();
- QSGNode *updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *data);
- QVideoSink *videoSink() const;
- QRectF adjustedViewport() const;
-
- friend class QSGVideoItemSurface;
- void present(const QVideoFrame &frame);
- void stop();
-
- void releaseResources();
- void invalidateSceneGraph();
-
-private:
- QQuickVideoOutput *q;
-
- mutable QVideoSink *m_sink = nullptr;
- QVideoFrameFormat m_surfaceFormat;
-
- QVideoFrame m_frame;
- QVideoFrame m_frameOnFlush;
- bool m_frameChanged;
- QMutex m_frameMutex;
- QRectF m_renderedRect; // Destination pixel coordinates, clipped
- QRectF m_sourceTextureRect; // Source texture coordinates
-};
-
-namespace {
-
-inline bool qIsDefaultAspect(int o)
-{
- return (o % 180) == 0;
-}
-
-/*
- * Return the orientation normalized to 0-359
- */
-inline int qNormalizedOrientation(int o)
-{
- // Negative orientations give negative results
- int o2 = o % 360;
- if (o2 < 0)
- o2 += 360;
- return o2;
-}
-
-}
-
-QT_END_NAMESPACE
-
-#endif