/****************************************************************************
**
** Copyright (C) 2016 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 "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>
#include <QtCore/qloggingcategory.h>

static void initResource() {
    Q_INIT_RESOURCE(qtmultimediaquicktools);
}

QT_BEGIN_NAMESPACE

Q_LOGGING_CATEGORY(qLcVideo, "qt.multimedia.video")

/*!
    \qmltype VideoOutput
    //! \instantiates QDeclarativeVideoOutput
    \brief Render video or camera viewfinder.

    \ingroup multimedia_qml
    \ingroup multimedia_video_qml
    \inqmlmodule QtMultimedia

    \qml

    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

\omit
    \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
\endomit
*/

// TODO: Restore Qt System Info docs when the module is released

/*!
    \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)
{
    initResource();
    setFlag(ItemHasContents, true);
    createBackend(nullptr);
}

QDeclarativeVideoOutput::~QDeclarativeVideoOutput()
{
    m_backend.reset();
    m_source.clear();
    _q_updateMediaObject();
}

/*!
    \qmlproperty object QtMultimedia::VideoOutput::videoSurface
    \since 5.15

    This property holds the underlaying video surface that can be used
    to render the video frames to this VideoOutput element.
    It is similar to setting a QObject with \c videoSurface property as a source,
    where this video surface will be set.

    \sa source
*/

QAbstractVideoSurface *QDeclarativeVideoOutput::videoSurface() const
{
    return m_backend ? m_backend->videoSurface() : nullptr;
}

/*!
    \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)
{
    qCDebug(qLcVideo) << "source is" << source;

    if (source == m_source.data())
        return;

    if (m_source && m_sourceType == MediaObjectSource) {
        disconnect(m_source.data(), 0, this, SLOT(_q_updateMediaObject()));
        disconnect(m_source.data(), 0, this, SLOT(_q_updateCameraInfo()));
    }

    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);

            }

            int deviceIdPropertyIndex = metaObject->indexOfProperty("deviceId");
            if (deviceIdPropertyIndex != -1) { // Camera source
                const QMetaProperty deviceIdProperty = metaObject->property(deviceIdPropertyIndex);

                if (deviceIdProperty.hasNotifySignal()) {
                    QMetaMethod method = deviceIdProperty.notifySignal();
                    QMetaObject::connect(m_source.data(), method.methodIndex(),
                                         this, this->metaObject()->indexOfSlot("_q_updateCameraInfo()"),
                                         Qt::DirectConnection, 0);

                }
            }

            m_sourceType = MediaObjectSource;
        } else if (metaObject->indexOfProperty("videoSurface") != -1) {
            m_source.data()->setProperty("videoSurface",
                QVariant::fromValue<QAbstractVideoSurface *>(videoSurface()));
            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;

    const auto instances = videoBackendFactoryLoader()->instances(QLatin1String("declarativevideobackend"));
    for (QObject *instance : instances) {
        if (QDeclarativeVideoBackendFactoryInterface *plugin = qobject_cast<QDeclarativeVideoBackendFactoryInterface*>(instance)) {
            if (!m_backend)
                m_backend.reset(plugin->create(this));
            if (m_backend && m_backend->init(service)) {
                backendAvailable = true;
                break;
            }
        }
    }
#if QT_CONFIG(opengl)
    if (!backendAvailable) {
        if (!m_backend)
            m_backend.reset(new QDeclarativeVideoRendererBackend(this));
        if (m_backend->init(service))
            backendAvailable = true;
    }
#endif

    // 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) {
        // Since new backend has been created needs to update its geometry.
        m_geometryDirty = true;

        m_backend->clearFilters();
        for (int i = 0; i < m_filters.count(); ++i)
            m_backend->appendFilter(m_filters[i]);
    } else {
        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*>());

    qCDebug(qLcVideo) << "media object is" << mediaObject;

    if (m_mediaObject.data() == mediaObject)
        return;

    m_mediaObject.clear();
    m_service.clear();

    if (mediaObject) {
        if (QMediaService *service = mediaObject->service()) {
            if (createBackend(service)) {
                m_service = service;
                m_mediaObject = mediaObject;
            }
        }
    }

    _q_updateCameraInfo();
}

void QDeclarativeVideoOutput::_q_updateCameraInfo()
{
    if (m_mediaObject) {
        const QCamera *camera = qobject_cast<const QCamera *>(m_mediaObject);
        if (camera) {
            QCameraInfo info(*camera);

            if (m_cameraInfo != info) {
                m_cameraInfo = info;

                // The camera position and orientation need to be taken into account for
                // the viewport auto orientation
                if (m_autoOrientation)
                    _q_screenOrientationChanged(m_screenOrientationHandler->currentOrientation());
            }
        }
    } else {
        m_cameraInfo = QCameraInfo();
    }
}

/*!
    \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) {
        if (!m_backend->videoSurface() || m_backend->videoSurface()->isActive())
            m_backend->updateGeometry();
        else
            m_geometryDirty = true;
    }


    if (m_contentRect != oldContentRect)
        emit contentRectChanged();
}

void QDeclarativeVideoOutput::_q_screenOrientationChanged(int orientation)
{
    // If the source is a camera, take into account its sensor position and orientation
    if (!m_cameraInfo.isNull()) {
        switch (m_cameraInfo.position()) {
        case QCamera::FrontFace:
            // Front facing cameras are flipped horizontally, compensate the mirror
            orientation += (360 - m_cameraInfo.orientation());
            break;
        case QCamera::BackFace:
        default:
            orientation += m_cameraInfo.orientation();
            break;
        }
    }

    setOrientation(orientation % 360);
}

/*!
    \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.

    \sa autoOrientation
*/
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 bool 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.

    \sa orientation
    \since 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::releaseResources()
{
    if (m_backend)
        m_backend->releaseResources();
}

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();
}

/*!
    \qmlproperty list<object> QtMultimedia::VideoOutput::filters

    This property holds the list of video filters that are run on the video
    frames. The order of the filters in the list matches the order in which
    they will be invoked on the video frames. The objects in the list must be
    instances of a subclass of QAbstractVideoFilter.

    \sa QAbstractVideoFilter
*/

QQmlListProperty<QAbstractVideoFilter> QDeclarativeVideoOutput::filters()
{
    return QQmlListProperty<QAbstractVideoFilter>(this, 0, filter_append, filter_count, filter_at, filter_clear);
}

void QDeclarativeVideoOutput::filter_append(QQmlListProperty<QAbstractVideoFilter> *property, QAbstractVideoFilter *value)
{
    QDeclarativeVideoOutput *self = static_cast<QDeclarativeVideoOutput *>(property->object);
    self->m_filters.append(value);
    if (self->m_backend)
        self->m_backend->appendFilter(value);
}

int QDeclarativeVideoOutput::filter_count(QQmlListProperty<QAbstractVideoFilter> *property)
{
    QDeclarativeVideoOutput *self = static_cast<QDeclarativeVideoOutput *>(property->object);
    return self->m_filters.count();
}

QAbstractVideoFilter *QDeclarativeVideoOutput::filter_at(QQmlListProperty<QAbstractVideoFilter> *property, int index)
{
    QDeclarativeVideoOutput *self = static_cast<QDeclarativeVideoOutput *>(property->object);
    return self->m_filters.at(index);
}

void QDeclarativeVideoOutput::filter_clear(QQmlListProperty<QAbstractVideoFilter> *property)
{
    QDeclarativeVideoOutput *self = static_cast<QDeclarativeVideoOutput *>(property->object);
    self->m_filters.clear();
    if (self->m_backend)
        self->m_backend->clearFilters();
}

void QDeclarativeVideoOutput::_q_invalidateSceneGraph()
{
    if (m_backend)
        m_backend->invalidateSceneGraph();
}

/*!
    \qmlproperty enumeration QtMultimedia::VideoOutput::flushMode
    \since 5.13

    Set this property to define what \c VideoOutput should show
    when playback is finished or stopped.

    \list
    \li EmptyFrame - clears video output.
    \li FirstFrame - shows the first valid frame.
    \li LastFrame - shows the last valid frame.
    \endlist

    The default flush mode is EmptyFrame.
*/

void QDeclarativeVideoOutput::setFlushMode(FlushMode mode)
{
    if (m_flushMode == mode)
        return;

    m_flushMode = mode;
    emit flushModeChanged();
}

QT_END_NAMESPACE
