/****************************************************************************
**
** 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 "qwinrtmediaplayercontrol.h"
#include "qwinrtplayerrenderercontrol.h"

#include <QtCore/QCoreApplication>
#include <QtCore/QFile>
#include <QtCore/qfunctions_winrt.h>
#include <QtCore/QSize>
#include <QtCore/QTimerEvent>
#include <QtCore/QUrl>
#include <QtMultimedia/QMediaPlaylist>
#include <QtConcurrent/QtConcurrentRun>

#include <dxgi.h>
#include <OleAuto.h>
#include <mfapi.h>
#include <mfmediaengine.h>

#include <wrl.h>
using namespace Microsoft::WRL;

QT_BEGIN_NAMESPACE

#define QT_WINRT_MEDIAPLAYER_STREAM_ID "__qtmultimedia_winrt_player_stream"

class MediaEngineNotify;
class MediaEngineSources;
class MediaEngineByteStream;
class QWinRTMediaPlayerControlPrivate
{
public:
    QMediaPlayer::State state;
    QMediaPlayer::MediaStatus mediaStatus;
    qint64 duration;
    qint64 position;
    qreal playbackRate;
    int volume;
    bool muted;
    int bufferStatus;
    bool seekable;
    bool hasVideo;
    bool hasAudio;

    QMediaContent media;
    QScopedPointer<QIODevice, QWinRTMediaPlayerControlPrivate> stream;
    QWinRTPlayerRendererControl *videoRenderer;

    ComPtr<MediaEngineNotify> notifier;
    ComPtr<MediaEngineSources> sources;
    ComPtr<MediaEngineByteStream> streamProvider;
    ComPtr<IMFAttributes> configuration;
    ComPtr<IMFMediaEngineEx> engine;

    quint32 resetToken;
    ComPtr<IMFDXGIDeviceManager> manager;

    // Automatically delete streams created by the player
    static inline void cleanup(QIODevice *device)
    {
        if (device && device->property(QT_WINRT_MEDIAPLAYER_STREAM_ID).toBool())
            device->deleteLater();
    }

    // Allows for deferred cleanup of the engine, which tends to block on shutdown
    static void cleanup(QWinRTMediaPlayerControlPrivate *d);
    static void shutdown(QWinRTMediaPlayerControlPrivate *d);
};

class MediaEngineNotify : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IMFMediaEngineNotify>
{
public:
    MediaEngineNotify(QWinRTMediaPlayerControl *q_ptr, QWinRTMediaPlayerControlPrivate *d_ptr)
        : q(q_ptr), d(d_ptr)
    {
    }

    HRESULT __stdcall EventNotify(DWORD event, DWORD_PTR param1, DWORD param2)
    {
        QMediaPlayer::State newState = d->state;
        QMediaPlayer::MediaStatus newStatus = d->mediaStatus;

        switch (event) {
        // Media change events
        case MF_MEDIA_ENGINE_EVENT_LOADEDMETADATA: {
            const bool hasAudio = d->engine->HasAudio();
            if (d->hasAudio != hasAudio) {
                d->hasAudio = hasAudio;
                emit q->audioAvailableChanged(d->hasAudio);
            }

            const bool hasVideo = d->engine->HasVideo();
            if (d->hasVideo != hasVideo) {
                d->hasVideo = hasVideo;
                emit q->audioAvailableChanged(d->hasAudio);
            }

            if (hasVideo) {
                HRESULT hr;
                DWORD width, height;
                hr = d->engine->GetNativeVideoSize(&width, &height);
                if (FAILED(hr))
                    break;
                d->videoRenderer->setSize(QSize(int(width), int(height)));
            }

            newStatus = QMediaPlayer::LoadedMedia;
            break;
        }
        case MF_MEDIA_ENGINE_EVENT_LOADSTART:
        case MF_MEDIA_ENGINE_EVENT_PROGRESS: {
            newStatus = QMediaPlayer::LoadingMedia;
            break;
        }
        case MF_MEDIA_ENGINE_EVENT_CANPLAY:
            d->bufferStatus = 100; // Fired when buffering is not used
            newStatus = d->state == QMediaPlayer::StoppedState ? QMediaPlayer::LoadedMedia
                                                               : QMediaPlayer::BufferedMedia;
            break;
        case MF_MEDIA_ENGINE_EVENT_BUFFERINGSTARTED:
        case MF_MEDIA_ENGINE_EVENT_BUFFERINGENDED: {
            PROPVARIANT stat;
            HRESULT hr = d->engine->GetStatistics(MF_MEDIA_ENGINE_STATISTIC_BUFFER_PROGRESS, &stat);
            if (SUCCEEDED(hr)) {
                d->bufferStatus = stat.lVal;
                PropVariantClear(&stat);
            }
            newStatus = d->state == QMediaPlayer::StoppedState ? QMediaPlayer::LoadedMedia
                    : (d->bufferStatus == 100 ? QMediaPlayer::BufferedMedia : QMediaPlayer::BufferingMedia);
            break;
        }
        //case MF_MEDIA_ENGINE_EVENT_SUSPEND: ???
        //case MF_MEDIA_ENGINE_EVENT_ABORT: ???
        case MF_MEDIA_ENGINE_EVENT_EMPTIED: {
            newState = QMediaPlayer::StoppedState;
            break;
        }
        // Transport controls
        case MF_MEDIA_ENGINE_EVENT_PLAY: {
            // If the media is already loaded, the playing event may not occur after stop
            if (d->mediaStatus != QMediaPlayer::LoadedMedia)
                break;
            Q_FALLTHROUGH();
        }
        case MF_MEDIA_ENGINE_EVENT_PLAYING: {
            newState = QMediaPlayer::PlayingState;
            newStatus = d->bufferStatus < 100 ? QMediaPlayer::BufferingMedia
                                              : QMediaPlayer::BufferedMedia;
            break;
        }
        case MF_MEDIA_ENGINE_EVENT_PAUSE: {
            newState = QMediaPlayer::PausedState;
            break;
        }
        case MF_MEDIA_ENGINE_EVENT_STALLED: {
            newStatus = QMediaPlayer::StalledMedia;
            break;
        }
        case MF_MEDIA_ENGINE_EVENT_WAITING: {
            newStatus = QMediaPlayer::StalledMedia;
            break;
        }
        case MF_MEDIA_ENGINE_EVENT_ENDED: {
            newState = QMediaPlayer::StoppedState;
            newStatus = QMediaPlayer::EndOfMedia;
            break;
        }
        // Media attributes
        case MF_MEDIA_ENGINE_EVENT_DURATIONCHANGE: {
            double duration = d->engine->GetDuration() * 1000;
            if (!qFuzzyCompare(d->duration, duration)) {
                d->duration = qint64(duration);
                emit q->durationChanged(d->duration);
            }
            break;
        }
        case MF_MEDIA_ENGINE_EVENT_TIMEUPDATE: {
            double position = d->engine->GetCurrentTime() * 1000;
            if (!qFuzzyCompare(d->position, position)) {
                d->position = qint64(position);
                emit q->positionChanged(d->position);
            }
            // Stopped state: paused at beginning
            if (qFuzzyIsNull(position) && d->state == QMediaPlayer::PausedState)
                newState = QMediaPlayer::StoppedState;
            break;
        }
        case MF_MEDIA_ENGINE_EVENT_RATECHANGE: {
            double playbackRate = d->engine->GetPlaybackRate();
            if (!qFuzzyCompare(d->playbackRate, playbackRate)) {
                d->playbackRate = playbackRate;
                emit q->playbackRateChanged(d->playbackRate);
            }
            break;
        }
        // Error handling
        case MF_MEDIA_ENGINE_EVENT_ERROR: {
            newState = QMediaPlayer::StoppedState;
            newStatus = QMediaPlayer::InvalidMedia;
            switch (param1) {
            default:
            case MF_MEDIA_ENGINE_ERR_NOERROR:
                newStatus = QMediaPlayer::UnknownMediaStatus;
                emit q->error(QMediaPlayer::ResourceError, qt_error_string(int(param2)));
                break;
            case MF_MEDIA_ENGINE_ERR_ABORTED:
                if (d->mediaStatus == QMediaPlayer::StalledMedia || d->mediaStatus == QMediaPlayer::BufferingMedia)
                    d->mediaStatus = QMediaPlayer::LoadedMedia;
                emit q->error(QMediaPlayer::ResourceError, QStringLiteral("The process of fetching the media resource was stopped at the user's request."));
                break;
            case MF_MEDIA_ENGINE_ERR_NETWORK:
                if (d->mediaStatus == QMediaPlayer::StalledMedia || d->mediaStatus == QMediaPlayer::BufferingMedia)
                    d->mediaStatus = QMediaPlayer::LoadedMedia;
                emit q->error(QMediaPlayer::NetworkError, QStringLiteral("A network error occurred while fetching the media resource."));
                break;
            case MF_MEDIA_ENGINE_ERR_DECODE:
                emit q->error(QMediaPlayer::FormatError, QStringLiteral("An error occurred while decoding the media resource."));
                break;
            case MF_MEDIA_ENGINE_ERR_SRC_NOT_SUPPORTED:
                emit q->error(QMediaPlayer::FormatError, QStringLiteral("The media resource is not supported."));
                break;
            case MF_MEDIA_ENGINE_ERR_ENCRYPTED:
                emit q->error(QMediaPlayer::FormatError, QStringLiteral("An error occurred while encrypting the media resource."));
                break;
            }
            break;
        }
        default:
            break;
        }

        if (d->videoRenderer)
            d->videoRenderer->setActive(d->state == QMediaPlayer::PlayingState &&
                                        d->videoRenderer->size().isValid());

        const QMediaPlayer::MediaStatus oldMediaStatus = d->mediaStatus;
        const QMediaPlayer::State oldState = d->state;
        d->mediaStatus = newStatus;
        d->state = newState;

        if (d->mediaStatus != oldMediaStatus)
            emit q->mediaStatusChanged(d->mediaStatus);

        if (d->state != oldState)
            emit q->stateChanged(d->state);

        return S_OK;
    }

private:
    QWinRTMediaPlayerControl *q;
    QWinRTMediaPlayerControlPrivate *d;
};

class MediaEngineSources : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IMFMediaEngineSrcElements>
{
public:
    MediaEngineSources(QWinRTMediaPlayerControlPrivate *d_ptr)
        : d(d_ptr)
    {
    }

    DWORD __stdcall GetLength()
    {
        return DWORD(d->media.resources().length());
    }

    HRESULT __stdcall GetURL(DWORD index, BSTR *url)
    {
        const QString resourceUrl = d->media.resources().value(int(index)).url().toString();
        *url = SysAllocString((const OLECHAR *)resourceUrl.utf16());
        return S_OK;
    }

    HRESULT __stdcall GetType(DWORD index, BSTR *type)
    {
        const QString resourceType = d->media.resources().value(int(index)).mimeType();
        *type = SysAllocString((const OLECHAR *)resourceType.utf16());
        return S_OK;
    }

    HRESULT __stdcall GetMedia(DWORD index, BSTR *media)
    {
        Q_UNUSED(index);
        *media = nullptr;
        return S_OK;
    }

    HRESULT __stdcall AddElement(BSTR url, BSTR type, BSTR media)
    {
        Q_UNUSED(url);
        Q_UNUSED(type);
        Q_UNUSED(media);
        return E_NOTIMPL;
    }

    HRESULT __stdcall RemoveAllElements()
    {
        return E_NOTIMPL;
    }

private:
    QWinRTMediaPlayerControlPrivate *d;
};

class MediaEngineReadResult : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IUnknown>
{
public:
    MediaEngineReadResult(BYTE *bytes, ULONG maxLength)
        : bytes(bytes), maxLength(maxLength) { }

    void read(QIODevice *device)
    {
        bytesRead = ULONG(device->read(reinterpret_cast<char *>(bytes), maxLength));
    }

    BYTE *bytes;
    ULONG maxLength;
    ULONG bytesRead;
};

class MediaEngineByteStream : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IMFByteStream>
{
public:
    MediaEngineByteStream(QWinRTMediaPlayerControlPrivate *d_ptr)
        : d(d_ptr)
    {
    }

    HRESULT __stdcall GetCapabilities(DWORD *capabilities)
    {
        *capabilities |= MFBYTESTREAM_IS_READABLE;
        if (!d->stream->isSequential())
            *capabilities |= MFBYTESTREAM_IS_SEEKABLE;
        return S_OK;
    }

    HRESULT __stdcall GetLength(QWORD *length)
    {
        *length = QWORD(d->stream->size());
        return S_OK;
    }

    HRESULT __stdcall SetLength(QWORD length)
    {
        Q_UNUSED(length);
        return E_NOTIMPL;
    }

    HRESULT __stdcall GetCurrentPosition(QWORD *position)
    {
        *position = QWORD(d->stream->pos());
        return S_OK;
    }

    HRESULT __stdcall SetCurrentPosition(QWORD position)
    {
        const qint64 pos = qint64(position);
        if (pos >= d->stream->size()) {
            // MSDN states we should return E_INVALIDARG, but that immediately
            // stops playback and does not play remaining buffers in the queue.
            // For some formats this can cause losing up to 5 seconds of the
            // end of the stream.
            return S_FALSE;
        }

        const bool ok = d->stream->seek(pos);
        return ok ? S_OK : S_FALSE;
    }

    HRESULT __stdcall IsEndOfStream(BOOL *endOfStream)
    {
        *endOfStream = d->stream->atEnd() ? TRUE : FALSE;
        return S_OK;
    }

    HRESULT __stdcall Read(BYTE *bytes, ULONG maxlen, ULONG *bytesRead)
    {
        *bytesRead = ULONG(d->stream->read(reinterpret_cast<char *>(bytes), maxlen));
        return S_OK;
    }

    HRESULT __stdcall BeginRead(BYTE *bytes, ULONG maxLength, IMFAsyncCallback *callback, IUnknown *state)
    {
        ComPtr<MediaEngineReadResult> readResult = Make<MediaEngineReadResult>(bytes, maxLength);
        HRESULT hr;
        hr = MFCreateAsyncResult(readResult.Get(), callback, state, &asyncResult);
        RETURN_HR_IF_FAILED("Failed to create read callback result");
        finishRead();
        return S_OK;
    }

    HRESULT __stdcall EndRead(IMFAsyncResult *result, ULONG *bytesRead)
    {
        HRESULT hr;
        ComPtr<MediaEngineReadResult> readResult;
        hr = result->GetObject(&readResult);
        RETURN_HR_IF_FAILED("Failed to get read result");

        *bytesRead = readResult->bytesRead;
        return S_OK;
    }

    HRESULT __stdcall Write(const BYTE *bytes, ULONG maxlen, ULONG *bytesWritten)
    {
        Q_UNUSED(bytes);
        Q_UNUSED(maxlen);
        Q_UNUSED(bytesWritten);
        return E_NOTIMPL;
    }

    HRESULT __stdcall BeginWrite(const BYTE *bytes, ULONG maxlen, IMFAsyncCallback *callback, IUnknown *state)
    {
        Q_UNUSED(bytes);
        Q_UNUSED(maxlen);
        Q_UNUSED(callback);
        Q_UNUSED(state);
        return E_NOTIMPL;
    }

    HRESULT __stdcall EndWrite(IMFAsyncResult *result, ULONG *bytesWritten)
    {
        Q_UNUSED(result);
        Q_UNUSED(bytesWritten);
        return E_NOTIMPL;
    }

    HRESULT __stdcall Seek(MFBYTESTREAM_SEEK_ORIGIN origin, LONGLONG offset, DWORD flags, QWORD *position)
    {
        Q_UNUSED(flags);

        qint64 pos = offset;
        if (origin == msoCurrent)
            pos += d->stream->pos();

        const bool ok = d->stream->seek(pos);
        *position = QWORD(d->stream->pos());

        return ok ? S_OK : E_FAIL;
    }

    HRESULT __stdcall Flush()
    {
        return E_NOTIMPL;
    }

    HRESULT __stdcall Close()
    {
        if (asyncResult)
            finishRead();

        if (d->stream->property(QT_WINRT_MEDIAPLAYER_STREAM_ID).toBool())
            d->stream->close();

        return S_OK;
    }

    void finishRead()
    {
        if (!asyncResult)
            return;

        HRESULT hr;
        ComPtr<MediaEngineReadResult> readResult;
        hr = asyncResult->GetObject(&readResult);
        RETURN_VOID_IF_FAILED("Failed to get read result object");
        readResult->read(d->stream.data());
        hr = MFInvokeCallback(asyncResult.Get());
        RETURN_VOID_IF_FAILED("Failed to invoke read callback");
        asyncResult.Reset();
    }

private:
    QWinRTMediaPlayerControlPrivate *d;

    ComPtr<IMFAsyncResult> asyncResult;
};

void QWinRTMediaPlayerControlPrivate::cleanup(QWinRTMediaPlayerControlPrivate *d)
{
    QtConcurrent::run(&QWinRTMediaPlayerControlPrivate::shutdown, d);
}

void QWinRTMediaPlayerControlPrivate::shutdown(QWinRTMediaPlayerControlPrivate *d)
{
    d->engine->Shutdown();
    delete d;
}

QWinRTMediaPlayerControl::QWinRTMediaPlayerControl(IMFMediaEngineClassFactory *factory, QObject *parent)
    : QMediaPlayerControl(parent), d_ptr(new QWinRTMediaPlayerControlPrivate)
{
    Q_D(QWinRTMediaPlayerControl);

    d->state = QMediaPlayer::StoppedState;
    d->mediaStatus = QMediaPlayer::NoMedia;
    d->duration = 0;
    d->position = 0;
    d->playbackRate = 1.0;
    d->volume = 100;
    d->bufferStatus = 0;
    d->muted = false;
    d->seekable = false;
    d->hasAudio = false;
    d->hasVideo = false;
    d->videoRenderer = nullptr;
    d->notifier = Make<MediaEngineNotify>(this, d);

    HRESULT hr;
    hr = MFCreateDXGIDeviceManager(&d->resetToken, &d->manager);
    RETURN_VOID_IF_FAILED("Failed to create DXGI device manager");

    hr = MFCreateAttributes(&d->configuration, 1);
    Q_ASSERT_SUCCEEDED(hr);
    hr = d->configuration->SetUnknown(MF_MEDIA_ENGINE_CALLBACK, d->notifier.Get());
    Q_ASSERT_SUCCEEDED(hr);
    hr = d->configuration->SetUnknown(MF_MEDIA_ENGINE_DXGI_MANAGER, d->manager.Get());
    Q_ASSERT_SUCCEEDED(hr);
    hr = d->configuration->SetUINT32(MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT, DXGI_FORMAT_B8G8R8A8_UNORM);
    Q_ASSERT_SUCCEEDED(hr);

    ComPtr<IMFMediaEngine> engine;
    hr = factory->CreateInstance(0, d->configuration.Get(), &engine);
    Q_ASSERT_SUCCEEDED(hr);
    hr = engine.As(&d->engine);
    Q_ASSERT_SUCCEEDED(hr);

    hr = d->engine->SetVolume(1.0);
    Q_ASSERT_SUCCEEDED(hr);

    d->sources = Make<MediaEngineSources>(d);
    hr = d->engine->SetSourceElements(d->sources.Get());
    Q_ASSERT_SUCCEEDED(hr);

    d->streamProvider = Make<MediaEngineByteStream>(d);
}

QMediaPlayer::State QWinRTMediaPlayerControl::state() const
{
    Q_D(const QWinRTMediaPlayerControl);
    return d->state;
}

QMediaPlayer::MediaStatus QWinRTMediaPlayerControl::mediaStatus() const
{
    Q_D(const QWinRTMediaPlayerControl);
    return d->mediaStatus;
}

qint64 QWinRTMediaPlayerControl::duration() const
{
    Q_D(const QWinRTMediaPlayerControl);
    return d->duration;
}

qint64 QWinRTMediaPlayerControl::position() const
{
    Q_D(const QWinRTMediaPlayerControl);
    return d->position;
}

void QWinRTMediaPlayerControl::setPosition(qint64 position)
{
    Q_D(QWinRTMediaPlayerControl);

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

    HRESULT hr;
    hr = d->engine->SetCurrentTime(double(position)/1000);
    RETURN_VOID_IF_FAILED("Failed to seek to new position");

    d->position = position;
    emit positionChanged(d->position);

    if (d->mediaStatus == QMediaPlayer::EndOfMedia) {
        d->mediaStatus = QMediaPlayer::LoadedMedia;
        emit mediaStatusChanged(d->mediaStatus);
    }
}

int QWinRTMediaPlayerControl::volume() const
{
    Q_D(const QWinRTMediaPlayerControl);
    return d->volume;
}

void QWinRTMediaPlayerControl::setVolume(int volume)
{
    Q_D(QWinRTMediaPlayerControl);

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

    HRESULT hr;
    hr = d->engine->SetVolume(double(volume)/100);
    RETURN_VOID_IF_FAILED("Failed to set volume");

    d->volume = volume;
    emit volumeChanged(d->volume);
}

bool QWinRTMediaPlayerControl::isMuted() const
{
    Q_D(const QWinRTMediaPlayerControl);
    return d->muted;
}

void QWinRTMediaPlayerControl::setMuted(bool muted)
{
    Q_D(QWinRTMediaPlayerControl);

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

    HRESULT hr;
    hr = d->engine->SetMuted(muted);
    RETURN_VOID_IF_FAILED("Failed to mute volume");

    d->muted = muted;
    emit mutedChanged(d->muted);
}

int QWinRTMediaPlayerControl::bufferStatus() const
{
    Q_D(const QWinRTMediaPlayerControl);
    return d->bufferStatus;
}

bool QWinRTMediaPlayerControl::isAudioAvailable() const
{
    Q_D(const QWinRTMediaPlayerControl);
    return d->hasAudio;
}

bool QWinRTMediaPlayerControl::isVideoAvailable() const
{
    Q_D(const QWinRTMediaPlayerControl);
    return d->hasVideo;
}

bool QWinRTMediaPlayerControl::isSeekable() const
{
    Q_D(const QWinRTMediaPlayerControl);
    return d->seekable;
}

QMediaTimeRange QWinRTMediaPlayerControl::availablePlaybackRanges() const
{
    Q_D(const QWinRTMediaPlayerControl);
    return QMediaTimeRange(0, d->duration);
}

qreal QWinRTMediaPlayerControl::playbackRate() const
{
    Q_D(const QWinRTMediaPlayerControl);
    return d->playbackRate;
}

void QWinRTMediaPlayerControl::setPlaybackRate(qreal rate)
{
    Q_D(QWinRTMediaPlayerControl);

    if (qFuzzyCompare(d->playbackRate, rate))
        return;

    HRESULT hr;
    hr = d->engine->SetPlaybackRate(rate);
    RETURN_VOID_IF_FAILED("Failed to set playback rate");
}

QMediaContent QWinRTMediaPlayerControl::media() const
{
    Q_D(const QWinRTMediaPlayerControl);
    return d->media;
}

const QIODevice *QWinRTMediaPlayerControl::mediaStream() const
{
    Q_D(const QWinRTMediaPlayerControl);
    return d->stream.data();
}

void QWinRTMediaPlayerControl::setMedia(const QMediaContent &media, QIODevice *stream)
{
    Q_D(QWinRTMediaPlayerControl);

    if (d->media == media && d->stream.data() == stream)
        return;

    d->media = media;
    d->stream.reset(stream);
    if (d->hasAudio != false) {
        d->hasAudio = false;
        emit audioAvailableChanged(d->hasAudio);
    }
    if (d->hasVideo != false) {
        d->hasVideo = false;
        emit videoAvailableChanged(d->hasVideo);
    }
    if (d->seekable != false) {
        d->seekable = false;
        emit seekableChanged(d->seekable);
    }
    if (d->bufferStatus != 0) {
        d->bufferStatus = 0;
        emit bufferStatusChanged(d->bufferStatus);
    }
    if (d->position != 0) {
        d->position = 0;
        emit positionChanged(d->position);
    }
    if (d->duration != 0) {
        d->duration = 0;
        emit durationChanged(d->duration);
    }
    QMediaPlayer::MediaStatus mediaStatus = media.isNull() ? QMediaPlayer::NoMedia
                                                           : QMediaPlayer::LoadingMedia;
    if (d->mediaStatus != mediaStatus) {
        d->mediaStatus = mediaStatus;
        emit mediaStatusChanged(d->mediaStatus);
    }
    emit mediaChanged(media);

    QString urlString = media.request().url().toString();
    if (!d->stream) {
        // If we can read the file via Qt, use the byte stream approach
        if (media.request().url().isLocalFile()) {
            urlString = media.request().url().toLocalFile();
            QScopedPointer<QFile> file(new QFile(urlString));
            if (file->open(QFile::ReadOnly)) {
                file->setProperty(QT_WINRT_MEDIAPLAYER_STREAM_ID, true);
                d->stream.reset(file.take());
            }
        }
    }

    HRESULT hr;
    if (d->stream) {
        hr = d->engine->SetSourceFromByteStream(d->streamProvider.Get(),
                                                reinterpret_cast<BSTR>(urlString.data()));
        if (FAILED(hr)) {
            emit error(QMediaPlayer::ResourceError, qt_error_string(hr));
            return;
        }
        if (d->videoRenderer)
            d->videoRenderer->ensureReady();
        return;
    }

    // Let Windows handle all other URLs
    hr = d->engine->SetSource(nullptr); // Resets the byte stream
    Q_ASSERT_SUCCEEDED(hr);
    hr = d->engine->Load();
    if (FAILED(hr))
        emit error(QMediaPlayer::ResourceError, qt_error_string(hr));

    if (d->media.isNull() && d->stream.isNull())
        return;

    // Resume play/pause/stop
    switch (d->state) {
    case QMediaPlayer::StoppedState:
        stop();
        break;
    case QMediaPlayer::PlayingState:
        play();
        break;
    case QMediaPlayer::PausedState:
        pause();
        break;
    }
}

void QWinRTMediaPlayerControl::play()
{
    Q_D(QWinRTMediaPlayerControl);

    if (d->state != QMediaPlayer::PlayingState) {
        d->state = QMediaPlayer::PlayingState;
        emit stateChanged(d->state);
    }

    if (d->media.isNull() && d->stream.isNull())
        return;

    if (d->videoRenderer)
        d->videoRenderer->ensureReady();

    HRESULT hr = d->engine->Play();
    if (FAILED(hr)) {
        emit error(QMediaPlayer::ResourceError, qt_error_string(hr));
        return;
    }
}

void QWinRTMediaPlayerControl::pause()
{
    Q_D(QWinRTMediaPlayerControl);

    if (d->state != QMediaPlayer::PausedState) {
        d->state = QMediaPlayer::PausedState;
        emit stateChanged(d->state);
    }

    if (d->media.isNull() && d->stream.isNull())
        return;

    HRESULT hr;
    hr = d->engine->Pause();
    if (FAILED(hr)) {
        emit error(QMediaPlayer::ResourceError, qt_error_string(hr));
        return;
    }
}

void QWinRTMediaPlayerControl::stop()
{
    Q_D(QWinRTMediaPlayerControl);

    const QMediaPlayer::MediaStatus oldMediaStatus = d->mediaStatus;
    const QMediaPlayer::State oldState = d->state;

    d->state = QMediaPlayer::StoppedState;

    if (d->mediaStatus == QMediaPlayer::BufferedMedia
            || d->mediaStatus == QMediaPlayer::BufferingMedia) {
        d->mediaStatus = QMediaPlayer::LoadedMedia;
    }

    if (d->mediaStatus != oldMediaStatus)
        emit mediaStatusChanged(d->mediaStatus);

    if (d->state != oldState)
        emit stateChanged(d->state);

    if (d->media.isNull() && d->stream.isNull())
        return;

    setPosition(0);

    HRESULT hr;
    hr = d->engine->Pause();
    if (FAILED(hr)) {
        emit error(QMediaPlayer::ResourceError, qt_error_string(hr));
        return;
    }
}

QVideoRendererControl *QWinRTMediaPlayerControl::videoRendererControl()
{
    Q_D(QWinRTMediaPlayerControl);

    if (!d->videoRenderer) {
        d->videoRenderer = new QWinRTPlayerRendererControl(d->engine.Get(), d->manager.Get(),
                                                          d->resetToken, this);
    }

    return d->videoRenderer;
}

QT_END_NAMESPACE
