/****************************************************************************
**
** 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;

    IMFMediaTypeHandler *typeHandler = NULL;
    if (SUCCEEDED(stream->GetMediaTypeHandler(&typeHandler))) {
        GUID guidMajorType;
        if (SUCCEEDED(typeHandler->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;
    }
}
