/****************************************************************************
**
** 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_render_p.h"
#include "qdeclarativevideooutput_p.h"
#include <QtMultimedia/qabstractvideofilter.h>
#include <QtMultimedia/qvideorenderercontrol.h>
#include <QtMultimedia/qmediaservice.h>
#include <QtCore/qloggingcategory.h>
#include <private/qmediapluginloader_p.h>
#include <private/qsgvideonode_p.h>

#include <QtGui/QOpenGLContext>
#include <QtQuick/QQuickWindow>
#include <QtCore/QRunnable>

QT_BEGIN_NAMESPACE

Q_DECLARE_LOGGING_CATEGORY(qLcVideo)

Q_GLOBAL_STATIC_WITH_ARGS(QMediaPluginLoader, videoNodeFactoryLoader,
        (QSGVideoNodeFactoryInterface_iid, QLatin1String("video/videonode"), Qt::CaseInsensitive))

QDeclarativeVideoRendererBackend::QDeclarativeVideoRendererBackend(QDeclarativeVideoOutput *parent)
    : QDeclarativeVideoBackend(parent),
      m_glContext(0),
      m_frameChanged(false)
{
    m_surface = new QSGVideoItemSurface(this);
    QObject::connect(m_surface, SIGNAL(surfaceFormatChanged(QVideoSurfaceFormat)),
                     q, SLOT(_q_updateNativeSize()), Qt::QueuedConnection);

    // Prioritize the plugin requested by the environment
    QString requestedVideoNode = QString::fromLatin1(qgetenv("QT_VIDEONODE"));

    const auto keys = videoNodeFactoryLoader()->keys();
    for (const QString &key : keys) {
        QObject *instance = videoNodeFactoryLoader()->instance(key);
        QSGVideoNodeFactoryInterface* plugin = qobject_cast<QSGVideoNodeFactoryInterface*>(instance);
        if (plugin) {
            if (key == requestedVideoNode)
                m_videoNodeFactories.prepend(plugin);
            else
                m_videoNodeFactories.append(plugin);
            qCDebug(qLcVideo) << "found videonode plugin" << key << plugin;
        }
    }

    // Append existing node factories as fallback if we have no plugins
    m_videoNodeFactories.append(&m_i420Factory);
    m_videoNodeFactories.append(&m_rgbFactory);
    m_videoNodeFactories.append(&m_textureFactory);
}

QDeclarativeVideoRendererBackend::~QDeclarativeVideoRendererBackend()
{
    releaseSource();
    releaseControl();
    delete m_surface;
}

bool QDeclarativeVideoRendererBackend::init(QMediaService *service)
{
    // When there is no service, the source is an object with a "videoSurface" property, which
    // doesn't require a QVideoRendererControl and therefore always works
    if (!service)
        return true;

    if (QMediaControl *control = service->requestControl(QVideoRendererControl_iid)) {
        if ((m_rendererControl = qobject_cast<QVideoRendererControl *>(control))) {
            m_rendererControl->setSurface(m_surface);
            m_service = service;
            return true;
        }
    }
    return false;
}

void QDeclarativeVideoRendererBackend::appendFilter(QAbstractVideoFilter *filter)
{
    QMutexLocker lock(&m_frameMutex);
    m_filters.append(Filter(filter));
}

void QDeclarativeVideoRendererBackend::clearFilters()
{
    QMutexLocker lock(&m_frameMutex);
    scheduleDeleteFilterResources();
    m_filters.clear();
}

class FilterRunnableDeleter : public QRunnable
{
public:
    FilterRunnableDeleter(const QList<QVideoFilterRunnable *> &runnables) : m_runnables(runnables) { }
    void run() override {
        for (QVideoFilterRunnable *runnable : qAsConst(m_runnables))
            delete runnable;
    }
private:
    QList<QVideoFilterRunnable *> m_runnables;
};

void QDeclarativeVideoRendererBackend::scheduleDeleteFilterResources()
{
    if (!q->window())
        return;

    QList<QVideoFilterRunnable *> runnables;
    for (int i = 0; i < m_filters.count(); ++i) {
        if (m_filters[i].runnable) {
            runnables.append(m_filters[i].runnable);
            m_filters[i].runnable = 0;
        }
    }

    if (!runnables.isEmpty()) {
        // Request the scenegraph to run our cleanup job on the render thread.
        // The execution of our QRunnable may happen after the QML tree including the QAbstractVideoFilter instance is
        // destroyed on the main thread so no references to it must be used during cleanup.
        q->window()->scheduleRenderJob(new FilterRunnableDeleter(runnables), QQuickWindow::BeforeSynchronizingStage);
    }
}

void QDeclarativeVideoRendererBackend::releaseResources()
{
    // Called on the gui thread when the window is closed or changed.
    invalidateSceneGraph();
}

void QDeclarativeVideoRendererBackend::invalidateSceneGraph()
{
    // Called on the render thread, e.g. when the context is lost.
    QMutexLocker lock(&m_frameMutex);
    for (int i = 0; i < m_filters.count(); ++i) {
        if (m_filters[i].runnable) {
            delete m_filters[i].runnable;
            m_filters[i].runnable = 0;
        }
    }
}

void QDeclarativeVideoRendererBackend::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);
    }
}

void QDeclarativeVideoRendererBackend::releaseSource()
{
    if (q->source() && q->sourceType() == QDeclarativeVideoOutput::VideoSurfaceSource) {
        if (q->source()->property("videoSurface").value<QAbstractVideoSurface*>() == m_surface)
            q->source()->setProperty("videoSurface", QVariant::fromValue<QAbstractVideoSurface*>(0));
    }

    m_surface->stop();
}

void QDeclarativeVideoRendererBackend::releaseControl()
{
    if (m_rendererControl) {
        m_rendererControl->setSurface(0);
        if (m_service)
            m_service->releaseControl(m_rendererControl);
        m_rendererControl = 0;
    }
}

QSize QDeclarativeVideoRendererBackend::nativeSize() const
{
    return m_surfaceFormat.sizeHint();
}

void QDeclarativeVideoRendererBackend::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() == QDeclarativeVideoOutput::Stretch) {
        m_renderedRect = rect;
        m_sourceTextureRect = normalizedViewport;
    } else if (q->fillMode() == QDeclarativeVideoOutput::PreserveAspectFit) {
        m_sourceTextureRect = normalizedViewport;
        m_renderedRect = q->contentRect();
    } else if (q->fillMode() == QDeclarativeVideoOutput::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() == QVideoSurfaceFormat::BottomToTop) {
        qreal top = m_sourceTextureRect.top();
        m_sourceTextureRect.setTop(m_sourceTextureRect.bottom());
        m_sourceTextureRect.setBottom(top);
    }

    if (m_surfaceFormat.property("mirrored").toBool()) {
        qreal left = m_sourceTextureRect.left();
        m_sourceTextureRect.setLeft(m_sourceTextureRect.right());
        m_sourceTextureRect.setRight(left);
    }
}

QSGNode *QDeclarativeVideoRendererBackend::updatePaintNode(QSGNode *oldNode,
                                                           QQuickItem::UpdatePaintNodeData *data)
{
    Q_UNUSED(data);
    QSGVideoNode *videoNode = static_cast<QSGVideoNode *>(oldNode);

    QMutexLocker lock(&m_frameMutex);

    if (!m_glContext) {
        m_glContext = QOpenGLContext::currentContext();
        m_surface->scheduleOpenGLContextUpdate();

        // Internal mechanism to call back the surface renderer from the QtQuick render thread
        QObject *obj = m_surface->property("_q_GLThreadCallback").value<QObject*>();
        if (obj) {
            QEvent ev(QEvent::User);
            obj->event(&ev);
        }
    }

    bool isFrameModified = false;
    if (m_frameChanged) {
        // Run the VideoFilter if there is one. This must be done before potentially changing the videonode below.
        if (m_frame.isValid() && !m_filters.isEmpty()) {
            for (int i = 0; i < m_filters.count(); ++i) {
                QAbstractVideoFilter *filter = m_filters[i].filter;
                QVideoFilterRunnable *&runnable = m_filters[i].runnable;
                if (filter && filter->isActive()) {
                    // Create the filter runnable if not yet done. Ownership is taken and is tied to this thread, on which rendering happens.
                    if (!runnable)
                        runnable = filter->createFilterRunnable();
                    if (!runnable)
                        continue;

                    QVideoFilterRunnable::RunFlags flags;
                    if (i == m_filters.count() - 1)
                        flags |= QVideoFilterRunnable::LastInChain;

                    QVideoFrame newFrame = runnable->run(&m_frame, m_surfaceFormat, flags);

                    if (newFrame.isValid() && newFrame != m_frame) {
                        isFrameModified = true;
                        m_frame = newFrame;
                    }
                }
            }
        }

        if (videoNode && (videoNode->pixelFormat() != m_frame.pixelFormat() || videoNode->handleType() != m_frame.handleType())) {
            qCDebug(qLcVideo) << "updatePaintNode: deleting old video node because frame format changed";
            delete videoNode;
            videoNode = 0;
        }

        if (!m_frame.isValid()) {
            qCDebug(qLcVideo) << "updatePaintNode: no frames yet";
            m_frameChanged = false;
            return 0;
        }

        if (!videoNode) {
            for (QSGVideoNodeFactoryInterface* factory : qAsConst(m_videoNodeFactories)) {
                // Get a node that supports our frame. The surface is irrelevant, our
                // QSGVideoItemSurface supports (logically) anything.
                QVideoSurfaceFormat nodeFormat(m_frame.size(), m_frame.pixelFormat(), m_frame.handleType());
                nodeFormat.setYCbCrColorSpace(m_surfaceFormat.yCbCrColorSpace());
                nodeFormat.setPixelAspectRatio(m_surfaceFormat.pixelAspectRatio());
                nodeFormat.setScanLineDirection(m_surfaceFormat.scanLineDirection());
                nodeFormat.setViewport(m_surfaceFormat.viewport());
                nodeFormat.setFrameRate(m_surfaceFormat.frameRate());
                // Update current surface format if something has changed.
                m_surfaceFormat = nodeFormat;
                videoNode = factory->createNode(nodeFormat);
                if (videoNode) {
                    qCDebug(qLcVideo) << "updatePaintNode: Video node created. Handle type:" << m_frame.handleType()
                                     << " Supported formats for the handle by this node:"
                                     << factory->supportedPixelFormats(m_frame.handleType());
                    break;
                }
            }
        }
    }

    if (!videoNode) {
        m_frameChanged = false;
        m_frame = QVideoFrame();
        return 0;
    }

    // Negative rotations need lots of %360
    videoNode->setTexturedRectGeometry(m_renderedRect, m_sourceTextureRect,
                                       qNormalizedOrientation(q->orientation()));
    if (m_frameChanged) {
        QSGVideoNode::FrameFlags flags;
        if (isFrameModified)
            flags |= QSGVideoNode::FrameFiltered;
        videoNode->setCurrentFrame(m_frame, flags);

        if ((q->flushMode() == QDeclarativeVideoOutput::FirstFrame && !m_frameOnFlush.isValid())
            || q->flushMode() == QDeclarativeVideoOutput::LastFrame) {
            m_frameOnFlush = m_surfaceFormat.handleType() == QAbstractVideoBuffer::NoHandle
                ? m_frame
                : m_frame.image();
        }

        //don't keep the frame for more than really necessary
        m_frameChanged = false;
        m_frame = QVideoFrame();
    }
    return videoNode;
}

QAbstractVideoSurface *QDeclarativeVideoRendererBackend::videoSurface() const
{
    return m_surface;
}

QRectF QDeclarativeVideoRendererBackend::adjustedViewport() const
{
    const QRectF viewport = m_surfaceFormat.viewport();
    const QSizeF pixelAspectRatio = m_surfaceFormat.pixelAspectRatio();

    if (pixelAspectRatio.isValid()) {
        const qreal ratio = pixelAspectRatio.width() / pixelAspectRatio.height();
        QRectF result = viewport;
        result.setX(result.x() * ratio);
        result.setWidth(result.width() * ratio);
        return result;
    }

    return viewport;
}

QOpenGLContext *QDeclarativeVideoRendererBackend::glContext() const
{
    return m_glContext;
}

void QDeclarativeVideoRendererBackend::present(const QVideoFrame &frame)
{
    m_frameMutex.lock();
    m_frame = frame.isValid() ? frame : m_frameOnFlush;
    m_frameChanged = true;
    m_frameMutex.unlock();

    q->update();
}

void QDeclarativeVideoRendererBackend::stop()
{
    present(QVideoFrame());
}

QSGVideoItemSurface::QSGVideoItemSurface(QDeclarativeVideoRendererBackend *backend, QObject *parent)
    : QAbstractVideoSurface(parent),
      m_backend(backend)
{
}

QSGVideoItemSurface::~QSGVideoItemSurface()
{
}

QList<QVideoFrame::PixelFormat> QSGVideoItemSurface::supportedPixelFormats(
        QAbstractVideoBuffer::HandleType handleType) const
{
    QList<QVideoFrame::PixelFormat> formats;

    static bool noGLTextures = false;
    static bool noGLTexturesChecked = false;
    if (handleType == QAbstractVideoBuffer::GLTextureHandle) {
        if (!noGLTexturesChecked) {
            noGLTexturesChecked = true;
            noGLTextures = qEnvironmentVariableIsSet("QT_QUICK_NO_TEXTURE_VIDEOFRAMES");
        }
        if (noGLTextures)
            return formats;
    }

    for (QSGVideoNodeFactoryInterface* factory : qAsConst(m_backend->m_videoNodeFactories))
        formats.append(factory->supportedPixelFormats(handleType));

    return formats;
}

bool QSGVideoItemSurface::start(const QVideoSurfaceFormat &format)
{
    qCDebug(qLcVideo) << "Video surface format:" << format << "all supported formats:" << supportedPixelFormats(format.handleType());
    m_backend->m_frameOnFlush = QVideoFrame();

    if (!supportedPixelFormats(format.handleType()).contains(format.pixelFormat()))
        return false;

    m_backend->m_surfaceFormat = format;
    return QAbstractVideoSurface::start(format);
}

void QSGVideoItemSurface::stop()
{
    m_backend->stop();
    QAbstractVideoSurface::stop();
}

bool QSGVideoItemSurface::present(const QVideoFrame &frame)
{
    m_backend->present(frame);
    return true;
}

void QSGVideoItemSurface::scheduleOpenGLContextUpdate()
{
    //This method is called from render thread
    QMetaObject::invokeMethod(this, "updateOpenGLContext");
}

void QSGVideoItemSurface::updateOpenGLContext()
{
    //Set a dynamic property to access the OpenGL context in Qt Quick render thread.
    this->setProperty("GLContext", QVariant::fromValue<QObject*>(m_backend->glContext()));
}

QT_END_NAMESPACE
