/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Mobility Components.
**
** $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 "qmediacontent.h"
#include "qmediaplayercontrol.h"

#include <QtCore/qcoreapplication.h>
#include <QtCore/qdatetime.h>
#include <QtCore/qthread.h>
#include <QtCore/qvarlengtharray.h>
#include <QtCore/qdebug.h>
#include <QtCore/qfile.h>
#include <QtCore/qbuffer.h>

#include "mfplayercontrol.h"
#include "mfevrvideowindowcontrol.h"
#include "mfvideorenderercontrol.h"
#include "mfaudioendpointcontrol.h"

#include "mfplayersession.h"
#include "mfplayerservice.h"
#include "mfmetadatacontrol.h"
#include <mferror.h>
#include <nserror.h>
#include "sourceresolver.h"
#include "samplegrabber.h"
#include "mftvideo.h"
#include <wmcodecdsp.h>

//#define DEBUG_MEDIAFOUNDATION

MFPlayerSession::MFPlayerSession(MFPlayerService *playerService)
    : m_playerService(playerService)
    , m_cRef(1)
    , m_session(0)
    , m_presentationClock(0)
    , m_rateControl(0)
    , m_rateSupport(0)
    , m_volumeControl(0)
    , m_netsourceStatistics(0)
    , m_duration(0)
    , m_sourceResolver(0)
    , m_hCloseEvent(0)
    , m_closing(false)
    , m_pendingRate(1)
    , m_volume(100)
    , m_muted(false)
    , m_status(QMediaPlayer::NoMedia)
    , m_scrubbing(false)
    , m_restoreRate(1)
    , m_mediaTypes(0)
    , m_audioSampleGrabber(0)
    , m_audioSampleGrabberNode(0)
    , m_videoProbeMFT(0)
{
    QObject::connect(this, SIGNAL(sessionEvent(IMFMediaEvent*)), this, SLOT(handleSessionEvent(IMFMediaEvent*)));

    m_pendingState = NoPending;
    ZeroMemory(&m_state, sizeof(m_state));
    m_state.command = CmdStop;
    m_state.prevCmd = CmdNone;
    m_state.rate = 1.0f;
    ZeroMemory(&m_request, sizeof(m_request));
    m_request.command = CmdNone;
    m_request.prevCmd = CmdNone;
    m_request.rate = 1.0f;

    m_audioSampleGrabber = new AudioSampleGrabberCallback;
}

void MFPlayerSession::close()
{
#ifdef DEBUG_MEDIAFOUNDATION
    qDebug() << "close";
#endif

    clear();
    if (!m_session)
        return;

    HRESULT hr = S_OK;
    if (m_session) {
        m_closing = true;
        hr = m_session->Close();
        if (SUCCEEDED(hr)) {
            DWORD dwWaitResult = WaitForSingleObject(m_hCloseEvent, 100);
            if (dwWaitResult == WAIT_TIMEOUT) {
                qWarning() << "session close time out!";
            }
        }
         m_closing = false;
    }

    if (SUCCEEDED(hr)) {
        if (m_session)
            m_session->Shutdown();
        if (m_sourceResolver)
            m_sourceResolver->shutdown();
    }
    if (m_sourceResolver) {
        m_sourceResolver->Release();
        m_sourceResolver = 0;
    }
    if (m_videoProbeMFT) {
        m_videoProbeMFT->Release();
        m_videoProbeMFT = 0;
    }

    if (m_playerService->videoRendererControl()) {
        m_playerService->videoRendererControl()->releaseActivate();
    } else if (m_playerService->videoWindowControl()) {
        m_playerService->videoWindowControl()->releaseActivate();
    }

    if (m_session)
        m_session->Release();
    m_session = 0;
    if (m_hCloseEvent)
        CloseHandle(m_hCloseEvent);
    m_hCloseEvent = 0;
}

void MFPlayerSession::addProbe(MFAudioProbeControl *probe)
{
    m_audioSampleGrabber->addProbe(probe);
}

void MFPlayerSession::removeProbe(MFAudioProbeControl *probe)
{
    m_audioSampleGrabber->removeProbe(probe);
}

void MFPlayerSession::addProbe(MFVideoProbeControl* probe)
{
    if (m_videoProbes.contains(probe))
        return;

    m_videoProbes.append(probe);

    if (m_videoProbeMFT)
        m_videoProbeMFT->addProbe(probe);
}

void MFPlayerSession::removeProbe(MFVideoProbeControl* probe)
{
    m_videoProbes.removeOne(probe);

    if (m_videoProbeMFT)
        m_videoProbeMFT->removeProbe(probe);
}

MFPlayerSession::~MFPlayerSession()
{
    m_audioSampleGrabber->Release();
}


void MFPlayerSession::load(const QMediaContent &media, QIODevice *stream)
{
#ifdef DEBUG_MEDIAFOUNDATION
    qDebug() << "load";
#endif
    clear();
    QUrl url = media.request().url();

    if (m_status == QMediaPlayer::LoadingMedia && m_sourceResolver)
        m_sourceResolver->cancel();

    if (url.isEmpty() && !stream) {
        changeStatus(QMediaPlayer::NoMedia);
    } else if (stream && (!stream->isReadable())) {
        changeStatus(QMediaPlayer::InvalidMedia);
        emit error(QMediaPlayer::ResourceError, tr("Invalid stream source."), true);
    } else {
        createSession();
        changeStatus(QMediaPlayer::LoadingMedia);
        m_sourceResolver->load(url, stream);
    }
    emit positionChanged(position());
}

void MFPlayerSession::handleSourceError(long hr)
{
    QString errorString;
    QMediaPlayer::Error errorCode = QMediaPlayer::ResourceError;
    switch (hr) {
    case QMediaPlayer::FormatError:
        errorCode = QMediaPlayer::FormatError;
        errorString = tr("Attempting to play invalid Qt resource.");
        break;
    case NS_E_FILE_NOT_FOUND:
        errorString = tr("The system cannot find the file specified.");
        break;
    case NS_E_SERVER_NOT_FOUND:
        errorString = tr("The specified server could not be found.");
        break;
    case MF_E_UNSUPPORTED_BYTESTREAM_TYPE:
        errorCode = QMediaPlayer::FormatError;
        errorString = tr("Unsupported media type.");
        break;
    default:
        errorString = tr("Failed to load source.");
        break;
    }
    changeStatus(QMediaPlayer::InvalidMedia);
    emit error(errorCode, errorString, true);
}

void MFPlayerSession::handleMediaSourceReady()
{
    if (QMediaPlayer::LoadingMedia != m_status || !m_sourceResolver || m_sourceResolver != sender())
        return;
#ifdef DEBUG_MEDIAFOUNDATION
    qDebug() << "handleMediaSourceReady";
#endif
    HRESULT hr = S_OK;
    IMFMediaSource* mediaSource = m_sourceResolver->mediaSource();

    DWORD dwCharacteristics = 0;
    mediaSource->GetCharacteristics(&dwCharacteristics);
    emit seekableUpdate(MFMEDIASOURCE_CAN_SEEK & dwCharacteristics);

    IMFPresentationDescriptor* sourcePD;
    hr = mediaSource->CreatePresentationDescriptor(&sourcePD);
    if (SUCCEEDED(hr)) {
        m_duration = 0;
        m_playerService->metaDataControl()->updateSource(sourcePD, mediaSource);
        sourcePD->GetUINT64(MF_PD_DURATION, &m_duration);
        //convert from 100 nanosecond to milisecond
        emit durationUpdate(qint64(m_duration / 10000));
        setupPlaybackTopology(mediaSource, sourcePD);
        sourcePD->Release();
    } else {
        changeStatus(QMediaPlayer::InvalidMedia);
        emit error(QMediaPlayer::ResourceError, tr("Cannot create presentation descriptor."), true);
    }
}

MFPlayerSession::MediaType MFPlayerSession::getStreamType(IMFStreamDescriptor *stream) const
{
    if (!stream)
        return Unknown;

    struct SafeRelease {
        IMFMediaTypeHandler *ptr = nullptr;
        ~SafeRelease() { if (ptr) ptr->Release(); }
    } typeHandler;
    if (SUCCEEDED(stream->GetMediaTypeHandler(&typeHandler.ptr))) {
        GUID guidMajorType;
        if (SUCCEEDED(typeHandler.ptr->GetMajorType(&guidMajorType))) {
            if (guidMajorType == MFMediaType_Audio)
                return Audio;
            else if (guidMajorType == MFMediaType_Video)
                return Video;
        }
    }

    return Unknown;
}

void MFPlayerSession::setupPlaybackTopology(IMFMediaSource *source, IMFPresentationDescriptor *sourcePD)
{
    HRESULT hr = S_OK;
    // Get the number of streams in the media source.
    DWORD cSourceStreams = 0;
    hr = sourcePD->GetStreamDescriptorCount(&cSourceStreams);
    if (FAILED(hr)) {
        changeStatus(QMediaPlayer::UnknownMediaStatus);
        emit error(QMediaPlayer::ResourceError, tr("Failed to get stream count."), true);
        return;
    }

    IMFTopology *topology;
    hr = MFCreateTopology(&topology);
    if (FAILED(hr)) {
        changeStatus(QMediaPlayer::UnknownMediaStatus);
        emit error(QMediaPlayer::ResourceError, tr("Failed to create topology."), true);
        return;
    }

    // Remember output node id for a first video stream
    TOPOID outputNodeId = -1;

    // For each stream, create the topology nodes and add them to the topology.
    DWORD succeededCount = 0;
    for (DWORD i = 0; i < cSourceStreams; i++)
    {
        BOOL fSelected = FALSE;
        bool streamAdded = false;
        IMFStreamDescriptor *streamDesc = NULL;

        HRESULT hr = sourcePD->GetStreamDescriptorByIndex(i, &fSelected, &streamDesc);
        if (SUCCEEDED(hr)) {
            // The media might have multiple audio and video streams,
            // only use one of each kind, and only if it is selected by default.
            MediaType mediaType = getStreamType(streamDesc);
            if (mediaType != Unknown
                    && ((m_mediaTypes & mediaType) == 0) // Check if this type isn't already added
                    && fSelected) {

                IMFTopologyNode *sourceNode = addSourceNode(topology, source, sourcePD, streamDesc);
                if (sourceNode) {
                    IMFTopologyNode *outputNode = addOutputNode(mediaType, topology, 0);
                    if (outputNode) {
                        bool connected = false;
                        if (mediaType == Audio) {
                            if (!m_audioSampleGrabberNode)
                                connected = setupAudioSampleGrabber(topology, sourceNode, outputNode);
                        } else if (mediaType == Video && outputNodeId == -1) {
                            // Remember video output node ID.
                            outputNode->GetTopoNodeID(&outputNodeId);
                        }

                        if (!connected)
                            hr = sourceNode->ConnectOutput(0, outputNode, 0);

                        if (FAILED(hr)) {
                            emit error(QMediaPlayer::FormatError, tr("Unable to play any stream."), false);
                        } else {
                            streamAdded = true;
                            succeededCount++;
                            m_mediaTypes |= mediaType;
                            switch (mediaType) {
                            case Audio:
                                emit audioAvailable();
                                break;
                            case Video:
                                emit videoAvailable();
                                break;
                            }
                        }
                        outputNode->Release();
                    }
                    sourceNode->Release();
                }
            }

            if (fSelected && !streamAdded)
                sourcePD->DeselectStream(i);

            streamDesc->Release();
        }
    }

    if (succeededCount == 0) {
        changeStatus(QMediaPlayer::InvalidMedia);
        emit error(QMediaPlayer::ResourceError, tr("Unable to play."), true);
    } else {
        if (outputNodeId != -1) {
            topology = insertMFT(topology, outputNodeId);
        }

        hr = m_session->SetTopology(MFSESSION_SETTOPOLOGY_IMMEDIATE, topology);
        if (FAILED(hr)) {
            changeStatus(QMediaPlayer::UnknownMediaStatus);
            emit error(QMediaPlayer::ResourceError, tr("Failed to set topology."), true);
        }
    }
    topology->Release();
}

IMFTopologyNode* MFPlayerSession::addSourceNode(IMFTopology* topology, IMFMediaSource* source,
                                                IMFPresentationDescriptor* presentationDesc, IMFStreamDescriptor *streamDesc)
{
    IMFTopologyNode *node = NULL;
    HRESULT hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
    if (SUCCEEDED(hr)) {
        hr = node->SetUnknown(MF_TOPONODE_SOURCE, source);
        if (SUCCEEDED(hr)) {
            hr = node->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, presentationDesc);
            if (SUCCEEDED(hr)) {
                hr = node->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, streamDesc);
                if (SUCCEEDED(hr)) {
                    hr = topology->AddNode(node);
                    if (SUCCEEDED(hr))
                        return node;
                }
            }
        }
        node->Release();
    }
    return NULL;
}

IMFTopologyNode* MFPlayerSession::addOutputNode(MediaType mediaType, IMFTopology* topology, DWORD sinkID)
{
    IMFTopologyNode *node = NULL;
    if (FAILED(MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node)))
        return NULL;

    IMFActivate *activate = NULL;
    if (mediaType == Audio) {
        activate = m_playerService->audioEndpointControl()->createActivate();
    } else if (mediaType == Video) {
        if (m_playerService->videoRendererControl()) {
            activate = m_playerService->videoRendererControl()->createActivate();
        } else if (m_playerService->videoWindowControl()) {
            activate = m_playerService->videoWindowControl()->createActivate();
        } else {
            qWarning() << "no videoWindowControl or videoRendererControl, unable to add output node for video data";
        }
    } else {
        // Unknown stream type.
        emit error(QMediaPlayer::FormatError, tr("Unknown stream type."), false);
    }

    if (!activate
            || FAILED(node->SetObject(activate))
            || FAILED(node->SetUINT32(MF_TOPONODE_STREAMID, sinkID))
            || FAILED(node->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE))
            || FAILED(topology->AddNode(node))) {
        node->Release();
        node = NULL;
    }

    return node;
}

bool MFPlayerSession::addAudioSampleGrabberNode(IMFTopology *topology)
{
    HRESULT hr = S_OK;
    IMFMediaType *pType = 0;
    IMFActivate *sinkActivate = 0;
    do {
        hr = MFCreateMediaType(&pType);
        if (FAILED(hr))
            break;

        hr = pType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
        if (FAILED(hr))
            break;

        hr = pType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM);
        if (FAILED(hr))
            break;

        hr = MFCreateSampleGrabberSinkActivate(pType, m_audioSampleGrabber, &sinkActivate);
        if (FAILED(hr))
            break;

        // Note: Data is distorted if this attribute is enabled
        hr = sinkActivate->SetUINT32(MF_SAMPLEGRABBERSINK_IGNORE_CLOCK, FALSE);
        if (FAILED(hr))
            break;

        hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &m_audioSampleGrabberNode);
        if (FAILED(hr))
            break;

        hr = m_audioSampleGrabberNode->SetObject(sinkActivate);
        if (FAILED(hr))
            break;

        hr = m_audioSampleGrabberNode->SetUINT32(MF_TOPONODE_STREAMID, 0); // Identifier of the stream sink.
        if (FAILED(hr))
            break;

        hr = m_audioSampleGrabberNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE);
        if (FAILED(hr))
            break;

        hr = topology->AddNode(m_audioSampleGrabberNode);
        if (FAILED(hr))
            break;

        pType->Release();
        sinkActivate->Release();
        return true;
    } while (false);

    if (pType)
        pType->Release();
    if (sinkActivate)
        sinkActivate->Release();
    if (m_audioSampleGrabberNode) {
        m_audioSampleGrabberNode->Release();
        m_audioSampleGrabberNode = NULL;
    }
    return false;
}

bool MFPlayerSession::setupAudioSampleGrabber(IMFTopology *topology, IMFTopologyNode *sourceNode, IMFTopologyNode *outputNode)
{
    if (!addAudioSampleGrabberNode(topology))
        return false;

    HRESULT hr = S_OK;
    IMFTopologyNode *pTeeNode = NULL;

    IMFMediaTypeHandler *typeHandler = NULL;
    IMFMediaType *mediaType = NULL;
    do {
        hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &pTeeNode);
        if (FAILED(hr))
            break;
        hr = sourceNode->ConnectOutput(0, pTeeNode, 0);
        if (FAILED(hr))
            break;
        hr = pTeeNode->ConnectOutput(0, outputNode, 0);
        if (FAILED(hr))
            break;
        hr = pTeeNode->ConnectOutput(1, m_audioSampleGrabberNode, 0);
        if (FAILED(hr))
            break;
    } while (false);

    if (pTeeNode)
        pTeeNode->Release();
    if (mediaType)
        mediaType->Release();
    if (typeHandler)
        typeHandler->Release();
    return hr == S_OK;
}

QAudioFormat MFPlayerSession::audioFormatForMFMediaType(IMFMediaType *mediaType) const
{
    WAVEFORMATEX *wfx = 0;
    UINT32 size;
    HRESULT hr = MFCreateWaveFormatExFromMFMediaType(mediaType, &wfx, &size, MFWaveFormatExConvertFlag_Normal);
    if (FAILED(hr))
        return QAudioFormat();

    if (size < sizeof(WAVEFORMATEX)) {
        CoTaskMemFree(wfx);
        return QAudioFormat();
    }

    if (wfx->wFormatTag != WAVE_FORMAT_PCM) {
        CoTaskMemFree(wfx);
        return QAudioFormat();
    }

    QAudioFormat format;
    format.setSampleRate(wfx->nSamplesPerSec);
    format.setChannelCount(wfx->nChannels);
    format.setSampleSize(wfx->wBitsPerSample);
    format.setCodec("audio/pcm");
    format.setByteOrder(QAudioFormat::LittleEndian);
    if (format.sampleSize() == 8)
        format.setSampleType(QAudioFormat::UnSignedInt);
    else
        format.setSampleType(QAudioFormat::SignedInt);

    CoTaskMemFree(wfx);
    return format;
}

// BindOutputNode
// Sets the IMFStreamSink pointer on an output node.
// IMFActivate pointer in the output node must be converted to an
// IMFStreamSink pointer before the topology loader resolves the topology.
HRESULT BindOutputNode(IMFTopologyNode *pNode)
{
    IUnknown *nodeObject = NULL;
    IMFActivate *activate = NULL;
    IMFStreamSink *stream = NULL;
    IMFMediaSink *sink = NULL;

    HRESULT hr = pNode->GetObject(&nodeObject);
    if (FAILED(hr))
        return hr;

    hr = nodeObject->QueryInterface(IID_PPV_ARGS(&activate));
    if (SUCCEEDED(hr)) {
        DWORD dwStreamID = 0;

        // Try to create the media sink.
        hr = activate->ActivateObject(IID_PPV_ARGS(&sink));
        if (SUCCEEDED(hr))
           dwStreamID = MFGetAttributeUINT32(pNode, MF_TOPONODE_STREAMID, 0);

        if (SUCCEEDED(hr)) {
            // First check if the media sink already has a stream sink with the requested ID.
            hr = sink->GetStreamSinkById(dwStreamID, &stream);
            if (FAILED(hr)) {
                // Create the stream sink.
                hr = sink->AddStreamSink(dwStreamID, NULL, &stream);
            }
        }

        // Replace the node's object pointer with the stream sink.
        if (SUCCEEDED(hr)) {
            hr = pNode->SetObject(stream);
        }
    } else {
        hr = nodeObject->QueryInterface(IID_PPV_ARGS(&stream));
    }

    if (nodeObject)
        nodeObject->Release();
    if (activate)
        activate->Release();
    if (stream)
        stream->Release();
    if (sink)
        sink->Release();
    return hr;
}

// BindOutputNodes
// Sets the IMFStreamSink pointers on all of the output nodes in a topology.
HRESULT BindOutputNodes(IMFTopology *pTopology)
{
    IMFCollection *collection;

    // Get the collection of output nodes.
    HRESULT hr = pTopology->GetOutputNodeCollection(&collection);

    // Enumerate all of the nodes in the collection.
    if (SUCCEEDED(hr)) {
        DWORD cNodes;
        hr = collection->GetElementCount(&cNodes);

        if (SUCCEEDED(hr)) {
            for (DWORD i = 0; i < cNodes; i++) {
                IUnknown *element;
                hr = collection->GetElement(i, &element);
                if (FAILED(hr))
                    break;

                IMFTopologyNode *node;
                hr = element->QueryInterface(IID_IMFTopologyNode, (void**)&node);
                element->Release();
                if (FAILED(hr))
                    break;

                // Bind this node.
                hr = BindOutputNode(node);
                node->Release();
                if (FAILED(hr))
                    break;
            }
        }
        collection->Release();
    }

    return hr;
}

// This method binds output nodes to complete the topology,
// then loads the topology and inserts MFT between the output node
// and a filter connected to the output node.
IMFTopology *MFPlayerSession::insertMFT(IMFTopology *topology, TOPOID outputNodeId)
{
    bool isNewTopology = false;

    IMFTopoLoader *topoLoader = 0;
    IMFTopology *resolvedTopology = 0;
    IMFCollection *outputNodes = 0;

    do {
        if (FAILED(BindOutputNodes(topology)))
            break;

        if (FAILED(MFCreateTopoLoader(&topoLoader)))
            break;

        if (FAILED(topoLoader->Load(topology, &resolvedTopology, NULL))) {
            // Topology could not be resolved, adding ourselves a color converter
            // to the topology might solve the problem
            insertColorConverter(topology, outputNodeId);
            if (FAILED(topoLoader->Load(topology, &resolvedTopology, NULL)))
                break;
        }

        if (insertResizer(resolvedTopology))
            isNewTopology = true;

        // Get all output nodes and search for video output node.
        if (FAILED(resolvedTopology->GetOutputNodeCollection(&outputNodes)))
            break;

        DWORD elementCount = 0;
        if (FAILED(outputNodes->GetElementCount(&elementCount)))
            break;

        for (DWORD n = 0; n < elementCount; n++) {
            IUnknown *element = 0;
            IMFTopologyNode *node = 0;
            IUnknown *outputObject = 0;
            IMFTopologyNode *inputNode = 0;
            IMFTopologyNode *mftNode = 0;
            bool mftAdded = false;

            do {
                if (FAILED(outputNodes->GetElement(n, &element)))
                    break;

                if (FAILED(element->QueryInterface(IID_IMFTopologyNode, (void**)&node)))
                    break;

                TOPOID id;
                if (FAILED(node->GetTopoNodeID(&id)))
                    break;

                if (id != outputNodeId)
                    break;

                if (FAILED(node->GetObject(&outputObject)))
                    break;

                m_videoProbeMFT->setVideoSink(outputObject);

                // Insert MFT between the output node and the node connected to it.
                DWORD outputIndex = 0;
                if (FAILED(node->GetInput(0, &inputNode, &outputIndex)))
                    break;

                if (FAILED(MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &mftNode)))
                    break;

                if (FAILED(mftNode->SetObject(m_videoProbeMFT)))
                    break;

                if (FAILED(resolvedTopology->AddNode(mftNode)))
                    break;

                if (FAILED(inputNode->ConnectOutput(0, mftNode, 0)))
                    break;

                if (FAILED(mftNode->ConnectOutput(0, node, 0)))
                    break;

                mftAdded = true;
                isNewTopology = true;
            } while (false);

            if (mftNode)
                mftNode->Release();
            if (inputNode)
                inputNode->Release();
            if (node)
                node->Release();
            if (element)
                element->Release();
            if (outputObject)
                outputObject->Release();

            if (mftAdded)
                break;
            else
                m_videoProbeMFT->setVideoSink(NULL);
        }
    } while (false);

    if (outputNodes)
        outputNodes->Release();

    if (topoLoader)
        topoLoader->Release();

    if (isNewTopology) {
        topology->Release();
        return resolvedTopology;
    }

    if (resolvedTopology)
        resolvedTopology->Release();

    return topology;
}

// This method checks if the topology contains a color converter transform (CColorConvertDMO),
// if it does it inserts a resizer transform (CResizerDMO) to handle dynamic frame size change
// of the video stream.
// Returns true if it inserted a resizer
bool MFPlayerSession::insertResizer(IMFTopology *topology)
{
    bool inserted = false;
    WORD elementCount = 0;
    IMFTopologyNode *node = 0;
    IUnknown *object = 0;
    IWMColorConvProps *colorConv = 0;
    IMFTransform *resizer = 0;
    IMFTopologyNode *resizerNode = 0;
    IMFTopologyNode *inputNode = 0;

    HRESULT hr = topology->GetNodeCount(&elementCount);
    if (FAILED(hr))
        return false;

    for (WORD i = 0; i < elementCount; ++i) {
        if (node) {
            node->Release();
            node = 0;
        }
        if (object) {
            object->Release();
            object = 0;
        }

        if (FAILED(topology->GetNode(i, &node)))
            break;

        MF_TOPOLOGY_TYPE nodeType;
        if (FAILED(node->GetNodeType(&nodeType)))
            break;

        if (nodeType != MF_TOPOLOGY_TRANSFORM_NODE)
            continue;

        if (FAILED(node->GetObject(&object)))
            break;

        if (FAILED(object->QueryInterface(&colorConv)))
            continue;

        if (FAILED(CoCreateInstance(CLSID_CResizerDMO, NULL, CLSCTX_INPROC_SERVER, IID_IMFTransform, (void**)&resizer)))
            break;

        if (FAILED(MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &resizerNode)))
            break;

        if (FAILED(resizerNode->SetObject(resizer)))
            break;

        if (FAILED(topology->AddNode(resizerNode)))
            break;

        DWORD outputIndex = 0;
        if (FAILED(node->GetInput(0, &inputNode, &outputIndex))) {
            topology->RemoveNode(resizerNode);
            break;
        }

        if (FAILED(inputNode->ConnectOutput(0, resizerNode, 0))) {
            topology->RemoveNode(resizerNode);
            break;
        }

        if (FAILED(resizerNode->ConnectOutput(0, node, 0))) {
            inputNode->ConnectOutput(0, node, 0);
            topology->RemoveNode(resizerNode);
            break;
        }

        inserted = true;
        break;
    }

    if (node)
        node->Release();
    if (object)
        object->Release();
    if (colorConv)
        colorConv->Release();
    if (resizer)
        resizer->Release();
    if (resizerNode)
        resizerNode->Release();
    if (inputNode)
        inputNode->Release();

    return inserted;
}

// This method inserts a color converter (CColorConvertDMO) in the topology,
// typically to convert to RGB format.
// Usually this converter is automatically inserted when the topology is resolved but
// for some reason it fails to do so in some cases, we then do it ourselves.
void MFPlayerSession::insertColorConverter(IMFTopology *topology, TOPOID outputNodeId)
{
    IMFCollection *outputNodes = 0;

    if (FAILED(topology->GetOutputNodeCollection(&outputNodes)))
        return;

    DWORD elementCount = 0;
    if (FAILED(outputNodes->GetElementCount(&elementCount)))
        goto done;

    for (DWORD n = 0; n < elementCount; n++) {
        IUnknown *element = 0;
        IMFTopologyNode *node = 0;
        IMFTopologyNode *inputNode = 0;
        IMFTopologyNode *mftNode = 0;
        IMFTransform *converter = 0;

        do {
            if (FAILED(outputNodes->GetElement(n, &element)))
                break;

            if (FAILED(element->QueryInterface(IID_IMFTopologyNode, (void**)&node)))
                break;

            TOPOID id;
            if (FAILED(node->GetTopoNodeID(&id)))
                break;

            if (id != outputNodeId)
                break;

            DWORD outputIndex = 0;
            if (FAILED(node->GetInput(0, &inputNode, &outputIndex)))
                break;

            if (FAILED(MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &mftNode)))
                break;

            if (FAILED(CoCreateInstance(CLSID_CColorConvertDMO, NULL, CLSCTX_INPROC_SERVER, IID_IMFTransform, (void**)&converter)))
                break;

            if (FAILED(mftNode->SetObject(converter)))
                break;

            if (FAILED(topology->AddNode(mftNode)))
                break;

            if (FAILED(inputNode->ConnectOutput(0, mftNode, 0)))
                break;

            if (FAILED(mftNode->ConnectOutput(0, node, 0)))
                break;

        } while (false);

        if (mftNode)
            mftNode->Release();
        if (inputNode)
            inputNode->Release();
        if (node)
            node->Release();
        if (element)
            element->Release();
        if (converter)
            converter->Release();
    }

done:
    if (outputNodes)
        outputNodes->Release();
}

void MFPlayerSession::stop(bool immediate)
{
#ifdef DEBUG_MEDIAFOUNDATION
    qDebug() << "stop";
#endif
    if (!immediate && m_pendingState != NoPending) {
        m_request.setCommand(CmdStop);
    } else {
        if (m_state.command == CmdStop)
            return;

        if (m_scrubbing)
            scrub(false);

        if (SUCCEEDED(m_session->Stop())) {
            m_state.setCommand(CmdStop);
            m_pendingState = CmdPending;
            if (m_status != QMediaPlayer::EndOfMedia) {
                m_varStart.vt = VT_I8;
                m_varStart.hVal.QuadPart = 0;
            }
        } else {
            emit error(QMediaPlayer::ResourceError, tr("Failed to stop."), true);
        }
    }
}

void MFPlayerSession::start()
{
    if (m_status == QMediaPlayer::EndOfMedia)
        m_varStart.hVal.QuadPart = 0; // restart from the beginning

#ifdef DEBUG_MEDIAFOUNDATION
    qDebug() << "start";
#endif

    if (m_pendingState != NoPending) {
        m_request.setCommand(CmdStart);
    } else {
        if (m_state.command == CmdStart)
            return;

        if (m_scrubbing)
            scrub(false);

        if (SUCCEEDED(m_session->Start(&GUID_NULL, &m_varStart))) {
            m_state.setCommand(CmdStart);
            m_pendingState = CmdPending;
            PropVariantInit(&m_varStart);
        } else {
            emit error(QMediaPlayer::ResourceError, tr("failed to start playback"), true);
        }
    }
}

void MFPlayerSession::pause()
{
#ifdef DEBUG_MEDIAFOUNDATION
    qDebug() << "pause";
#endif
    if (m_pendingState != NoPending) {
        m_request.setCommand(CmdPause);
    } else {
        if (m_state.command == CmdPause)
            return;

        if (SUCCEEDED(m_session->Pause())) {
            m_state.setCommand(CmdPause);
            m_pendingState = CmdPending;
        } else {
            emit error(QMediaPlayer::ResourceError, tr("Failed to pause."), false);
        }
    }
}

void MFPlayerSession::changeStatus(QMediaPlayer::MediaStatus newStatus)
{
    if (m_status == newStatus)
        return;
#ifdef DEBUG_MEDIAFOUNDATION
    qDebug() << "MFPlayerSession::changeStatus" << newStatus;
#endif
    m_status = newStatus;
    emit statusChanged();
}

QMediaPlayer::MediaStatus MFPlayerSession::status() const
{
    return m_status;
}

void MFPlayerSession::createSession()
{
    close();

    m_hCloseEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    m_sourceResolver = new SourceResolver();
    QObject::connect(m_sourceResolver, SIGNAL(mediaSourceReady()), this, SLOT(handleMediaSourceReady()));
    QObject::connect(m_sourceResolver, SIGNAL(error(long)), this, SLOT(handleSourceError(long)));

    m_videoProbeMFT = new MFTransform;
    for (int i = 0; i < m_videoProbes.size(); ++i)
        m_videoProbeMFT->addProbe(m_videoProbes.at(i));

    Q_ASSERT(m_session == NULL);
    HRESULT hr = MFCreateMediaSession(NULL, &m_session);
    if (FAILED(hr)) {
        changeStatus(QMediaPlayer::UnknownMediaStatus);
        emit error(QMediaPlayer::ResourceError, tr("Unable to create mediasession."), true);
    }

    hr = m_session->BeginGetEvent(this, m_session);

    if (FAILED(hr)) {
        changeStatus(QMediaPlayer::UnknownMediaStatus);
        emit error(QMediaPlayer::ResourceError, tr("Unable to pull session events."), false);
    }

    PropVariantInit(&m_varStart);
    m_varStart.vt = VT_I8;
    m_varStart.hVal.QuadPart = 0;
}

qint64 MFPlayerSession::position()
{
    if (m_request.command == CmdSeek || m_request.command == CmdSeekResume)
        return m_request.start;

    if (m_pendingState == SeekPending)
        return m_state.start;

    if (m_state.command == CmdStop)
        return qint64(m_varStart.hVal.QuadPart / 10000);

    if (m_presentationClock) {
        MFTIME time, sysTime;
        if (FAILED(m_presentationClock->GetCorrelatedTime(0, &time, &sysTime)))
            return 0;
        return qint64(time / 10000);
    }
    return 0;
}

void MFPlayerSession::setPosition(qint64 position)
{
#ifdef DEBUG_MEDIAFOUNDATION
    qDebug() << "setPosition";
#endif
    if (m_pendingState != NoPending) {
        m_request.setCommand(CmdSeek);
        m_request.start = position;
    } else {
        setPositionInternal(position, CmdNone);
    }
}

void MFPlayerSession::setPositionInternal(qint64 position, Command requestCmd)
{
    if (m_status == QMediaPlayer::EndOfMedia)
        changeStatus(QMediaPlayer::LoadedMedia);
    if (m_state.command == CmdStop && requestCmd != CmdSeekResume) {
        m_varStart.vt = VT_I8;
        m_varStart.hVal.QuadPart = LONGLONG(position * 10000);
        // Even though the position is not actually set on the session yet,
        // report it to have changed anyway for UI controls to be updated
        emit positionChanged(this->position());
        return;
    }

    if (m_state.command == CmdPause)
        scrub(true);

#ifdef DEBUG_MEDIAFOUNDATION
    qDebug() << "setPositionInternal";
#endif

    PROPVARIANT varStart;
    varStart.vt = VT_I8;
    varStart.hVal.QuadPart = LONGLONG(position * 10000);
    if (SUCCEEDED(m_session->Start(NULL, &varStart)))
    {
        PropVariantInit(&m_varStart);
        // Store the pending state.
        m_state.setCommand(CmdStart);
        m_state.start = position;
        m_pendingState = SeekPending;
    } else {
        emit error(QMediaPlayer::ResourceError, tr("Failed to seek."), true);
    }
}

qreal MFPlayerSession::playbackRate() const
{
    if (m_scrubbing)
        return m_restoreRate;
    return m_state.rate;
}

void MFPlayerSession::setPlaybackRate(qreal rate)
{
    if (m_scrubbing) {
        m_restoreRate = rate;
        emit playbackRateChanged(rate);
        return;
    }
    setPlaybackRateInternal(rate);
}

void MFPlayerSession::setPlaybackRateInternal(qreal rate)
{
    if (rate == m_request.rate)
        return;

    m_pendingRate = rate;
    if (!m_rateSupport)
        return;

#ifdef DEBUG_MEDIAFOUNDATION
    qDebug() << "setPlaybackRate";
#endif
    BOOL isThin = FALSE;

    //from MSDN http://msdn.microsoft.com/en-us/library/aa965220%28v=vs.85%29.aspx
    //Thinning applies primarily to video streams.
    //In thinned mode, the source drops delta frames and deliver only key frames.
    //At very high playback rates, the source might skip some key frames (for example, deliver every other key frame).

    if (FAILED(m_rateSupport->IsRateSupported(FALSE, rate, NULL))) {
        isThin = TRUE;
        if (FAILED(m_rateSupport->IsRateSupported(isThin, rate, NULL))) {
            qWarning() << "unable to set playbackrate = " << rate;
            m_pendingRate = m_request.rate = m_state.rate;
            return;
        }
    }
    if (m_pendingState != NoPending) {
        m_request.rate = rate;
        m_request.isThin = isThin;
        // Remember the current transport state (play, paused, etc), so that we
        // can restore it after the rate change, if necessary. However, if
        // anothercommand is already pending, that one takes precedent.
        if (m_request.command == CmdNone)
            m_request.setCommand(m_state.command);
    } else {
        //No pending operation. Commit the new rate.
        commitRateChange(rate, isThin);
    }
}

void MFPlayerSession::commitRateChange(qreal rate, BOOL isThin)
{
#ifdef DEBUG_MEDIAFOUNDATION
    qDebug() << "commitRateChange";
#endif
    Q_ASSERT(m_pendingState == NoPending);
    MFTIME  hnsSystemTime = 0;
    MFTIME  hnsClockTime = 0;
    Command cmdNow = m_state.command;
    bool resetPosition = false;
    // Allowed rate transitions:
    // Positive <-> negative:   Stopped
    // Negative <-> zero:       Stopped
    // Postive <-> zero:        Paused or stopped
    if ((rate > 0 && m_state.rate <= 0) || (rate < 0 && m_state.rate >= 0)) {
        if (cmdNow == CmdStart) {
            // Get the current clock position. This will be the restart time.
            m_presentationClock->GetCorrelatedTime(0, &hnsClockTime, &hnsSystemTime);
            Q_ASSERT(hnsSystemTime != 0);

            if (rate < 0 || m_state.rate < 0)
                m_request.setCommand(CmdSeekResume);
            else if (isThin || m_state.isThin)
                m_request.setCommand(CmdStartAndSeek);
            else
                m_request.setCommand(CmdStart);

            // We need to stop only when dealing with negative rates
            if (rate >= 0 && m_state.rate >= 0)
                pause();
            else
                stop();

            // If we deal with negative rates, we stopped the session and consequently
            // reset the position to zero. We then need to resume to the current position.
            m_request.start = hnsClockTime / 10000;
        } else if (cmdNow == CmdPause) {
            if (rate < 0 || m_state.rate < 0) {
                // The current state is paused.
                // For this rate change, the session must be stopped. However, the
                // session cannot transition back from stopped to paused.
                // Therefore, this rate transition is not supported while paused.
                qWarning() << "Unable to change rate from positive to negative or vice versa in paused state";
                rate = m_state.rate;
                isThin = m_state.isThin;
                goto done;
            }

            // This happens when resuming playback after scrubbing in pause mode.
            // This transition requires the session to be paused. Even though our
            // internal state is set to paused, the session might not be so we need
            // to enforce it
            if (rate > 0 && m_state.rate == 0) {
                m_state.setCommand(CmdNone);
                pause();
            }
        }
    } else if (rate == 0 && m_state.rate > 0) {
        if (cmdNow != CmdPause) {
            // Transition to paused.
            // This transisition requires the paused state.
            // Pause and set the rate.
            pause();

            // Request: Switch back to current state.
            m_request.setCommand(cmdNow);
        }
    } else if (rate == 0 && m_state.rate < 0) {
        // Changing rate from negative to zero requires to stop the session
        m_presentationClock->GetCorrelatedTime(0, &hnsClockTime, &hnsSystemTime);

        m_request.setCommand(CmdSeekResume);

        stop();

        // Resume to the current position (stop() will reset the position to 0)
        m_request.start = hnsClockTime / 10000;
    } else if (!isThin && m_state.isThin) {
        if (cmdNow == CmdStart) {
            // When thinning, only key frames are read and presented. Going back
            // to normal playback requires to reset the current position to force
            // the pipeline to decode the actual frame at the current position
            // (which might be earlier than the last decoded key frame)
            resetPosition = true;
        } else if (cmdNow == CmdPause) {
            // If paused, don't reset the position until we resume, otherwise
            // a new frame will be rendered
            m_presentationClock->GetCorrelatedTime(0, &hnsClockTime, &hnsSystemTime);
            m_request.setCommand(CmdSeekResume);
            m_request.start = hnsClockTime / 10000;
        }

    }

    // Set the rate.
    if (FAILED(m_rateControl->SetRate(isThin, rate))) {
        qWarning() << "failed to set playbackrate = " << rate;
        rate = m_state.rate;
        isThin = m_state.isThin;
        goto done;
    }

    if (resetPosition) {
        m_presentationClock->GetCorrelatedTime(0, &hnsClockTime, &hnsSystemTime);
        setPosition(hnsClockTime / 10000);
    }

done:
    // Adjust our current rate and requested rate.
    m_pendingRate = m_request.rate = m_state.rate = rate;
    if (rate != 0)
        m_state.isThin = isThin;
    emit playbackRateChanged(rate);
}

void MFPlayerSession::scrub(bool enableScrub)
{
    if (m_scrubbing == enableScrub)
        return;

    m_scrubbing = enableScrub;

    if (!canScrub()) {
        if (!enableScrub)
            m_pendingRate = m_restoreRate;
        return;
    }

    if (enableScrub)  {
        // Enter scrubbing mode. Cache the rate.
        m_restoreRate = m_request.rate;
        setPlaybackRateInternal(0.0f);
    } else {
        // Leaving scrubbing mode. Restore the old rate.
        setPlaybackRateInternal(m_restoreRate);
    }
}

int MFPlayerSession::volume() const
{
    return m_volume;
}

void MFPlayerSession::setVolume(int volume)
{
    if (m_volume == volume)
        return;
    m_volume = volume;

    if (!m_muted)
        setVolumeInternal(volume);

    emit volumeChanged(m_volume);
}

bool MFPlayerSession::isMuted() const
{
    return m_muted;
}

void MFPlayerSession::setMuted(bool muted)
{
    if (m_muted == muted)
        return;
    m_muted = muted;

    setVolumeInternal(muted ? 0 : m_volume);

    emit mutedChanged(m_muted);
}

void MFPlayerSession::setVolumeInternal(int volume)
{
    if (m_volumeControl) {
        quint32 channelCount = 0;
        if (!SUCCEEDED(m_volumeControl->GetChannelCount(&channelCount))
                || channelCount == 0)
            return;

        float scaled = volume * 0.01f;
        for (quint32 i = 0; i < channelCount; ++i)
            m_volumeControl->SetChannelVolume(i, scaled);
    }
}

int MFPlayerSession::bufferStatus()
{
    if (!m_netsourceStatistics)
        return 0;
    PROPVARIANT var;
    PropVariantInit(&var);
    PROPERTYKEY key;
    key.fmtid = MFNETSOURCE_STATISTICS;
    key.pid = MFNETSOURCE_BUFFERPROGRESS_ID;
    int progress = -1;
    // GetValue returns S_FALSE if the property is not available, which has
    // a value > 0. We therefore can't use the SUCCEEDED macro here.
    if (m_netsourceStatistics->GetValue(key, &var) == S_OK) {
        progress = var.lVal;
        PropVariantClear(&var);
    }

#ifdef DEBUG_MEDIAFOUNDATION
    qDebug() << "bufferStatus: progress = " << progress;
#endif

    return progress;
}

QMediaTimeRange MFPlayerSession::availablePlaybackRanges()
{
    // defaults to the whole media
    qint64 start = 0;
    qint64 end = qint64(m_duration / 10000);

    if (m_netsourceStatistics) {
        PROPVARIANT var;
        PropVariantInit(&var);
        PROPERTYKEY key;
        key.fmtid = MFNETSOURCE_STATISTICS;
        key.pid = MFNETSOURCE_SEEKRANGESTART_ID;
        // GetValue returns S_FALSE if the property is not available, which has
        // a value > 0. We therefore can't use the SUCCEEDED macro here.
        if (m_netsourceStatistics->GetValue(key, &var) == S_OK) {
            start = qint64(var.uhVal.QuadPart / 10000);
            PropVariantClear(&var);
            PropVariantInit(&var);
            key.pid = MFNETSOURCE_SEEKRANGEEND_ID;
            if (m_netsourceStatistics->GetValue(key, &var) == S_OK) {
                end = qint64(var.uhVal.QuadPart / 10000);
                PropVariantClear(&var);
            }
        }
    }

    return QMediaTimeRange(start, end);
}

HRESULT MFPlayerSession::QueryInterface(REFIID riid, void** ppvObject)
{
    if (!ppvObject)
        return E_POINTER;
    if (riid == IID_IMFAsyncCallback) {
        *ppvObject = static_cast<IMFAsyncCallback*>(this);
    } else if (riid == IID_IUnknown) {
        *ppvObject = static_cast<IUnknown*>(this);
    } else {
        *ppvObject =  NULL;
        return E_NOINTERFACE;
    }
    return S_OK;
}

ULONG MFPlayerSession::AddRef(void)
{
    return InterlockedIncrement(&m_cRef);
}

ULONG MFPlayerSession::Release(void)
{
    LONG cRef = InterlockedDecrement(&m_cRef);
    if (cRef == 0)
        this->deleteLater();
    return cRef;
}

HRESULT MFPlayerSession::Invoke(IMFAsyncResult *pResult)
{
    if (pResult->GetStateNoAddRef() != m_session)
        return S_OK;

    IMFMediaEvent *pEvent = NULL;
    // Get the event from the event queue.
    HRESULT hr = m_session->EndGetEvent(pResult, &pEvent);
    if (FAILED(hr)) {
        return S_OK;
    }

    MediaEventType meType = MEUnknown;
    hr = pEvent->GetType(&meType);
    if (FAILED(hr)) {
        pEvent->Release();
        return S_OK;
    }

    if (meType == MESessionClosed) {
        SetEvent(m_hCloseEvent);
        pEvent->Release();
        return S_OK;
    } else {
        hr = m_session->BeginGetEvent(this, m_session);
        if (FAILED(hr)) {
            pEvent->Release();
            return S_OK;
        }
    }

    if (!m_closing) {
        emit sessionEvent(pEvent);
    } else {
        pEvent->Release();
    }
    return S_OK;
}

void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
{
    HRESULT hrStatus = S_OK;
    HRESULT hr = sessionEvent->GetStatus(&hrStatus);
    if (FAILED(hr) || !m_session) {
        sessionEvent->Release();
        return;
    }

    MediaEventType meType = MEUnknown;
    hr = sessionEvent->GetType(&meType);

#ifdef DEBUG_MEDIAFOUNDATION
    if (FAILED(hrStatus))
        qDebug() << "handleSessionEvent: MediaEventType = " << meType << "Failed";
    else
        qDebug() << "handleSessionEvent: MediaEventType = " << meType;
#endif

    switch (meType) {
    case MENonFatalError: {
            PROPVARIANT var;
            PropVariantInit(&var);
            sessionEvent->GetValue(&var);
            qWarning() << "handleSessionEvent: non fatal error = " << var.ulVal;
            PropVariantClear(&var);
            emit error(QMediaPlayer::ResourceError, tr("Media session non-fatal error."), false);
        }
        break;
    case MESourceUnknown:
        changeStatus(QMediaPlayer::InvalidMedia);
        break;
    case MEError:
        changeStatus(QMediaPlayer::UnknownMediaStatus);
        qWarning() << "handleSessionEvent: serious error = " << hrStatus;
        emit error(QMediaPlayer::ResourceError, tr("Media session serious error."), true);
        break;
    case MESessionRateChanged:
        // If the rate change succeeded, we've already got the rate
        // cached. If it failed, try to get the actual rate.
        if (FAILED(hrStatus)) {
            PROPVARIANT var;
            PropVariantInit(&var);
            if (SUCCEEDED(sessionEvent->GetValue(&var)) && (var.vt == VT_R4))    {
                m_state.rate = var.fltVal;
            }
            emit playbackRateChanged(playbackRate());
        }
        break;
    case MESessionScrubSampleComplete :
        if (m_scrubbing)
            updatePendingCommands(CmdStart);
        break;
    case MESessionStarted:
        if (m_status == QMediaPlayer::EndOfMedia
                || m_status == QMediaPlayer::LoadedMedia) {
            // If the session started, then enough data is buffered to play
            changeStatus(QMediaPlayer::BufferedMedia);
        }

        updatePendingCommands(CmdStart);
        // playback started, we can now set again the procAmpValues if they have been
        // changed previously (these are lost when loading a new media)
        if (m_playerService->videoWindowControl()) {
            m_playerService->videoWindowControl()->applyImageControls();
        }
        break;
    case MESessionStopped:
        if (m_status != QMediaPlayer::EndOfMedia) {
            m_varStart.vt = VT_I8;
            m_varStart.hVal.QuadPart = 0;

            // Reset to Loaded status unless we are loading a new media
            // or changing the playback rate to negative values (stop required)
            if (m_status != QMediaPlayer::LoadingMedia && m_request.command != CmdSeekResume)
                changeStatus(QMediaPlayer::LoadedMedia);
        }
        updatePendingCommands(CmdStop);
        break;
    case MESessionPaused:
        updatePendingCommands(CmdPause);
        break;
    case MEReconnectStart:
#ifdef DEBUG_MEDIAFOUNDATION
            qDebug() << "MEReconnectStart" << ((hrStatus == S_OK) ? "OK" : "Failed");
#endif
        break;
    case MEReconnectEnd:
#ifdef DEBUG_MEDIAFOUNDATION
            qDebug() << "MEReconnectEnd" << ((hrStatus == S_OK) ? "OK" : "Failed");
#endif
        break;
    case MESessionTopologySet:
        if (FAILED(hrStatus)) {
            changeStatus(QMediaPlayer::InvalidMedia);
            emit error(QMediaPlayer::FormatError, tr("Unsupported media, a codec is missing."), true);
        } else {
            if (m_audioSampleGrabberNode) {
                IUnknown *obj = 0;
                if (SUCCEEDED(m_audioSampleGrabberNode->GetObject(&obj))) {
                    IMFStreamSink *streamSink = 0;
                    if (SUCCEEDED(obj->QueryInterface(IID_PPV_ARGS(&streamSink)))) {
                        IMFMediaTypeHandler *typeHandler = 0;
                        if (SUCCEEDED(streamSink->GetMediaTypeHandler((&typeHandler)))) {
                            IMFMediaType *mediaType = 0;
                            if (SUCCEEDED(typeHandler->GetCurrentMediaType(&mediaType))) {
                                m_audioSampleGrabber->setFormat(audioFormatForMFMediaType(mediaType));
                                mediaType->Release();
                            }
                            typeHandler->Release();
                        }
                        streamSink->Release();
                    }
                    obj->Release();
                }
            }

            // Topology is resolved and successfuly set, this happens only after loading a new media.
            // Make sure we always start the media from the beginning
            m_varStart.vt = VT_I8;
            m_varStart.hVal.QuadPart = 0;

            changeStatus(QMediaPlayer::LoadedMedia);
        }
        break;
    }

    if (FAILED(hrStatus)) {
        sessionEvent->Release();
        return;
    }

    switch (meType) {
    case MEBufferingStarted:
        changeStatus(QMediaPlayer::StalledMedia);
        emit bufferStatusChanged(bufferStatus());
        break;
    case MEBufferingStopped:
        changeStatus(QMediaPlayer::BufferedMedia);
        emit bufferStatusChanged(bufferStatus());
        break;
    case MESessionEnded:
        m_pendingState = NoPending;
        m_state.command = CmdStop;
        m_state.prevCmd = CmdNone;
        m_request.command = CmdNone;
        m_request.prevCmd = CmdNone;

        m_varStart.vt = VT_I8;
        //keep reporting the final position after end of media
        m_varStart.hVal.QuadPart = m_duration;
        emit positionChanged(position());

        changeStatus(QMediaPlayer::EndOfMedia);
        break;
    case MEEndOfPresentationSegment:
        break;
    case MESessionTopologyStatus: {
            UINT32 status;
            if (SUCCEEDED(sessionEvent->GetUINT32(MF_EVENT_TOPOLOGY_STATUS, &status))) {
                if (status == MF_TOPOSTATUS_READY) {
                    IMFClock* clock;
                    if (SUCCEEDED(m_session->GetClock(&clock))) {
                        clock->QueryInterface(IID_IMFPresentationClock, (void**)(&m_presentationClock));
                        clock->Release();
                    }

                    if (SUCCEEDED(MFGetService(m_session, MF_RATE_CONTROL_SERVICE, IID_PPV_ARGS(&m_rateControl)))) {
                        if (SUCCEEDED(MFGetService(m_session, MF_RATE_CONTROL_SERVICE, IID_PPV_ARGS(&m_rateSupport)))) {
                            if ((m_mediaTypes & Video) == Video
                                && SUCCEEDED(m_rateSupport->IsRateSupported(TRUE, 0, NULL)))
                                m_canScrub = true;
                        }
                        BOOL isThin = FALSE;
                        float rate = 1;
                        if (SUCCEEDED(m_rateControl->GetRate(&isThin, &rate))) {
                            if (m_pendingRate != rate) {
                                m_state.rate = m_request.rate = rate;
                                setPlaybackRate(m_pendingRate);
                            }
                        }
                    }
                    MFGetService(m_session, MFNETSOURCE_STATISTICS_SERVICE, IID_PPV_ARGS(&m_netsourceStatistics));

                    if (SUCCEEDED(MFGetService(m_session, MR_STREAM_VOLUME_SERVICE, IID_PPV_ARGS(&m_volumeControl))))
                        setVolumeInternal(m_muted ? 0 : m_volume);
                }
            }
        }
        break;
    default:
        break;
    }

    sessionEvent->Release();
}

void MFPlayerSession::updatePendingCommands(Command command)
{
    emit positionChanged(position());
    if (m_state.command != command || m_pendingState == NoPending)
        return;

    // Seek while paused completed
    if (m_pendingState == SeekPending && m_state.prevCmd == CmdPause) {
        m_pendingState = NoPending;
        // A seek operation actually restarts playback. If scrubbing is possible, playback rate
        // is set to 0.0 at this point and we just need to reset the current state to Pause.
        // If scrubbing is not possible, the playback rate was not changed and we explicitly need
        // to re-pause playback.
        if (!canScrub())
            pause();
        else
            m_state.setCommand(CmdPause);
    }

    m_pendingState = NoPending;

    //First look for rate changes.
    if (m_request.rate != m_state.rate) {
        commitRateChange(m_request.rate, m_request.isThin);
    }

    // Now look for new requests.
    if (m_pendingState == NoPending) {
        switch (m_request.command) {
        case CmdStart:
            start();
            break;
        case CmdPause:
            pause();
            break;
        case CmdStop:
            stop();
            break;
        case CmdSeek:
        case CmdSeekResume:
            setPositionInternal(m_request.start, m_request.command);
            break;
        case CmdStartAndSeek:
            start();
            setPositionInternal(m_request.start, m_request.command);
            break;
        }
        m_request.setCommand(CmdNone);
    }

}

bool MFPlayerSession::canScrub() const
{
    return m_canScrub && m_rateSupport && m_rateControl;
}

void MFPlayerSession::clear()
{
#ifdef DEBUG_MEDIAFOUNDATION
    qDebug() << "MFPlayerSession::clear";
#endif
    m_mediaTypes = 0;
    m_canScrub = false;

    m_pendingState = NoPending;
    m_state.command = CmdStop;
    m_state.prevCmd = CmdNone;
    m_request.command = CmdNone;
    m_request.prevCmd = CmdNone;

    if (m_presentationClock) {
        m_presentationClock->Release();
        m_presentationClock = NULL;
    }
    if (m_rateControl) {
        m_rateControl->Release();
        m_rateControl = NULL;
    }
    if (m_rateSupport) {
        m_rateSupport->Release();
        m_rateSupport = NULL;
    }
    if (m_volumeControl) {
        m_volumeControl->Release();
        m_volumeControl = NULL;
    }
    if (m_netsourceStatistics) {
        m_netsourceStatistics->Release();
        m_netsourceStatistics = NULL;
    }
    if (m_audioSampleGrabberNode) {
        m_audioSampleGrabberNode->Release();
        m_audioSampleGrabberNode = NULL;
    }
}
