/****************************************************************************
**
** 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 "qwinrtcameravideorenderercontrol.h"

#include <QtCore/qfunctions_winrt.h>
#include <QtCore/QSize>
#include <QtCore/QPointer>
#include <QtCore/QVector>
#include <QVideoFrame>

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

#include "qwinrtcameracontrol.h"

#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
#include <windows.security.exchangeactivesyncprovisioning.h>
using namespace ABI::Windows::Security::ExchangeActiveSyncProvisioning;
#endif

using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;

QT_BEGIN_NAMESPACE

#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
template <int n>
static bool blacklisted(const wchar_t (&blackListName)[n], const HString &deviceModel)
{
    quint32 deviceNameLength;
    const wchar_t *deviceName = deviceModel.GetRawBuffer(&deviceNameLength);
    return n - 1 <= deviceNameLength && !wmemcmp(blackListName, deviceName, n - 1);
}
#endif

class QWinRTCameraVideoBuffer : public QAbstractVideoBuffer
{
public:
    QWinRTCameraVideoBuffer(IMF2DBuffer *buffer, int size, QWinRTCameraControl *control)
        : QAbstractVideoBuffer(NoHandle)
        , buffer(buffer)
        , currentMode(NotMapped)
        , size(size)
        , control(control)
    {
        Q_ASSERT(control);
    }

    ~QWinRTCameraVideoBuffer() override
    {
        unmap();
    }

    MapMode mapMode() const override
    {
        return currentMode;
    }

    uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) override
    {
        if (currentMode != NotMapped || mode == NotMapped || (control && control->state() != QCamera::ActiveState))
            return nullptr;

        BYTE *bytes;
        LONG stride;
        HRESULT hr = buffer->Lock2D(&bytes, &stride);
        RETURN_IF_FAILED("Failed to lock camera frame buffer", return nullptr);
        control->frameMapped();

        if (bytesPerLine)
            *bytesPerLine = stride;
        if (numBytes)
            *numBytes = size;
        currentMode = mode;
        return bytes;
    }

    void unmap() override
    {
        if (currentMode == NotMapped)
            return;
        HRESULT hr = buffer->Unlock2D();
        RETURN_VOID_IF_FAILED("Failed to unlock camera frame buffer");
        currentMode = NotMapped;
        if (control)
            control->frameUnmapped();
    }

private:
    ComPtr<IMF2DBuffer> buffer;
    MapMode currentMode;
    int size;
    QPointer<QWinRTCameraControl> control;
};

class D3DVideoBlitter
{
public:
    D3DVideoBlitter(ID3D11Texture2D *target)
        : m_target(target)
    {
        Q_ASSERT(target);
        target->GetDevice(&m_d3dDevice);
        Q_ASSERT(m_d3dDevice);
        HRESULT hr;
        hr = m_d3dDevice.As(&m_videoDevice);
        Q_ASSERT_SUCCEEDED(hr);
    }

    ID3D11Device *device() const
    {
        return m_d3dDevice.Get();
    }

    ID3D11Texture2D *target() const
    {
        return m_target;
    }

    void blit(ID3D11Texture2D *texture)
    {
        HRESULT hr;
        D3D11_TEXTURE2D_DESC desc;
        texture->GetDesc(&desc);
        if (!m_videoEnumerator) {
            D3D11_VIDEO_PROCESSOR_CONTENT_DESC videoProcessorDesc = {
                D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE,
                { 0, 0}, desc.Width, desc.Height,
                { 0, 0}, desc.Width, desc.Height,
                D3D11_VIDEO_USAGE_OPTIMAL_SPEED
            };
            hr = m_videoDevice->CreateVideoProcessorEnumerator(&videoProcessorDesc, &m_videoEnumerator);
            RETURN_VOID_IF_FAILED("Failed to create video enumerator");
        }

        if (!m_videoProcessor) {
            hr = m_videoDevice->CreateVideoProcessor(m_videoEnumerator.Get(), 0, &m_videoProcessor);
            RETURN_VOID_IF_FAILED("Failed to create video processor");
        }

        if (!m_outputView) {
            D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC outputDesc = { D3D11_VPOV_DIMENSION_TEXTURE2D, {{ 0 }} };
            hr = m_videoDevice->CreateVideoProcessorOutputView(
                        m_target, m_videoEnumerator.Get(), &outputDesc, &m_outputView);
            RETURN_VOID_IF_FAILED("Failed to create video output view");
        }

        ComPtr<IDXGIResource1> sourceResource;
        hr = texture->QueryInterface(IID_PPV_ARGS(&sourceResource));
        RETURN_VOID_IF_FAILED("Failed to query interface IDXGIResource1");
        HANDLE sharedHandle = nullptr;
        hr = sourceResource->CreateSharedHandle(nullptr, DXGI_SHARED_RESOURCE_READ, nullptr, &sharedHandle);
        RETURN_VOID_IF_FAILED("Failed to create shared handle");
        ComPtr<ID3D11Device1> dev;
        hr = m_d3dDevice.As(&dev);
        RETURN_VOID_IF_FAILED("Failed to cast from ID3D11Device to ID3D11Device1");
        ComPtr<ID3D11Texture2D> sharedTexture;
        hr = dev->OpenSharedResource1(sharedHandle, IID_PPV_ARGS(&sharedTexture));
        RETURN_VOID_IF_FAILED("Failed to open shared resource");

        D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC inputViewDesc = {
            0, D3D11_VPIV_DIMENSION_TEXTURE2D, { 0, 0 }
        };
        ComPtr<ID3D11VideoProcessorInputView> inputView;
        hr = m_videoDevice->CreateVideoProcessorInputView(
                    sharedTexture.Get(), m_videoEnumerator.Get(), &inputViewDesc, &inputView);
        CloseHandle(sharedHandle);
        RETURN_VOID_IF_FAILED("Failed to create video input view");

        ComPtr<ID3D11DeviceContext> context;
        ComPtr<ID3D11VideoContext> videoContext;
        m_d3dDevice->GetImmediateContext(&context);
        hr = context.As(&videoContext);
        RETURN_VOID_IF_FAILED("Failed to get video context");

        D3D11_VIDEO_PROCESSOR_STREAM stream = { TRUE, 0, 0, 0, 0, nullptr,
                                                nullptr, nullptr, nullptr,
                                                nullptr, nullptr};
        stream.pInputSurface = inputView.Get();
        hr = videoContext->VideoProcessorBlt(
                    m_videoProcessor.Get(), m_outputView.Get(), 0, 1, &stream);
        RETURN_VOID_IF_FAILED("Failed to get blit video frame");
    }

private:
    ComPtr<ID3D11Device> m_d3dDevice;
    ID3D11Texture2D *m_target;
    ComPtr<ID3D11VideoDevice> m_videoDevice;
    ComPtr<ID3D11VideoProcessorEnumerator> m_videoEnumerator;
    ComPtr<ID3D11VideoProcessor> m_videoProcessor;
    ComPtr<ID3D11VideoProcessorOutputView> m_outputView;
};

#define CAMERA_SAMPLE_QUEUE_SIZE 5
class QWinRTCameraVideoRendererControlPrivate
{
public:
    QScopedPointer<D3DVideoBlitter> blitter;
    ComPtr<IMF2DBuffer> buffers[CAMERA_SAMPLE_QUEUE_SIZE];
    QAtomicInteger<quint16> writeIndex;
    QAtomicInteger<quint16> readIndex;
    QVideoFrame::PixelFormat cameraSampleformat;
    int cameraSampleSize;
    uint videoProbesCounter;
    bool getCameraSampleInfo(const ComPtr<IMF2DBuffer> &buffer,
                             QWinRTAbstractVideoRendererControl::BlitMode *mode);
    ComPtr<IMF2DBuffer> dequeueBuffer();
};

bool QWinRTCameraVideoRendererControlPrivate::getCameraSampleInfo(const ComPtr<IMF2DBuffer> &buffer,
                                                                  QWinRTAbstractVideoRendererControl::BlitMode *mode)
{
    Q_ASSERT(mode);
    ComPtr<ID3D11Texture2D> sourceTexture;
    ComPtr<IMFDXGIBuffer> dxgiBuffer;
    HRESULT hr = buffer.As(&dxgiBuffer);
    Q_ASSERT_SUCCEEDED(hr);
    hr = dxgiBuffer->GetResource(IID_PPV_ARGS(&sourceTexture));
    if (FAILED(hr)) {
        qErrnoWarning(hr, "The video frame does not support texture output");
        cameraSampleformat = QVideoFrame::Format_Invalid;
        return false;
    }
    D3D11_TEXTURE2D_DESC desc;
    sourceTexture->GetDesc(&desc);

    if (!(desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED))
        *mode = QWinRTAbstractVideoRendererControl::MediaFoundation;

    switch (desc.Format) {
    case DXGI_FORMAT_R8G8B8A8_TYPELESS:
        cameraSampleformat = QVideoFrame::Format_ARGB32;
        break;
    case DXGI_FORMAT_NV12:
        cameraSampleformat = QVideoFrame::Format_NV12;
        break;
    case DXGI_FORMAT_YUY2:
        cameraSampleformat = QVideoFrame::Format_YUYV;
        break;
    default:
        cameraSampleformat = QVideoFrame::Format_Invalid;
        qErrnoWarning("Unsupported camera probe format.");
        return false;
    }
    DWORD pcbLength;
    hr = buffer->GetContiguousLength(&pcbLength);
    Q_ASSERT_SUCCEEDED(hr);
    cameraSampleSize = int(pcbLength);
    return true;
}

QWinRTCameraVideoRendererControl::QWinRTCameraVideoRendererControl(const QSize &size, QObject *parent)
    : QWinRTAbstractVideoRendererControl(size, parent), d_ptr(new QWinRTCameraVideoRendererControlPrivate)
{
    Q_D(QWinRTCameraVideoRendererControl);
    d->cameraSampleformat = QVideoFrame::Format_User;
    d->videoProbesCounter = 0;

#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
    // Workaround for certain devices which fail to blit.
    ComPtr<IEasClientDeviceInformation> deviceInfo;
    HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Security_ExchangeActiveSyncProvisioning_EasClientDeviceInformation).Get(),
                                    &deviceInfo);
    Q_ASSERT_SUCCEEDED(hr);
    HString deviceModel;
    hr = deviceInfo->get_SystemProductName(deviceModel.GetAddressOf());
    Q_ASSERT_SUCCEEDED(hr);
    const bool blacklist = blacklisted(L"RM-1045", deviceModel) // Lumia  930
                        || blacklisted(L"RM-937", deviceModel); // Lumia 1520
    setBlitMode(blacklist ? MediaFoundation : DirectVideo);
#endif
}

QWinRTCameraVideoRendererControl::~QWinRTCameraVideoRendererControl()
{
    shutdown();
}

bool QWinRTCameraVideoRendererControl::render(ID3D11Texture2D *target)
{
    Q_D(QWinRTCameraVideoRendererControl);
    ComPtr<IMF2DBuffer> buffer = d->dequeueBuffer();
    if (!buffer) {
        emit bufferRequested();
        return false;
    }

    ComPtr<ID3D11Texture2D> sourceTexture;
    ComPtr<IMFDXGIBuffer> dxgiBuffer;
    HRESULT hr = buffer.As(&dxgiBuffer);
    Q_ASSERT_SUCCEEDED(hr);
    hr = dxgiBuffer->GetResource(IID_PPV_ARGS(&sourceTexture));
    if (FAILED(hr)) {
        qErrnoWarning(hr, "The video frame does not support texture output; aborting rendering.");
        return false;
    }

    if (!d->blitter || d->blitter->target() != target)
        d->blitter.reset(new D3DVideoBlitter(target));

    d->blitter->blit(sourceTexture.Get());

    emit bufferRequested();
    return true;
}

bool QWinRTCameraVideoRendererControl::dequeueFrame(QVideoFrame *frame)
{
    Q_ASSERT(frame);
    Q_D(QWinRTCameraVideoRendererControl);

    ComPtr<IMF2DBuffer> buffer = d->dequeueBuffer();
    if (!buffer || d->cameraSampleformat == QVideoFrame::Format_Invalid) {
        emit bufferRequested();
        return false;
    }

    QWinRTCameraVideoBuffer *videoBuffer = new QWinRTCameraVideoBuffer(buffer.Get(),
                                                                       d->cameraSampleSize,
                                                                       static_cast<QWinRTCameraControl *>(parent()));
    *frame = QVideoFrame(videoBuffer, size(), d->cameraSampleformat);

    emit bufferRequested();
    return true;
}

void QWinRTCameraVideoRendererControl::queueBuffer(IMF2DBuffer *buffer)
{
    Q_D(QWinRTCameraVideoRendererControl);
    Q_ASSERT(buffer);

    if (d->cameraSampleformat == QVideoFrame::Format_User) {
        BlitMode mode = blitMode();
        d->getCameraSampleInfo(buffer, &mode);
        setBlitMode(mode);
    }

    if (d->videoProbesCounter > 0 && d->cameraSampleformat != QVideoFrame::Format_Invalid) {
        QWinRTCameraVideoBuffer *videoBuffer = new QWinRTCameraVideoBuffer(buffer,
                                                                           d->cameraSampleSize,
                                                                           static_cast<QWinRTCameraControl *>(parent()));
        QVideoFrame frame(videoBuffer, size(), d->cameraSampleformat);
        emit videoFrameProbed(frame);
    }

    const quint16 writeIndex = (d->writeIndex + 1) % CAMERA_SAMPLE_QUEUE_SIZE;
    if (d->readIndex == writeIndex) // Drop new sample if queue is full
        return;
    d->buffers[d->writeIndex] = buffer;
    d->writeIndex = writeIndex;

    if (!surface()) {
        d->dequeueBuffer();
        emit bufferRequested();
    }
}

ComPtr<IMF2DBuffer> QWinRTCameraVideoRendererControlPrivate::dequeueBuffer()
{
    const quint16 currentReadIndex = readIndex;
    if (currentReadIndex == writeIndex)
        return nullptr;

    ComPtr<IMF2DBuffer> buffer = buffers[currentReadIndex];
    Q_ASSERT(buffer);
    buffers[currentReadIndex].Reset();
    readIndex = (currentReadIndex + 1) % CAMERA_SAMPLE_QUEUE_SIZE;
    return buffer;
}

void QWinRTCameraVideoRendererControl::discardBuffers()
{
    Q_D(QWinRTCameraVideoRendererControl);
    d->writeIndex = d->readIndex = 0;
    for (ComPtr<IMF2DBuffer> &buffer : d->buffers)
        buffer.Reset();
}

void QWinRTCameraVideoRendererControl::incrementProbe()
{
    Q_D(QWinRTCameraVideoRendererControl);
    ++d->videoProbesCounter;
}

void QWinRTCameraVideoRendererControl::decrementProbe()
{
    Q_D(QWinRTCameraVideoRendererControl);
    Q_ASSERT(d->videoProbesCounter > 0);
    --d->videoProbesCounter;
}

void QWinRTCameraVideoRendererControl::resetSampleFormat()
{
    Q_D(QWinRTCameraVideoRendererControl);
    d->cameraSampleformat = QVideoFrame::Format_User;
}

QT_END_NAMESPACE
