/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
** 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 "qwinrtabstractvideorenderercontrol.h"

#include <QtCore/qfunctions_winrt.h>
#include <QtCore/QGlobalStatic>
#include <QtCore/QLoggingCategory>
#include <QtCore/QMetaMethod>
#include <QtCore/QMutexLocker>
#include <QtCore/QPointer>
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLTexture>
#include <QtMultimedia/QAbstractVideoBuffer>
#include <QtMultimedia/QAbstractVideoSurface>
#include <QtMultimedia/QVideoSurfaceFormat>

#define EGL_EGLEXT_PROTOTYPES
#include <EGL/egl.h>
#include <EGL/eglext.h>

#include <d3d11.h>
#include <mfapi.h>
#include <wrl.h>

using namespace Microsoft::WRL;

QT_BEGIN_NAMESPACE

Q_LOGGING_CATEGORY(lcMMVideoRender, "qt.mm.videorender")

#define BREAK_IF_FAILED(msg) RETURN_IF_FAILED(msg, break)
#define CONTINUE_IF_FAILED(msg) RETURN_IF_FAILED(msg, continue)

// Global D3D device to be shared between video surfaces
struct QWinRTVideoRendererControlGlobal
{
    QWinRTVideoRendererControlGlobal()
    {
        qCDebug(lcMMVideoRender) << __FUNCTION__;
        HRESULT hr;

        D3D_FEATURE_LEVEL featureLevels[] =
        {
            D3D_FEATURE_LEVEL_11_1,
            D3D_FEATURE_LEVEL_11_0,
            D3D_FEATURE_LEVEL_10_1,
            D3D_FEATURE_LEVEL_10_0,
            D3D_FEATURE_LEVEL_9_3,
            D3D_FEATURE_LEVEL_9_2,
            D3D_FEATURE_LEVEL_9_1
        };

        UINT flags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT;
#ifdef _DEBUG
        flags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
        hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, flags,
                               featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION,
                               &device, &featureLevel, &context);
#ifdef _DEBUG
        if (FAILED(hr)) {
            qErrnoWarning(hr, "Failed to create D3D device with device debug flag");
            hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
                                   featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION,
                                   &device, &featureLevel, &context);
        }
#endif
        if (FAILED(hr))
            qErrnoWarning(hr, "Failed to create D3D device");

        if (!device || FAILED(hr)) {
            hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_WARP, nullptr, flags,
                                   featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION,
                                   &device, &featureLevel, &context);
            if (FAILED(hr)) {
                qErrnoWarning(hr, "Failed to create software D3D device");
                return;
            }
        }

        ComPtr<ID3D10Multithread> multithread;
        hr = device.As(&multithread);
        Q_ASSERT_SUCCEEDED(hr);
        hr = multithread->SetMultithreadProtected(true);
        Q_ASSERT_SUCCEEDED(hr);

        ComPtr<IDXGIDevice> dxgiDevice;
        hr = device.As(&dxgiDevice);
        Q_ASSERT_SUCCEEDED(hr);
        ComPtr<IDXGIAdapter> adapter;
        hr = dxgiDevice->GetAdapter(&adapter);
        Q_ASSERT_SUCCEEDED(hr);
        hr = adapter->EnumOutputs(0, &output);
        Q_ASSERT_SUCCEEDED(hr);
    }

    ComPtr<ID3D11Device> device;
    ComPtr<ID3D11DeviceContext> context;
    D3D_FEATURE_LEVEL featureLevel;
    ComPtr<IDXGIOutput> output;
};
Q_GLOBAL_STATIC(QWinRTVideoRendererControlGlobal, g)

class QWinRTVideoBuffer : public QAbstractVideoBuffer, public QOpenGLTexture
{
public:
    QWinRTVideoBuffer(const QSize &size, TextureFormat format)
        : QAbstractVideoBuffer(QAbstractVideoBuffer::GLTextureHandle)
        , QOpenGLTexture(QOpenGLTexture::Target2D)
    {
        setSize(size.width(), size.height());
        setFormat(format);
        create();
    }

    MapMode mapMode() const override
    {
        return NotMapped;
    }

    uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) override
    {
        Q_UNUSED(mode);
        Q_UNUSED(numBytes);
        Q_UNUSED(bytesPerLine);
        return nullptr;
    }

    void unmap() override
    {
    }

    QVariant handle() const override
    {
        return QVariant::fromValue(textureId());
    }
};

enum DirtyState {
    NotDirty,     // All resources have been created
    TextureDirty, // The shared D3D texture needs to be recreated
    SurfaceDirty  // The shared EGL surface needs to be recreated
};

class QWinRTAbstractVideoRendererControlPrivate
{
public:
    QPointer<QAbstractVideoSurface> surface;
    QVideoSurfaceFormat format;

    DirtyState dirtyState;

    HANDLE shareHandle;
    ComPtr<ID3D11Texture2D> texture;

    EGLDisplay eglDisplay;
    EGLConfig eglConfig;
    EGLSurface eglSurface;

    QVideoFrame presentFrame;

    QThread renderThread;
    bool active;
    QWinRTAbstractVideoRendererControl::BlitMode blitMode;
    QMutex mutex;
};

ID3D11Device *QWinRTAbstractVideoRendererControl::d3dDevice()
{
    return g->device.Get();
}

// This is required so that subclasses can stop the render thread before deletion
void QWinRTAbstractVideoRendererControl::shutdown()
{
    qCDebug(lcMMVideoRender) << __FUNCTION__;
    Q_D(QWinRTAbstractVideoRendererControl);
    if (d->renderThread.isRunning()) {
        d->renderThread.requestInterruption();
        d->renderThread.wait();
    }
}

QWinRTAbstractVideoRendererControl::QWinRTAbstractVideoRendererControl(const QSize &size, QObject *parent)
    : QVideoRendererControl(parent), d_ptr(new QWinRTAbstractVideoRendererControlPrivate)
{
    qCDebug(lcMMVideoRender) << __FUNCTION__;
    Q_D(QWinRTAbstractVideoRendererControl);

    d->format = QVideoSurfaceFormat(size, QVideoFrame::Format_BGRA32,
                                    QAbstractVideoBuffer::GLTextureHandle);
    d->dirtyState = TextureDirty;
    d->shareHandle = nullptr;
    d->eglDisplay = EGL_NO_DISPLAY;
    d->eglConfig = nullptr;
    d->eglSurface = EGL_NO_SURFACE;
    d->active = false;
    d->blitMode = DirectVideo;

    connect(&d->renderThread, &QThread::started,
            this, &QWinRTAbstractVideoRendererControl::syncAndRender,
            Qt::DirectConnection);
}

QWinRTAbstractVideoRendererControl::~QWinRTAbstractVideoRendererControl()
{
    qCDebug(lcMMVideoRender) << __FUNCTION__;
    Q_D(QWinRTAbstractVideoRendererControl);
    QMutexLocker locker(&d->mutex);
    shutdown();
    locker.unlock();
    eglDestroySurface(d->eglDisplay, d->eglSurface);
}

QAbstractVideoSurface *QWinRTAbstractVideoRendererControl::surface() const
{
    Q_D(const QWinRTAbstractVideoRendererControl);
    return d->surface;
}

void QWinRTAbstractVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
{
    Q_D(QWinRTAbstractVideoRendererControl);
    d->surface = surface;
}

void QWinRTAbstractVideoRendererControl::syncAndRender()
{
    qCDebug(lcMMVideoRender) << __FUNCTION__;
    Q_D(QWinRTAbstractVideoRendererControl);

    QThread *currentThread = QThread::currentThread();
    const QMetaMethod present = staticMetaObject.method(staticMetaObject.indexOfMethod("present()"));
    forever {
        if (currentThread->isInterruptionRequested())
            break;
        {
            QMutexLocker lock(&d->mutex);
            HRESULT hr;
            if (d->dirtyState == TextureDirty) {
                CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, d->format.frameWidth(), d->format.frameHeight(), 1, 1);
                desc.BindFlags |= D3D11_BIND_RENDER_TARGET;
                desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
                hr = g->device->CreateTexture2D(&desc, nullptr, d->texture.ReleaseAndGetAddressOf());
                BREAK_IF_FAILED("Failed to get create video texture");
                ComPtr<IDXGIResource> resource;
                hr = d->texture.As(&resource);
                BREAK_IF_FAILED("Failed to cast texture to resource");
                hr = resource->GetSharedHandle(&d->shareHandle);
                BREAK_IF_FAILED("Failed to get texture share handle");
                d->dirtyState = SurfaceDirty;
            }

            hr = g->output->WaitForVBlank();
            CONTINUE_IF_FAILED("Failed to wait for vertical blank");

            bool success = false;
            switch (d->blitMode) {
            case DirectVideo:
                success = render(d->texture.Get());
                break;
            case MediaFoundation:
                success = dequeueFrame(&d->presentFrame);
                break;
            default:
                success = false;
            }

            if (!success)
                continue;

            // Queue to the control's thread for presentation
            present.invoke(this, Qt::QueuedConnection);
            currentThread->eventDispatcher()->processEvents(QEventLoop::AllEvents);
        }
    }

    // All done, exit render loop
    currentThread->quit();
}

QSize QWinRTAbstractVideoRendererControl::size() const
{
    Q_D(const QWinRTAbstractVideoRendererControl);
    return d->format.frameSize();
}

void QWinRTAbstractVideoRendererControl::setSize(const QSize &size)
{
    Q_D(QWinRTAbstractVideoRendererControl);

    if (d->format.frameSize() == size)
        return;

    d->format.setFrameSize(size);
    d->dirtyState = TextureDirty;
}

void QWinRTAbstractVideoRendererControl::setScanLineDirection(QVideoSurfaceFormat::Direction scanLineDirection)
{
    Q_D(QWinRTAbstractVideoRendererControl);

    if (d->format.scanLineDirection() == scanLineDirection)
        return;

    d->format.setScanLineDirection(scanLineDirection);
}

void QWinRTAbstractVideoRendererControl::setActive(bool active)
{
    qCDebug(lcMMVideoRender) << __FUNCTION__ << active;
    Q_D(QWinRTAbstractVideoRendererControl);

    if (d->active == active)
        return;

    d->active = active;
    if (d->active) {
        if (!d->surface)
            return;

        // This only happens for quick restart scenarios, for instance
        // when switching cameras.
        if (d->renderThread.isRunning() && d->renderThread.isInterruptionRequested()) {
            QMutexLocker lock(&d->mutex);
            d->renderThread.wait();
        }

        if (!d->surface->isActive())
            d->surface->start(d->format);

        d->renderThread.start();
        return;
    }

    d->renderThread.requestInterruption();

    if (d->surface && d->surface->isActive())
        d->surface->stop();
}

QWinRTAbstractVideoRendererControl::BlitMode QWinRTAbstractVideoRendererControl::blitMode() const
{
    Q_D(const QWinRTAbstractVideoRendererControl);
    return d->blitMode;
}

void QWinRTAbstractVideoRendererControl::setBlitMode(QWinRTAbstractVideoRendererControl::BlitMode mode)
{
    Q_D(QWinRTAbstractVideoRendererControl);
    QMutexLocker lock(&d->mutex);

    if (d->blitMode == mode)
        return;

    d->blitMode = mode;
    d->dirtyState = d->blitMode == MediaFoundation ? NotDirty : TextureDirty;

    if (d->blitMode == DirectVideo)
        return;

    if (d->texture) {
        d->texture.Reset();
        d->shareHandle = nullptr;
    }

    if (d->eglSurface) {
        eglDestroySurface(d->eglDisplay, d->eglSurface);
        d->eglSurface = EGL_NO_SURFACE;
    }
}

bool QWinRTAbstractVideoRendererControl::dequeueFrame(QVideoFrame *frame)
{
    Q_UNUSED(frame)
    return false;
}

void QWinRTAbstractVideoRendererControl::textureToFrame()
{
    Q_D(QWinRTAbstractVideoRendererControl);

    if (d->dirtyState == SurfaceDirty) {
        if (!QOpenGLContext::currentContext()) {
            qWarning("A valid OpenGL context is required for binding the video texture.");
            return;
        }

        if (d->eglDisplay == EGL_NO_DISPLAY)
            d->eglDisplay = eglGetCurrentDisplay();

        if (d->eglDisplay == EGL_NO_DISPLAY) {
            qWarning("Failed to get the current EGL display for video presentation: 0x%x", eglGetError());
            return;
        }

        EGLint configAttributes[] = {
            EGL_RED_SIZE, 8,
            EGL_GREEN_SIZE, 8,
            EGL_BLUE_SIZE, 8,
            EGL_ALPHA_SIZE, 8,
            EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE,
            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
            EGL_NONE
        };
        EGLint configCount;
        if (!eglChooseConfig(d->eglDisplay, configAttributes, &d->eglConfig, 1, &configCount)) {
            qWarning("Failed to create the texture EGL configuration for video presentation: 0x%x", eglGetError());
            return;
        }

        if (d->eglSurface != EGL_NO_SURFACE)
            eglDestroySurface(d->eglDisplay, d->eglSurface);

        EGLint bufferAttributes[] = {
            EGL_WIDTH, d->format.frameWidth(),
            EGL_HEIGHT, d->format.frameHeight(),
            EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
            EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
            EGL_NONE
        };
        d->eglSurface = eglCreatePbufferFromClientBuffer(d->eglDisplay,
                                                         EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
                                                         d->shareHandle, d->eglConfig, bufferAttributes);
        if (d->eglSurface == EGL_NO_SURFACE) {
            qWarning("Failed to create the EGL configuration for video presentation: 0x%x", eglGetError());
            return;
        }

        QWinRTVideoBuffer *videoBuffer = new QWinRTVideoBuffer(d->format.frameSize(), QOpenGLTexture::RGBAFormat);
        d->presentFrame = QVideoFrame(videoBuffer, d->format.frameSize(), d->format.pixelFormat());

        // bind the pbuffer surface to the texture
        videoBuffer->bind();
        eglBindTexImage(d->eglDisplay, d->eglSurface, EGL_BACK_BUFFER);
        static_cast<QOpenGLTexture *>(videoBuffer)->release();

        d->dirtyState = NotDirty;
    }
}

void QWinRTAbstractVideoRendererControl::present()
{
    Q_D(QWinRTAbstractVideoRendererControl);
    if (d->blitMode == DirectVideo)
        textureToFrame();

    // Present the frame
    d->surface->present(d->presentFrame);
}

QT_END_NAMESPACE
