summaryrefslogtreecommitdiffstats
path: root/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den.exter@jollamobile.com>2013-12-05 15:38:14 +1000
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-20 14:26:03 +0100
commit60fb11d9a2f5ff659a6ccffe01b4de16c1fb5929 (patch)
tree9b715c70d25f1b46b3a4caf46e58cb1caa0ad34f /src/qtmultimediaquicktools/qdeclarativevideooutput.cpp
parenta52f552d4274eeaeb3a7362c509e77df501b1349 (diff)
Allow plugins to override the QML VideoOutput type.
Move QDeclarativeVideoOutput to the private QtMultimediaQuickTools library to make the QDeclarativeVideoOutputBackend interface implementable by a plugin. Change-Id: I763c483a1fc9ec56dc7b8be0bc71523f029a36ee Reviewed-by: Yoann Lopes <yoann.lopes@digia.com>
Diffstat (limited to 'src/qtmultimediaquicktools/qdeclarativevideooutput.cpp')
-rw-r--r--src/qtmultimediaquicktools/qdeclarativevideooutput.cpp760
1 files changed, 760 insertions, 0 deletions
diff --git a/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp b/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp
new file mode 100644
index 000000000..321fd5e81
--- /dev/null
+++ b/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp
@@ -0,0 +1,760 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2012 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qdeclarativevideooutput_p.h"
+
+#include "qdeclarativevideooutput_render_p.h"
+#include "qdeclarativevideooutput_window_p.h"
+#include <private/qvideooutputorientationhandler_p.h>
+#include <QtMultimedia/qmediaobject.h>
+#include <QtMultimedia/qmediaservice.h>
+#include <private/qmediapluginloader_p.h>
+
+//#define DEBUG_VIDEOITEM
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype VideoOutput
+ \instantiates QDeclarativeVideoOutput
+ \brief Render video or camera viewfinder.
+
+ \ingroup multimedia_qml
+ \ingroup multimedia_video_qml
+ \inqmlmodule QtMultimedia
+
+ \c VideoOutput is part of the \b{QtMultimedia 5.0} module.
+
+ \qml
+ import QtQuick 2.0
+ import QtMultimedia 5.0
+
+ Rectangle {
+ width: 800
+ height: 600
+ color: "black"
+
+ MediaPlayer {
+ id: player
+ source: "file://video.webm"
+ autoPlay: true
+ }
+
+ VideoOutput {
+ id: videoOutput
+ source: player
+ anchors.fill: parent
+ }
+ }
+
+ \endqml
+
+ The VideoOutput item supports untransformed, stretched, and uniformly scaled video presentation.
+ For a description of stretched uniformly scaled presentation, see the \l fillMode property
+ description.
+
+ The VideoOutput item works with backends that support either QVideoRendererControl or
+ QVideoWindowControl. If the backend only supports QVideoWindowControl, the video is rendered
+ onto an overlay window that is layered on top of the QtQuick window. Due to the nature of the
+ video overlays, certain features are not available for these kind of backends:
+ \list
+ \li Some transformations like rotations
+ \li Having other QtQuick items on top of the VideoOutput item
+ \endlist
+ Most backends however do support QVideoRendererControl and therefore don't have the limitations
+ listed above.
+
+ \sa MediaPlayer, Camera
+
+ \section1 Screen Saver
+
+ If it is likely that an application will be playing video for an extended
+ period of time without user interaction it may be necessary to disable
+ the platform's screen saver. The \l ScreenSaver (from \l QtSystemInfo)
+ may be used to disable the screensaver in this fashion:
+
+ \qml
+ import QtSystemInfo 5.0
+
+ ScreenSaver { screenSaverEnabled: false }
+ \endqml
+*/
+
+/*!
+ \internal
+ \class QDeclarativeVideoOutput
+ \brief The QDeclarativeVideoOutput class provides a video output item.
+*/
+
+QDeclarativeVideoOutput::QDeclarativeVideoOutput(QQuickItem *parent) :
+ QQuickItem(parent),
+ m_sourceType(NoSource),
+ m_fillMode(PreserveAspectFit),
+ m_geometryDirty(true),
+ m_orientation(0),
+ m_autoOrientation(false),
+ m_screenOrientationHandler(0)
+{
+ setFlag(ItemHasContents, true);
+}
+
+QDeclarativeVideoOutput::~QDeclarativeVideoOutput()
+{
+ m_backend.reset();
+ m_source.clear();
+ _q_updateMediaObject();
+}
+
+/*!
+ \qmlproperty variant QtMultimedia::VideoOutput::source
+
+ This property holds the source item providing the video frames like MediaPlayer or Camera.
+
+ If you are extending your own C++ classes to interoperate with VideoOutput, you can
+ either provide a QObject based class with a \c mediaObject property that exposes a
+ QMediaObject derived class that has a QVideoRendererControl available, or you can
+ provide a QObject based class with a writable \c videoSurface property that can
+ accept a QAbstractVideoSurface based class and can follow the correct protocol to
+ deliver QVideoFrames to it.
+*/
+
+void QDeclarativeVideoOutput::setSource(QObject *source)
+{
+#ifdef DEBUG_VIDEOITEM
+ qDebug() << Q_FUNC_INFO << source;
+#endif
+
+ if (source == m_source.data())
+ return;
+
+ if (m_source && m_sourceType == MediaObjectSource)
+ disconnect(m_source.data(), 0, this, SLOT(_q_updateMediaObject()));
+
+ if (m_backend)
+ m_backend->releaseSource();
+
+ m_source = source;
+
+ if (m_source) {
+ const QMetaObject *metaObject = m_source.data()->metaObject();
+
+ int mediaObjectPropertyIndex = metaObject->indexOfProperty("mediaObject");
+ if (mediaObjectPropertyIndex != -1) {
+ const QMetaProperty mediaObjectProperty = metaObject->property(mediaObjectPropertyIndex);
+
+ if (mediaObjectProperty.hasNotifySignal()) {
+ QMetaMethod method = mediaObjectProperty.notifySignal();
+ QMetaObject::connect(m_source.data(), method.methodIndex(),
+ this, this->metaObject()->indexOfSlot("_q_updateMediaObject()"),
+ Qt::DirectConnection, 0);
+
+ }
+ m_sourceType = MediaObjectSource;
+ } else if (metaObject->indexOfProperty("videoSurface") != -1) {
+ // Make sure our backend is a QDeclarativeVideoRendererBackend
+ m_backend.reset();
+ createBackend(0);
+ Q_ASSERT(m_backend);
+#ifndef QT_NO_DYNAMIC_CAST
+ Q_ASSERT(dynamic_cast<QDeclarativeVideoRendererBackend *>(m_backend.data()));
+#endif
+ QAbstractVideoSurface * const surface = m_backend->videoSurface();
+ Q_ASSERT(surface);
+ m_source.data()->setProperty("videoSurface",
+ QVariant::fromValue<QAbstractVideoSurface*>(surface));
+ m_sourceType = VideoSurfaceSource;
+ } else {
+ m_sourceType = NoSource;
+ }
+ } else {
+ m_sourceType = NoSource;
+ }
+
+ _q_updateMediaObject();
+ emit sourceChanged();
+}
+
+Q_GLOBAL_STATIC_WITH_ARGS(QMediaPluginLoader, videoBackendFactoryLoader,
+ (QDeclarativeVideoBackendFactoryInterface_iid, QLatin1String("video/declarativevideobackend"), Qt::CaseInsensitive))
+
+bool QDeclarativeVideoOutput::createBackend(QMediaService *service)
+{
+ bool backendAvailable = false;
+
+ foreach (QObject *instance, videoBackendFactoryLoader()->instances(QLatin1String("declarativevideobackend"))) {
+ if (QDeclarativeVideoBackendFactoryInterface *plugin = qobject_cast<QDeclarativeVideoBackendFactoryInterface*>(instance)) {
+ m_backend.reset(plugin->create(this));
+ if (m_backend && m_backend->init(service)) {
+ backendAvailable = true;
+ break;
+ }
+ }
+ }
+
+ if (!backendAvailable) {
+ m_backend.reset(new QDeclarativeVideoRendererBackend(this));
+ if (m_backend->init(service))
+ backendAvailable = true;
+ }
+
+ // QDeclarativeVideoWindowBackend only works when there is a service with a QVideoWindowControl.
+ // Without service, the QDeclarativeVideoRendererBackend should always work.
+ if (!backendAvailable) {
+ Q_ASSERT(service);
+ m_backend.reset(new QDeclarativeVideoWindowBackend(this));
+ if (m_backend->init(service))
+ backendAvailable = true;
+ }
+
+ if (!backendAvailable) {
+ qWarning() << Q_FUNC_INFO << "Media service has neither renderer nor window control available.";
+ m_backend.reset();
+ }
+ return backendAvailable;
+}
+
+void QDeclarativeVideoOutput::_q_updateMediaObject()
+{
+ QMediaObject *mediaObject = 0;
+
+ if (m_source)
+ mediaObject = qobject_cast<QMediaObject*>(m_source.data()->property("mediaObject").value<QObject*>());
+
+#ifdef DEBUG_VIDEOITEM
+ qDebug() << Q_FUNC_INFO << mediaObject;
+#endif
+
+ if (m_mediaObject.data() == mediaObject)
+ return;
+
+ if (m_sourceType != VideoSurfaceSource)
+ m_backend.reset();
+
+ m_mediaObject.clear();
+ m_service.clear();
+
+ if (mediaObject) {
+ if (QMediaService *service = mediaObject->service()) {
+ if (createBackend(service)) {
+ m_service = service;
+ m_mediaObject = mediaObject;
+ }
+ }
+ }
+}
+
+/*!
+ \qmlproperty enumeration QtMultimedia::VideoOutput::fillMode
+
+ Set this property to define how the video is scaled to fit the target area.
+
+ \list
+ \li Stretch - the video is scaled to fit.
+ \li PreserveAspectFit - the video is scaled uniformly to fit without cropping
+ \li PreserveAspectCrop - the video is scaled uniformly to fill, cropping if necessary
+ \endlist
+
+ The default fill mode is PreserveAspectFit.
+*/
+
+QDeclarativeVideoOutput::FillMode QDeclarativeVideoOutput::fillMode() const
+{
+ return m_fillMode;
+}
+
+void QDeclarativeVideoOutput::setFillMode(FillMode mode)
+{
+ if (mode == m_fillMode)
+ return;
+
+ m_fillMode = mode;
+ m_geometryDirty = true;
+ update();
+
+ emit fillModeChanged(mode);
+}
+
+void QDeclarativeVideoOutput::_q_updateNativeSize()
+{
+ if (!m_backend)
+ return;
+
+ QSize size = m_backend->nativeSize();
+ if (!qIsDefaultAspect(m_orientation)) {
+ size.transpose();
+ }
+
+ if (m_nativeSize != size) {
+ m_nativeSize = size;
+
+ m_geometryDirty = true;
+
+ setImplicitWidth(size.width());
+ setImplicitHeight(size.height());
+
+ emit sourceRectChanged();
+ }
+}
+
+/* Based on fill mode and our size, figure out the source/dest rects */
+void QDeclarativeVideoOutput::_q_updateGeometry()
+{
+ const QRectF rect(0, 0, width(), height());
+ const QRectF absoluteRect(x(), y(), width(), height());
+
+ if (!m_geometryDirty && m_lastRect == absoluteRect)
+ return;
+
+ QRectF oldContentRect(m_contentRect);
+
+ m_geometryDirty = false;
+ m_lastRect = absoluteRect;
+
+ if (m_nativeSize.isEmpty()) {
+ //this is necessary for item to receive the
+ //first paint event and configure video surface.
+ m_contentRect = rect;
+ } else if (m_fillMode == Stretch) {
+ m_contentRect = rect;
+ } else if (m_fillMode == PreserveAspectFit || m_fillMode == PreserveAspectCrop) {
+ QSizeF scaled = m_nativeSize;
+ scaled.scale(rect.size(), m_fillMode == PreserveAspectFit ?
+ Qt::KeepAspectRatio : Qt::KeepAspectRatioByExpanding);
+
+ m_contentRect = QRectF(QPointF(), scaled);
+ m_contentRect.moveCenter(rect.center());
+ }
+
+ if (m_backend)
+ m_backend->updateGeometry();
+
+ if (m_contentRect != oldContentRect)
+ emit contentRectChanged();
+}
+
+void QDeclarativeVideoOutput::_q_screenOrientationChanged(int orientation)
+{
+ setOrientation(orientation);
+}
+
+/*!
+ \qmlproperty int QtMultimedia::VideoOutput::orientation
+
+ In some cases the source video stream requires a certain
+ orientation to be correct. This includes
+ sources like a camera viewfinder, where the displayed
+ viewfinder should match reality, no matter what rotation
+ the rest of the user interface has.
+
+ This property allows you to apply a rotation (in steps
+ of 90 degrees) to compensate for any user interface
+ rotation, with positive values in the anti-clockwise direction.
+
+ The orientation change will also affect the mapping
+ of coordinates from source to viewport.
+*/
+int QDeclarativeVideoOutput::orientation() const
+{
+ return m_orientation;
+}
+
+void QDeclarativeVideoOutput::setOrientation(int orientation)
+{
+ // Make sure it's a multiple of 90.
+ if (orientation % 90)
+ return;
+
+ // If there's no actual change, return
+ if (m_orientation == orientation)
+ return;
+
+ // If the new orientation is the same effect
+ // as the old one, don't update the video node stuff
+ if ((m_orientation % 360) == (orientation % 360)) {
+ m_orientation = orientation;
+ emit orientationChanged();
+ return;
+ }
+
+ m_geometryDirty = true;
+
+ // Otherwise, a new orientation
+ // See if we need to change aspect ratio orientation too
+ bool oldAspect = qIsDefaultAspect(m_orientation);
+ bool newAspect = qIsDefaultAspect(orientation);
+
+ m_orientation = orientation;
+
+ if (oldAspect != newAspect) {
+ m_nativeSize.transpose();
+
+ setImplicitWidth(m_nativeSize.width());
+ setImplicitHeight(m_nativeSize.height());
+
+ // Source rectangle does not change for orientation
+ }
+
+ update();
+ emit orientationChanged();
+}
+
+/*!
+ \qmlproperty int QtMultimedia::VideoOutput::autoOrientation
+
+ This property allows you to enable and disable auto orientation
+ of the video stream, so that its orientation always matches
+ the orientation of the screen. If \c autoOrientation is enabled,
+ the \c orientation property is overwritten.
+
+ By default \c autoOrientation is disabled.
+
+ \since QtMultimedia 5.2
+*/
+bool QDeclarativeVideoOutput::autoOrientation() const
+{
+ return m_autoOrientation;
+}
+
+void QDeclarativeVideoOutput::setAutoOrientation(bool autoOrientation)
+{
+ if (autoOrientation == m_autoOrientation)
+ return;
+
+ m_autoOrientation = autoOrientation;
+ if (m_autoOrientation) {
+ m_screenOrientationHandler = new QVideoOutputOrientationHandler(this);
+ connect(m_screenOrientationHandler, SIGNAL(orientationChanged(int)),
+ this, SLOT(_q_screenOrientationChanged(int)));
+
+ _q_screenOrientationChanged(m_screenOrientationHandler->currentOrientation());
+ } else {
+ disconnect(m_screenOrientationHandler, SIGNAL(orientationChanged(int)),
+ this, SLOT(_q_screenOrientationChanged(int)));
+ m_screenOrientationHandler->deleteLater();
+ m_screenOrientationHandler = 0;
+ }
+
+ emit autoOrientationChanged();
+}
+
+/*!
+ \qmlproperty rectangle QtMultimedia::VideoOutput::contentRect
+
+ This property holds the item coordinates of the area that
+ would contain video to render. With certain fill modes,
+ this rectangle will be larger than the visible area of the
+ \c VideoOutput.
+
+ This property is useful when other coordinates are specified
+ in terms of the source dimensions - this applied for relative
+ (normalized) frame coordinates in the range of 0 to 1.0.
+
+ \sa mapRectToItem(), mapPointToItem()
+
+ Areas outside this will be transparent.
+*/
+QRectF QDeclarativeVideoOutput::contentRect() const
+{
+ return m_contentRect;
+}
+
+/*!
+ \qmlproperty rectangle QtMultimedia::VideoOutput::sourceRect
+
+ This property holds the area of the source video
+ content that is considered for rendering. The
+ values are in source pixel coordinates, adjusted for
+ the source's pixel aspect ratio.
+
+ Note that typically the top left corner of this rectangle
+ will be \c {0,0} while the width and height will be the
+ width and height of the input content. Only when the video
+ source has a viewport set, these values will differ.
+
+ The orientation setting does not affect this rectangle.
+
+ \sa QVideoSurfaceFormat::pixelAspectRatio()
+ \sa QVideoSurfaceFormat::viewport()
+*/
+QRectF QDeclarativeVideoOutput::sourceRect() const
+{
+ // We might have to transpose back
+ QSizeF size = m_nativeSize;
+ 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 originats
+ // from QVideoSurfaceFormat::sizeHint(), which includes pixel aspect
+ // ratio and viewport.
+ const QRectF viewport = m_backend->adjustedViewport();
+ Q_ASSERT(viewport.size() == size);
+ return QRectF(viewport.topLeft(), size);
+}
+
+/*!
+ \qmlmethod QPointF QtMultimedia::VideoOutput::mapNormalizedPointToItem (const QPointF &point) const
+
+ Given normalized coordinates \a point (that is, each
+ component in the range of 0 to 1.0), return the mapped point
+ that it corresponds to (in item coordinates).
+ This mapping is affected by the orientation.
+
+ Depending on the fill mode, this point may lie outside the rendered
+ rectangle.
+ */
+QPointF QDeclarativeVideoOutput::mapNormalizedPointToItem(const QPointF &point) const
+{
+ qreal dx = point.x();
+ qreal dy = point.y();
+
+ if (qIsDefaultAspect(m_orientation)) {
+ dx *= m_contentRect.width();
+ dy *= m_contentRect.height();
+ } else {
+ dx *= m_contentRect.height();
+ dy *= m_contentRect.width();
+ }
+
+ switch (qNormalizedOrientation(m_orientation)) {
+ case 0:
+ default:
+ return m_contentRect.topLeft() + QPointF(dx, dy);
+ case 90:
+ return m_contentRect.bottomLeft() + QPointF(dy, -dx);
+ case 180:
+ return m_contentRect.bottomRight() + QPointF(-dx, -dy);
+ case 270:
+ return m_contentRect.topRight() + QPointF(-dy, dx);
+ }
+}
+
+/*!
+ \qmlmethod QRectF QtMultimedia::VideoOutput::mapNormalizedRectToItem(const QRectF &rectangle) const
+
+ Given a rectangle \a rectangle in normalized
+ coordinates (that is, each component in the range of 0 to 1.0),
+ return the mapped rectangle that it corresponds to (in item coordinates).
+ This mapping is affected by the orientation.
+
+ Depending on the fill mode, this rectangle may extend outside the rendered
+ rectangle.
+ */
+QRectF QDeclarativeVideoOutput::mapNormalizedRectToItem(const QRectF &rectangle) const
+{
+ return QRectF(mapNormalizedPointToItem(rectangle.topLeft()),
+ mapNormalizedPointToItem(rectangle.bottomRight())).normalized();
+}
+
+/*!
+ \qmlmethod QPointF QtMultimedia::VideoOutput::mapPointToSource(const QPointF &point) const
+
+ Given a point \a point in item coordinates, return the
+ corresponding point in source coordinates. This mapping is
+ affected by the orientation.
+
+ If the supplied point lies outside the rendered area, the returned
+ point will be outside the source rectangle.
+ */
+QPointF QDeclarativeVideoOutput::mapPointToSource(const QPointF &point) const
+{
+ QPointF norm = mapPointToSourceNormalized(point);
+
+ if (qIsDefaultAspect(m_orientation))
+ return QPointF(norm.x() * m_nativeSize.width(), norm.y() * m_nativeSize.height());
+ else
+ return QPointF(norm.x() * m_nativeSize.height(), norm.y() * m_nativeSize.width());
+}
+
+/*!
+ \qmlmethod QRectF QtMultimedia::VideoOutput::mapRectToSource(const QRectF &rectangle) const
+
+ Given a rectangle \a rectangle in item coordinates, return the
+ corresponding rectangle in source coordinates. This mapping is
+ affected by the orientation.
+
+ This mapping is affected by the orientation.
+
+ If the supplied point lies outside the rendered area, the returned
+ point will be outside the source rectangle.
+ */
+QRectF QDeclarativeVideoOutput::mapRectToSource(const QRectF &rectangle) const
+{
+ return QRectF(mapPointToSource(rectangle.topLeft()),
+ mapPointToSource(rectangle.bottomRight())).normalized();
+}
+
+/*!
+ \qmlmethod QPointF QtMultimedia::VideoOutput::mapPointToSourceNormalized(const QPointF &point) const
+
+ Given a point \a point in item coordinates, return the
+ corresponding point in normalized source coordinates. This mapping is
+ affected by the orientation.
+
+ If the supplied point lies outside the rendered area, the returned
+ point will be outside the source rectangle. No clamping is performed.
+ */
+QPointF QDeclarativeVideoOutput::mapPointToSourceNormalized(const QPointF &point) const
+{
+ if (m_contentRect.isEmpty())
+ return QPointF();
+
+ // Normalize the item source point
+ qreal nx = (point.x() - m_contentRect.left()) / m_contentRect.width();
+ qreal ny = (point.y() - m_contentRect.top()) / m_contentRect.height();
+
+ const qreal one(1.0f);
+
+ // For now, the origin of the source rectangle is 0,0
+ switch (qNormalizedOrientation(m_orientation)) {
+ case 0:
+ default:
+ return QPointF(nx, ny);
+ case 90:
+ return QPointF(one - ny, nx);
+ case 180:
+ return QPointF(one - nx, one - ny);
+ case 270:
+ return QPointF(ny, one - nx);
+ }
+}
+
+/*!
+ \qmlmethod QRectF QtMultimedia::VideoOutput::mapRectToSourceNormalized(const QRectF &rectangle) const
+
+ Given a rectangle \a rectangle in item coordinates, return the
+ corresponding rectangle in normalized source coordinates. This mapping is
+ affected by the orientation.
+
+ This mapping is affected by the orientation.
+
+ If the supplied point lies outside the rendered area, the returned
+ point will be outside the source rectangle. No clamping is performed.
+ */
+QRectF QDeclarativeVideoOutput::mapRectToSourceNormalized(const QRectF &rectangle) const
+{
+ return QRectF(mapPointToSourceNormalized(rectangle.topLeft()),
+ mapPointToSourceNormalized(rectangle.bottomRight())).normalized();
+}
+
+QDeclarativeVideoOutput::SourceType QDeclarativeVideoOutput::sourceType() const
+{
+ return m_sourceType;
+}
+
+/*!
+ \qmlmethod QPointF QtMultimedia::VideoOutput::mapPointToItem(const QPointF &point) const
+
+ Given a point \a point in source coordinates, return the
+ corresponding point in item coordinates. This mapping is
+ affected by the orientation.
+
+ Depending on the fill mode, this point may lie outside the rendered
+ rectangle.
+ */
+QPointF QDeclarativeVideoOutput::mapPointToItem(const QPointF &point) const
+{
+ if (m_nativeSize.isEmpty())
+ return QPointF();
+
+ // Just normalize and use that function
+ // m_nativeSize is transposed in some orientations
+ if (qIsDefaultAspect(m_orientation))
+ return mapNormalizedPointToItem(QPointF(point.x() / m_nativeSize.width(), point.y() / m_nativeSize.height()));
+ else
+ return mapNormalizedPointToItem(QPointF(point.x() / m_nativeSize.height(), point.y() / m_nativeSize.width()));
+}
+
+/*!
+ \qmlmethod QRectF QtMultimedia::VideoOutput::mapRectToItem(const QRectF &rectangle) const
+
+ Given a rectangle \a rectangle in source coordinates, return the
+ corresponding rectangle in item coordinates. This mapping is
+ affected by the orientation.
+
+ Depending on the fill mode, this rectangle may extend outside the rendered
+ rectangle.
+
+ */
+QRectF QDeclarativeVideoOutput::mapRectToItem(const QRectF &rectangle) const
+{
+ return QRectF(mapPointToItem(rectangle.topLeft()),
+ mapPointToItem(rectangle.bottomRight())).normalized();
+}
+
+QSGNode *QDeclarativeVideoOutput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
+{
+ _q_updateGeometry();
+
+ if (!m_backend)
+ return 0;
+
+ return m_backend->updatePaintNode(oldNode, data);
+}
+
+void QDeclarativeVideoOutput::itemChange(QQuickItem::ItemChange change,
+ const QQuickItem::ItemChangeData &changeData)
+{
+ if (m_backend)
+ m_backend->itemChange(change, changeData);
+}
+
+void QDeclarativeVideoOutput::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ Q_UNUSED(newGeometry);
+ Q_UNUSED(oldGeometry);
+
+ QQuickItem::geometryChanged(newGeometry, oldGeometry);
+
+ // Explicitly listen to geometry changes here. This is needed since changing the position does
+ // not trigger a call to updatePaintNode().
+ // We need to react to position changes though, as the window backened's display rect gets
+ // changed in that situation.
+ _q_updateGeometry();
+}
+
+QT_END_NAMESPACE