/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <qabstractvideosurface.h>
#include <qvideoframe.h>
#include <QDebug>
#include <QMap>
#include <QDebug>
#include <QThread>

#include <private/qmediapluginloader_p.h>
#include "qgstvideobuffer_p.h"

#include "qgstutils_p.h"
#include "qvideosurfacegstsink_p.h"

#if GST_VERSION_MAJOR >=1
#include <gst/video/video.h>
#endif

//#define DEBUG_VIDEO_SURFACE_SINK

QT_BEGIN_NAMESPACE

Q_GLOBAL_STATIC_WITH_ARGS(QMediaPluginLoader, bufferPoolLoader,
        (QGstBufferPoolInterface_iid, QLatin1String("video/bufferpool"), Qt::CaseInsensitive))


QVideoSurfaceGstDelegate::QVideoSurfaceGstDelegate(
    QAbstractVideoSurface *surface)
    : m_surface(surface)
{
    if (m_surface) {
        const auto instances = bufferPoolLoader()->instances(QGstBufferPoolPluginKey);
        for (QObject *instance : instances) {
            auto plugin = qobject_cast<QGstBufferPoolInterface*>(instance);

            if (plugin) {
                m_pools.append(plugin);
            }
        }

        updateSupportedFormats();
        connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(updateSupportedFormats()));
    }
}

QVideoSurfaceGstDelegate::~QVideoSurfaceGstDelegate()
{
}

QList<QVideoFrame::PixelFormat> QVideoSurfaceGstDelegate::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const
{
    QMutexLocker locker(const_cast<QMutex *>(&m_mutex));

    if (!m_surface)
        return QList<QVideoFrame::PixelFormat>();
    else if (handleType == QAbstractVideoBuffer::NoHandle)
        return m_supportedPixelFormats;
    else if (handleType == m_pool->handleType())
        return m_supportedPoolPixelFormats;
    else
        return m_surface->supportedPixelFormats(handleType);
}

QVideoSurfaceFormat QVideoSurfaceGstDelegate::surfaceFormat() const
{
    QMutexLocker locker(const_cast<QMutex *>(&m_mutex));
    return m_format;
}

bool QVideoSurfaceGstDelegate::start(const QVideoSurfaceFormat &format, int bytesPerLine)
{
    if (!m_surface)
        return false;

    QMutexLocker locker(&m_mutex);

    m_format = format;
    m_bytesPerLine = bytesPerLine;

    if (QThread::currentThread() == thread()) {
        m_started = !m_surface.isNull() ? m_surface->start(m_format) : false;
    } else {
        m_started = false;
        m_startCanceled = false;
        QMetaObject::invokeMethod(this, "queuedStart", Qt::QueuedConnection);

        /*
        Waiting for start() to be invoked in the main thread may block
        if gstreamer blocks the main thread until this call is finished.
        This situation is rare and usually caused by setState(Null)
        while pipeline is being prerolled.

        The proper solution to this involves controlling gstreamer pipeline from
        other thread than video surface.

        Currently start() fails if wait() timed out.
        */
        if (!m_setupCondition.wait(&m_mutex, 1000)) {
            qWarning() << "Failed to start video surface due to main thread blocked.";
            m_startCanceled = true;
        }
    }

    m_format = m_surface->surfaceFormat();

    return m_started;
}

void QVideoSurfaceGstDelegate::stop()
{
    if (!m_surface)
        return;

    QMutexLocker locker(&m_mutex);

    if (QThread::currentThread() == thread()) {
        if (!m_surface.isNull())
            m_surface->stop();
    } else {
        QMetaObject::invokeMethod(this, "queuedStop", Qt::QueuedConnection);

        // Waiting for stop() to be invoked in the main thread may block
        // if gstreamer blocks the main thread until this call is finished.
        m_setupCondition.wait(&m_mutex, 500);
    }

    m_started = false;
}

void QVideoSurfaceGstDelegate::unlock()
{
    QMutexLocker locker(&m_mutex);

    m_startCanceled = true;
    m_setupCondition.wakeAll();
    m_renderCondition.wakeAll();
}

bool QVideoSurfaceGstDelegate::isActive()
{
    QMutexLocker locker(&m_mutex);
    return !m_surface.isNull() && m_surface->isActive();
}

void QVideoSurfaceGstDelegate::clearPoolBuffers()
{
    QMutexLocker locker(&m_poolMutex);
    if (m_pool)
        m_pool->clear();
}

void QVideoSurfaceGstDelegate::flush()
{
    QMutexLocker locker(&m_mutex);

    m_frame = QVideoFrame();
    m_renderCondition.wakeAll();

    if (QThread::currentThread() == thread()) {
        if (!m_surface.isNull())
            m_surface->present(m_frame);
    } else {
        QMetaObject::invokeMethod(this, "queuedFlush", Qt::QueuedConnection);
    }
}

GstFlowReturn QVideoSurfaceGstDelegate::render(GstBuffer *buffer)
{
    if (!m_surface) {
        qWarning() << "Rendering video frame to deleted surface, skip.";
        //return GST_FLOW_NOT_NEGOTIATED;
        return GST_FLOW_OK;
    }

    QMutexLocker locker(&m_mutex);

    QAbstractVideoBuffer *videoBuffer = 0;

    if (m_pool)
        videoBuffer = m_pool->prepareVideoBuffer(buffer, m_bytesPerLine);

    if (!videoBuffer)
        videoBuffer = new QGstVideoBuffer(buffer, m_bytesPerLine);

    m_frame = QVideoFrame(
            videoBuffer,
            m_format.frameSize(),
            m_format.pixelFormat());

    QGstUtils::setFrameTimeStamps(&m_frame, buffer);

    m_renderReturn = GST_FLOW_OK;

    if (QThread::currentThread() == thread()) {
        if (!m_surface.isNull())
            m_surface->present(m_frame);
        else
            qWarning() << "m_surface.isNull().";
    } else {
        QMetaObject::invokeMethod(this, "queuedRender", Qt::QueuedConnection);
        m_renderCondition.wait(&m_mutex, 300);
    }

    m_frame = QVideoFrame();
    return m_renderReturn;
}

void QVideoSurfaceGstDelegate::queuedStart()
{
    QMutexLocker locker(&m_mutex);

    if (!m_startCanceled) {
        m_started = m_surface->start(m_format);
        m_setupCondition.wakeAll();
    }
}

void QVideoSurfaceGstDelegate::queuedStop()
{
    QMutexLocker locker(&m_mutex);

    m_surface->stop();

    m_setupCondition.wakeAll();
}

void QVideoSurfaceGstDelegate::queuedFlush()
{
    QMutexLocker locker(&m_mutex);

    if (!m_surface.isNull())
        m_surface->present(QVideoFrame());
}

void QVideoSurfaceGstDelegate::queuedRender()
{
    QMutexLocker locker(&m_mutex);

    if (!m_frame.isValid())
        return;

    if (m_surface.isNull()) {
        qWarning() << "Rendering video frame to deleted surface, skip the frame";
        m_renderReturn = GST_FLOW_OK;
    } else if (m_surface->present(m_frame)) {
        m_renderReturn = GST_FLOW_OK;
    } else {
        switch (m_surface->error()) {
        case QAbstractVideoSurface::NoError:
            m_renderReturn = GST_FLOW_OK;
            break;
        case QAbstractVideoSurface::StoppedError:
            //It's likely we are in process of changing video output
            //and the surface is already stopped, ignore the frame
            m_renderReturn = GST_FLOW_OK;
            break;
        default:
            qWarning() << "Failed to render video frame:" << m_surface->error();
            m_renderReturn = GST_FLOW_OK;
            break;
        }
    }

    m_renderCondition.wakeAll();
}

void QVideoSurfaceGstDelegate::updateSupportedFormats()
{
    QGstBufferPoolInterface *newPool = 0;
    for (QGstBufferPoolInterface *pool : qAsConst(m_pools)) {
        if (!m_surface->supportedPixelFormats(pool->handleType()).isEmpty()) {
            newPool = pool;
            break;
        }
    }

    if (newPool != m_pool) {
        QMutexLocker lock(&m_poolMutex);

        if (m_pool)
            m_pool->clear();
        m_pool = newPool;
    }

    QMutexLocker locker(&m_mutex);

    m_supportedPixelFormats.clear();
    m_supportedPoolPixelFormats.clear();
    if (m_surface) {
        m_supportedPixelFormats = m_surface->supportedPixelFormats();
        if (m_pool)
            m_supportedPoolPixelFormats = m_surface->supportedPixelFormats(m_pool->handleType());
    }
}

static GstVideoSinkClass *sink_parent_class;

#define VO_SINK(s) QVideoSurfaceGstSink *sink(reinterpret_cast<QVideoSurfaceGstSink *>(s))

QVideoSurfaceGstSink *QVideoSurfaceGstSink::createSink(QAbstractVideoSurface *surface)
{
    QVideoSurfaceGstSink *sink = reinterpret_cast<QVideoSurfaceGstSink *>(
            g_object_new(QVideoSurfaceGstSink::get_type(), 0));

    sink->delegate = new QVideoSurfaceGstDelegate(surface);

    g_signal_connect(G_OBJECT(sink), "notify::show-preroll-frame", G_CALLBACK(handleShowPrerollChange), sink);

    return sink;
}

GType QVideoSurfaceGstSink::get_type()
{
    static GType type = 0;

    if (type == 0) {
        static const GTypeInfo info =
        {
            sizeof(QVideoSurfaceGstSinkClass),                    // class_size
            base_init,                                         // base_init
            nullptr,                                           // base_finalize
            class_init,                                        // class_init
            nullptr,                                           // class_finalize
            nullptr,                                           // class_data
            sizeof(QVideoSurfaceGstSink),                         // instance_size
            0,                                                 // n_preallocs
            instance_init,                                     // instance_init
            0                                                  // value_table
        };

        type = g_type_register_static(
                GST_TYPE_VIDEO_SINK, "QVideoSurfaceGstSink", &info, GTypeFlags(0));
    }

    return type;
}

void QVideoSurfaceGstSink::class_init(gpointer g_class, gpointer class_data)
{
    Q_UNUSED(class_data);

    sink_parent_class = reinterpret_cast<GstVideoSinkClass *>(g_type_class_peek_parent(g_class));

    GstBaseSinkClass *base_sink_class = reinterpret_cast<GstBaseSinkClass *>(g_class);
    base_sink_class->get_caps = QVideoSurfaceGstSink::get_caps;
    base_sink_class->set_caps = QVideoSurfaceGstSink::set_caps;
    base_sink_class->buffer_alloc = QVideoSurfaceGstSink::buffer_alloc;
    base_sink_class->start = QVideoSurfaceGstSink::start;
    base_sink_class->stop = QVideoSurfaceGstSink::stop;
    base_sink_class->unlock = QVideoSurfaceGstSink::unlock;

#if GST_CHECK_VERSION(0, 10, 25)
    GstVideoSinkClass *video_sink_class = reinterpret_cast<GstVideoSinkClass *>(g_class);
    video_sink_class->show_frame = QVideoSurfaceGstSink::show_frame;
#else
    base_sink_class->preroll = QVideoSurfaceGstSink::preroll;
    base_sink_class->render = QVideoSurfaceGstSink::render;
#endif

    GstElementClass *element_class = reinterpret_cast<GstElementClass *>(g_class);
    element_class->change_state = QVideoSurfaceGstSink::change_state;

    GObjectClass *object_class = reinterpret_cast<GObjectClass *>(g_class);
    object_class->finalize = QVideoSurfaceGstSink::finalize;
}

void QVideoSurfaceGstSink::base_init(gpointer g_class)
{
    static GstStaticPadTemplate sink_pad_template = GST_STATIC_PAD_TEMPLATE(
            "sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS(
                    "video/x-raw-rgb, "
                    "framerate = (fraction) [ 0, MAX ], "
                    "width = (int) [ 1, MAX ], "
                    "height = (int) [ 1, MAX ]; "
                    "video/x-raw-yuv, "
                    "framerate = (fraction) [ 0, MAX ], "
                    "width = (int) [ 1, MAX ], "
                    "height = (int) [ 1, MAX ]"));

    gst_element_class_add_pad_template(
            GST_ELEMENT_CLASS(g_class), gst_static_pad_template_get(&sink_pad_template));
}

void QVideoSurfaceGstSink::instance_init(GTypeInstance *instance, gpointer g_class)
{
    VO_SINK(instance);

    Q_UNUSED(g_class);

    sink->delegate = 0;

    sink->lastRequestedCaps = 0;
    sink->lastBufferCaps = 0;
    sink->lastSurfaceFormat = new QVideoSurfaceFormat;
}

void QVideoSurfaceGstSink::finalize(GObject *object)
{
    VO_SINK(object);

    delete sink->lastSurfaceFormat;
    sink->lastSurfaceFormat = 0;

    if (sink->lastBufferCaps)
        gst_caps_unref(sink->lastBufferCaps);
    sink->lastBufferCaps = 0;

    if (sink->lastRequestedCaps)
        gst_caps_unref(sink->lastRequestedCaps);
    sink->lastRequestedCaps = 0;

    delete sink->delegate;

    // Chain up
    G_OBJECT_CLASS(sink_parent_class)->finalize(object);
}

void QVideoSurfaceGstSink::handleShowPrerollChange(GObject *o, GParamSpec *p, gpointer d)
{
    Q_UNUSED(o);
    Q_UNUSED(p);
    QVideoSurfaceGstSink *sink = reinterpret_cast<QVideoSurfaceGstSink *>(d);

    gboolean showPrerollFrame = true; // "show-preroll-frame" property is true by default
    g_object_get(G_OBJECT(sink), "show-preroll-frame", &showPrerollFrame, nullptr);

    if (!showPrerollFrame) {
        GstState state = GST_STATE_VOID_PENDING;
        gst_element_get_state(GST_ELEMENT(sink), &state, nullptr, GST_CLOCK_TIME_NONE);
        // show-preroll-frame being set to 'false' while in GST_STATE_PAUSED means
        // the QMediaPlayer was stopped from the paused state.
        // We need to flush the current frame.
        if (state == GST_STATE_PAUSED)
            sink->delegate->flush();
    }
}

GstStateChangeReturn QVideoSurfaceGstSink::change_state(GstElement *element, GstStateChange transition)
{
    QVideoSurfaceGstSink *sink = reinterpret_cast<QVideoSurfaceGstSink *>(element);

    gboolean showPrerollFrame = true; // "show-preroll-frame" property is true by default
    g_object_get(G_OBJECT(element), "show-preroll-frame", &showPrerollFrame, nullptr);

    // If show-preroll-frame is 'false' when transitioning from GST_STATE_PLAYING to
    // GST_STATE_PAUSED, it means the QMediaPlayer was stopped.
    // We need to flush the current frame.
    if (transition == GST_STATE_CHANGE_PLAYING_TO_PAUSED && !showPrerollFrame)
        sink->delegate->flush();

    return GST_ELEMENT_CLASS(sink_parent_class)->change_state(element, transition);
}

GstCaps *QVideoSurfaceGstSink::get_caps(GstBaseSink *base)
{
    VO_SINK(base);

    // Find the supported pixel formats
    // with buffer pool specific formats listed first
    QList<QVideoFrame::PixelFormat> supportedFormats;

    QList<QVideoFrame::PixelFormat> poolHandleFormats;
    sink->delegate->poolMutex()->lock();
    QGstBufferPoolInterface *pool = sink->delegate->pool();

    if (pool)
        poolHandleFormats = sink->delegate->supportedPixelFormats(pool->handleType());
    sink->delegate->poolMutex()->unlock();

    supportedFormats = poolHandleFormats;
    const auto supportedPixelFormats = sink->delegate->supportedPixelFormats();
    for (QVideoFrame::PixelFormat format : supportedPixelFormats) {
        if (!poolHandleFormats.contains(format))
            supportedFormats.append(format);
    }

    return QGstUtils::capsForFormats(supportedFormats);
}

gboolean QVideoSurfaceGstSink::set_caps(GstBaseSink *base, GstCaps *caps)
{
    VO_SINK(base);

#ifdef DEBUG_VIDEO_SURFACE_SINK
    qDebug() << "set_caps:";
    qDebug() << gst_caps_to_string(caps);
#endif

    if (!caps) {
        sink->delegate->stop();

        return TRUE;
    } else {
        int bytesPerLine = 0;
        QGstBufferPoolInterface *pool = sink->delegate->pool();
        QAbstractVideoBuffer::HandleType handleType =
                pool ? pool->handleType() : QAbstractVideoBuffer::NoHandle;

        QVideoSurfaceFormat format = QGstUtils::formatForCaps(caps, &bytesPerLine, handleType);

        if (sink->delegate->isActive()) {
            QVideoSurfaceFormat surfaceFormst = sink->delegate->surfaceFormat();

            if (format.pixelFormat() == surfaceFormst.pixelFormat() &&
                format.frameSize() == surfaceFormst.frameSize())
                return TRUE;
            else
                sink->delegate->stop();
        }

        if (sink->lastRequestedCaps)
            gst_caps_unref(sink->lastRequestedCaps);
        sink->lastRequestedCaps = 0;

#ifdef DEBUG_VIDEO_SURFACE_SINK
        qDebug() << "Starting video surface, format:";
        qDebug() << format;
        qDebug() << "bytesPerLine:" << bytesPerLine;
#endif

        if (sink->delegate->start(format, bytesPerLine))
            return TRUE;
        else
            qWarning() << "Failed to start video surface";
    }

    return FALSE;
}

GstFlowReturn QVideoSurfaceGstSink::buffer_alloc(
        GstBaseSink *base, guint64 offset, guint size, GstCaps *caps, GstBuffer **buffer)
{
    VO_SINK(base);

    Q_UNUSED(offset);
    Q_UNUSED(size);

    if (!buffer)
        return GST_FLOW_ERROR;

    *buffer = nullptr;

    if (!sink->delegate->pool())
        return GST_FLOW_OK;

    QMutexLocker poolLock(sink->delegate->poolMutex());
    QGstBufferPoolInterface *pool = sink->delegate->pool();

    if (!pool)
        return GST_FLOW_OK;

    if (sink->lastRequestedCaps && gst_caps_is_equal(sink->lastRequestedCaps, caps)) {
        //qDebug() << "reusing last caps";
        *buffer = GST_BUFFER(pool->takeBuffer(*sink->lastSurfaceFormat, sink->lastBufferCaps));
        return GST_FLOW_OK;
    }

    if (sink->delegate->supportedPixelFormats(pool->handleType()).isEmpty()) {
        //qDebug() << "sink doesn't support native pool buffers, skip buffers allocation";
        return GST_FLOW_OK;
    }

    poolLock.unlock();

    GstCaps *intersection = gst_caps_intersect(get_caps(GST_BASE_SINK(sink)), caps);

    if (gst_caps_is_empty (intersection)) {
        gst_caps_unref(intersection);
        return GST_FLOW_NOT_NEGOTIATED;
    }

    if (sink->delegate->isActive()) {
        //if format was changed, restart the surface
        QVideoSurfaceFormat format = QGstUtils::formatForCaps(intersection);
        QVideoSurfaceFormat surfaceFormat = sink->delegate->surfaceFormat();

        if (format.pixelFormat() != surfaceFormat.pixelFormat() ||
            format.frameSize() != surfaceFormat.frameSize()) {
#ifdef DEBUG_VIDEO_SURFACE_SINK
            qDebug() << "new format requested, restart video surface";
#endif
            sink->delegate->stop();
        }
    }

    if (!sink->delegate->isActive()) {
        int bytesPerLine = 0;
        QGstBufferPoolInterface *pool = sink->delegate->pool();
        QAbstractVideoBuffer::HandleType handleType =
                pool ? pool->handleType() : QAbstractVideoBuffer::NoHandle;

        QVideoSurfaceFormat format = QGstUtils::formatForCaps(intersection, &bytesPerLine, handleType);

        if (!sink->delegate->start(format, bytesPerLine)) {
            qWarning() << "failed to start video surface";
            return GST_FLOW_NOT_NEGOTIATED;
        }
    }

    poolLock.relock();
    pool = sink->delegate->pool();

    QVideoSurfaceFormat surfaceFormat = sink->delegate->surfaceFormat();

    if (!pool->isFormatSupported(surfaceFormat)) {
        qDebug() << "sink doesn't support native pool format, skip custom buffers allocation";
        return GST_FLOW_OK;
    }

    if (sink->lastRequestedCaps)
        gst_caps_unref(sink->lastRequestedCaps);
    sink->lastRequestedCaps = caps;
    gst_caps_ref(sink->lastRequestedCaps);

    if (sink->lastBufferCaps)
        gst_caps_unref(sink->lastBufferCaps);
    sink->lastBufferCaps = intersection;
    gst_caps_ref(sink->lastBufferCaps);

    *sink->lastSurfaceFormat = surfaceFormat;

    *buffer =  GST_BUFFER(pool->takeBuffer(surfaceFormat, intersection));

    return GST_FLOW_OK;
}

gboolean QVideoSurfaceGstSink::start(GstBaseSink *base)
{
    Q_UNUSED(base);
    return TRUE;
}

gboolean QVideoSurfaceGstSink::stop(GstBaseSink *base)
{
    VO_SINK(base);
    sink->delegate->clearPoolBuffers();

    return TRUE;
}

gboolean QVideoSurfaceGstSink::unlock(GstBaseSink *base)
{
    VO_SINK(base);
    sink->delegate->unlock();
    return TRUE;
}

#if GST_CHECK_VERSION(0, 10, 25)
GstFlowReturn QVideoSurfaceGstSink::show_frame(GstVideoSink *base, GstBuffer *buffer)
{
    VO_SINK(base);
    return sink->delegate->render(buffer);
}
#else
GstFlowReturn QVideoSurfaceGstSink::preroll(GstBaseSink *base, GstBuffer *buffer)
{
    VO_SINK(base);
    gboolean showPrerollFrame = true;
    g_object_get(G_OBJECT(sink), "show-preroll-frame", &showPrerollFrame, nullptr);

    if (showPrerollFrame)
        return sink->delegate->render(buffer);

    return GST_FLOW_OK;
}

GstFlowReturn QVideoSurfaceGstSink::render(GstBaseSink *base, GstBuffer *buffer)
{
    VO_SINK(base);
    return sink->delegate->render(buffer);
}
#endif

QT_END_NAMESPACE
