/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <dshow.h>
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif

#include "directshowplayerservice.h"

#include "directshowaudioendpointcontrol.h"
#include "directshowmetadatacontrol.h"
#include "vmr9videowindowcontrol.h"
#include "directshowiosource.h"
#include "directshowplayercontrol.h"
#include "directshowvideorenderercontrol.h"
#include "directshowutils.h"
#include "directshowglobal.h"
#include "directshowaudioprobecontrol.h"
#include "directshowvideoprobecontrol.h"
#include "directshowsamplegrabber.h"

#if QT_CONFIG(evr)
#include "directshowevrvideowindowcontrol.h"
#else
#include <mmreg.h>
#endif

#include "qmediacontent.h"

#include <QtMultimedia/private/qtmultimedia-config_p.h>

#include <QtCore/qcoreapplication.h>
#include <QtCore/qdatetime.h>
#include <QtCore/qdir.h>
#include <QtCore/qthread.h>
#include <QtCore/qvarlengtharray.h>
#include <QtCore/qsize.h>

#include <QtMultimedia/qaudiobuffer.h>
#include <QtMultimedia/qvideoframe.h>
#include <QtMultimedia/private/qmemoryvideobuffer_p.h>

#if QT_CONFIG(wmsdk)
#  include <wmsdk.h>
#endif

#ifndef Q_CC_MINGW
#  include <comdef.h>
#endif

QT_BEGIN_NAMESPACE

Q_GLOBAL_STATIC(DirectShowEventLoop, qt_directShowEventLoop)

static QString comError(HRESULT hr)
{
#ifndef Q_CC_MINGW // MinGW 5.3 no longer has swprintf_s().
    _com_error error(hr);
    return QString::fromWCharArray(error.ErrorMessage());
#else
    Q_UNUSED(hr)
    return QString();
#endif
}

// QMediaPlayer uses millisecond time units, direct show uses 100 nanosecond units.
static const int qt_directShowTimeScale = 10000;

class DirectShowPlayerServiceThread : public QThread
{
public:
    DirectShowPlayerServiceThread(DirectShowPlayerService *service)
        : m_service(service)
    {
    }

protected:
    void run() override { m_service->run(); }

private:
    DirectShowPlayerService *m_service;
};

DirectShowPlayerService::DirectShowPlayerService(QObject *parent)
    : QMediaService(parent)
    , m_loop(qt_directShowEventLoop())
    , m_taskHandle(::CreateEvent(nullptr, FALSE, FALSE, nullptr))
{
    m_playerControl = new DirectShowPlayerControl(this);
    m_metaDataControl = new DirectShowMetaDataControl(this);
    m_audioEndpointControl = new DirectShowAudioEndpointControl(this);

    m_taskThread = new DirectShowPlayerServiceThread(this);
    m_taskThread->start();
}

DirectShowPlayerService::~DirectShowPlayerService()
{
    {
        QMutexLocker locker(&m_mutex);

        releaseGraph();

        m_pendingTasks = Shutdown;
        ::SetEvent(m_taskHandle);
    }

    m_taskThread->wait();
    delete m_taskThread;

    if (m_audioOutput) {
        m_audioOutput->Release();
        m_audioOutput = nullptr;
    }

    if (m_videoOutput) {
        m_videoOutput->Release();
        m_videoOutput = nullptr;
    }

    delete m_playerControl;
    delete m_audioEndpointControl;
    delete m_metaDataControl;
    delete m_videoRendererControl;
    delete m_videoWindowControl;
    delete m_audioProbeControl;
    delete m_videoProbeControl;

    ::CloseHandle(m_taskHandle);
}

QMediaControl *DirectShowPlayerService::requestControl(const char *name)
{
    if (qstrcmp(name, QMediaPlayerControl_iid) == 0)
        return m_playerControl;
    if (qstrcmp(name, QAudioOutputSelectorControl_iid) == 0)
        return m_audioEndpointControl;
    if (qstrcmp(name, QMetaDataReaderControl_iid) == 0)
        return m_metaDataControl;
    if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
        if (!m_videoRendererControl && !m_videoWindowControl) {
            m_videoRendererControl = new DirectShowVideoRendererControl(m_loop);

            connect(m_videoRendererControl, &DirectShowVideoRendererControl::filterChanged,
                    this, &DirectShowPlayerService::videoOutputChanged);

            return m_videoRendererControl;
        }
        return nullptr;
    }
    if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
        if (!m_videoRendererControl && !m_videoWindowControl) {
            IBaseFilter *filter{};

#if QT_CONFIG(evr)
            if (!qgetenv("QT_DIRECTSHOW_NO_EVR").toInt()) {
                DirectShowEvrVideoWindowControl *evrControl = new DirectShowEvrVideoWindowControl;
                if ((filter = evrControl->filter()))
                    m_videoWindowControl = evrControl;
                else
                    delete evrControl;
            }
#endif
            // Fall back to the VMR9 if the EVR is not available
            if (!m_videoWindowControl) {
                Vmr9VideoWindowControl *vmr9Control = new Vmr9VideoWindowControl;
                filter = vmr9Control->filter();
                m_videoWindowControl = vmr9Control;
            }

            setVideoOutput(filter);

            return m_videoWindowControl;
        }
        return nullptr;
    }
    if (qstrcmp(name, QMediaAudioProbeControl_iid) == 0) {
        if (!m_audioProbeControl)
            m_audioProbeControl = new DirectShowAudioProbeControl();
        m_audioProbeControl->ref();
        updateAudioProbe();
        return m_audioProbeControl;
    }
    if (qstrcmp(name, QMediaVideoProbeControl_iid) == 0) {
        if (!m_videoProbeControl)
            m_videoProbeControl = new DirectShowVideoProbeControl();
        m_videoProbeControl->ref();
        updateVideoProbe();
        return m_videoProbeControl;
    }
    return nullptr;
}

void DirectShowPlayerService::releaseControl(QMediaControl *control)
{
    if (!control) {
        qWarning("QMediaService::releaseControl():"
                " Attempted release of null control");
    } else if (control == m_videoRendererControl) {
        setVideoOutput(nullptr);

        delete m_videoRendererControl;

        m_videoRendererControl = nullptr;
    } else if (control == m_videoWindowControl) {
        setVideoOutput(nullptr);

        delete m_videoWindowControl;

        m_videoWindowControl = nullptr;
    } else if (control == m_audioProbeControl) {
        if (!m_audioProbeControl->deref()) {
            DirectShowAudioProbeControl *old = m_audioProbeControl;
            m_audioProbeControl = nullptr;
            updateAudioProbe();
            delete old;
        }
    } else if (control == m_videoProbeControl) {
        if (!m_videoProbeControl->deref()) {
            DirectShowVideoProbeControl *old = m_videoProbeControl;
            m_videoProbeControl = nullptr;
            updateVideoProbe();
            delete old;
        }
    }
}

void DirectShowPlayerService::load(const QMediaContent &media, QIODevice *stream)
{
    QMutexLocker locker(&m_mutex);

    m_pendingTasks = 0;

    if (m_graph)
        releaseGraph();

    m_url = media.request().url();

    m_stream = stream;
    m_error = QMediaPlayer::NoError;
    m_errorString = QString();
    m_position = 0;
    m_seekPosition = -1;
    m_duration = 0;
    m_streamTypes = 0;
    m_executedTasks = 0;
    m_buffering = false;
    m_seekable = false;
    m_atEnd = false;
    m_dontCacheNextSeekResult = false;
    m_metaDataControl->setMetadata(QVariantMap());

    if (m_url.isEmpty() && !stream) {
        m_pendingTasks = 0;
        m_graphStatus = NoMedia;
    } else if (stream && (!stream->isReadable() || stream->isSequential())) {
        m_pendingTasks = 0;
        m_graphStatus = InvalidMedia;
        m_error = QMediaPlayer::ResourceError;
    } else {
        // {36b73882-c2c8-11cf-8b46-00805f6cef60}
        static const GUID iid_IFilterGraph2 = {
            0x36b73882, 0xc2c8, 0x11cf, {0x8b, 0x46, 0x00, 0x80, 0x5f, 0x6c, 0xef, 0x60} };
        m_graphStatus = Loading;

        DirectShowUtils::CoInitializeIfNeeded();
        m_graph = com_new<IFilterGraph2>(CLSID_FilterGraph, iid_IFilterGraph2);
        m_graphBuilder = com_new<ICaptureGraphBuilder2>(CLSID_CaptureGraphBuilder2, IID_ICaptureGraphBuilder2);

        // Attach the filter graph to the capture graph.
        HRESULT hr = m_graphBuilder->SetFiltergraph(m_graph);
        if (FAILED(hr)) {
            qCWarning(qtDirectShowPlugin, "[0x%x] Failed to attach filter to capture graph", hr);
            m_graphBuilder->Release();
            m_graphBuilder = nullptr;
        }

        if (stream)
            m_pendingTasks = SetStreamSource;
        else
            m_pendingTasks = SetUrlSource;

        ::SetEvent(m_taskHandle);
    }

    m_playerControl->updateError(m_error, m_errorString);
    m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable);
    m_playerControl->updateState(QMediaPlayer::StoppedState);
    m_playerControl->updatePosition(m_position);
    updateStatus();
}

void DirectShowPlayerService::doSetUrlSource(QMutexLocker *locker)
{
    IBaseFilter *source = nullptr;

    HRESULT hr = E_FAIL;
    if (m_url.scheme() == QLatin1String("http") || m_url.scheme() == QLatin1String("https")) {
        static const GUID clsid_WMAsfReader = {
            0x187463a0, 0x5bb7, 0x11d3, {0xac, 0xbe, 0x00, 0x80, 0xc7, 0x5e, 0x24, 0x6e} };

        // {56a868a6-0ad4-11ce-b03a-0020af0ba770}
        static const GUID iid_IFileSourceFilter = {
            0x56a868a6, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70} };

        if (IFileSourceFilter *fileSource = com_new<IFileSourceFilter>(clsid_WMAsfReader, iid_IFileSourceFilter)) {
            locker->unlock();
            hr = fileSource->Load(reinterpret_cast<const OLECHAR *>(m_url.toString().utf16()), nullptr);

            if (SUCCEEDED(hr)) {
                source = com_cast<IBaseFilter>(fileSource, IID_IBaseFilter);

                if (!SUCCEEDED(hr = m_graph->AddFilter(source, L"Source")) && source) {
                    source->Release();
                    source = nullptr;
                }
            }
            fileSource->Release();
            locker->relock();
        }
    }

    if (!SUCCEEDED(hr)) {
        locker->unlock();
        const QString urlString = m_url.isLocalFile()
            ? QDir::toNativeSeparators(m_url.toLocalFile()) : m_url.toString();
        hr = m_graph->AddSourceFilter(
                reinterpret_cast<const OLECHAR *>(urlString.utf16()), L"Source", &source);
        locker->relock();
    }

    if (SUCCEEDED(hr)) {
        m_executedTasks = SetSource;
        m_pendingTasks |= Render;

        if (m_audioOutput)
            m_pendingTasks |= SetAudioOutput;
        if (m_videoOutput)
            m_pendingTasks |= SetVideoOutput;
        if (m_audioProbeControl)
            m_pendingTasks |= SetAudioProbe;
        if (m_videoProbeControl)
            m_pendingTasks |= SetVideoProbe;

        if (m_rate != 1.0)
            m_pendingTasks |= SetRate;

        m_source = source;
    } else {
        m_graphStatus = InvalidMedia;

        switch (hr) {
        case VFW_E_UNKNOWN_FILE_TYPE:
            m_error = QMediaPlayer::FormatError;
            m_errorString = QString();
            break;
        default:
            m_error = QMediaPlayer::ResourceError;
            m_errorString = QString();
            qWarning("DirectShowPlayerService::doSetUrlSource: Unresolved error code 0x%x (%s)",
                     uint(hr), qPrintable(comError(hr)));
            break;
        }

        QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error)));
    }
}

void DirectShowPlayerService::doSetStreamSource(QMutexLocker *locker)
{
    Q_UNUSED(locker)
    DirectShowIOSource *source = new DirectShowIOSource(m_loop);
    source->setDevice(m_stream);

    const HRESULT hr = m_graph->AddFilter(source, L"Source");
    if (SUCCEEDED(hr)) {
        m_executedTasks = SetSource;
        m_pendingTasks |= Render;

        if (m_audioOutput)
            m_pendingTasks |= SetAudioOutput;
        if (m_videoOutput)
            m_pendingTasks |= SetVideoOutput;

        if (m_rate != 1.0)
            m_pendingTasks |= SetRate;

        m_source = source;
    } else {
        source->Release();

        m_pendingTasks = 0;
        m_graphStatus = InvalidMedia;

        m_error = QMediaPlayer::ResourceError;
        m_errorString = QString();
        qWarning("DirectShowPlayerService::doPlay: Unresolved error code 0x%x (%s)",
                 uint(hr), qPrintable(comError(hr)));

        QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error)));
    }
}

void DirectShowPlayerService::doRender(QMutexLocker *locker)
{
    m_pendingTasks |= m_executedTasks & (Play | Pause);

    if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) {
        control->Stop();
        control->Release();
    }

    if (m_pendingTasks & SetAudioOutput) {
        m_graph->AddFilter(m_audioOutput, L"AudioOutput");

        m_pendingTasks ^= SetAudioOutput;
        m_executedTasks |= SetAudioOutput;
    }
    if (m_pendingTasks & SetVideoOutput) {
        m_graph->AddFilter(m_videoOutput, L"VideoOutput");

        m_pendingTasks ^= SetVideoOutput;
        m_executedTasks |= SetVideoOutput;
    }

    if (m_pendingTasks & SetAudioProbe) {
        doSetAudioProbe(locker);
        m_pendingTasks ^= SetAudioProbe;
        m_executedTasks |= SetAudioProbe;
    }

    if (m_pendingTasks & SetVideoProbe) {
        doSetVideoProbe(locker);
        m_pendingTasks ^= SetVideoProbe;
        m_executedTasks |= SetVideoProbe;
    }

    IFilterGraph2 *graph = m_graph;
    graph->AddRef();

    QVarLengthArray<IBaseFilter *, 16> filters;
    m_source->AddRef();
    filters.append(m_source);

    bool rendered = false;

    HRESULT renderHr = S_OK;

    while (!filters.isEmpty()) {
        IEnumPins *pins = nullptr;
        IBaseFilter *filter = filters[filters.size() - 1];
        filters.removeLast();

        if (!(m_pendingTasks & ReleaseFilters) && SUCCEEDED(filter->EnumPins(&pins))) {
            int outputs = 0;
            for (IPin *pin = nullptr; pins->Next(1, &pin, nullptr) == S_OK; pin->Release()) {
                PIN_DIRECTION direction;
                if (pin->QueryDirection(&direction) == S_OK && direction == PINDIR_OUTPUT) {
                    ++outputs;

                    IPin *peer = nullptr;
                    if (pin->ConnectedTo(&peer) == S_OK) {
                        PIN_INFO peerInfo;
                        if (SUCCEEDED(peer->QueryPinInfo(&peerInfo)))
                            filters.append(peerInfo.pFilter);
                        peer->Release();
                    } else {
                        locker->unlock();
                        HRESULT hr = graph->RenderEx(pin, /*AM_RENDEREX_RENDERTOEXISTINGRENDERERS*/ 1, nullptr);
                        if (SUCCEEDED(hr)) {
                            rendered = true;
                            m_error = QMediaPlayer::NoError;
                        } else if (!(m_executedTasks & SetVideoOutput)) {
                            // Do not return an error if no video output is set yet.
                            rendered = true;
                            // Remember the error in this case.
                            // Handle it when playing is requested and no video output has been provided.
                            m_error = QMediaPlayer::ResourceError;
                            m_errorString = QString("%1: %2").arg(__FUNCTION__).arg(qt_error_string(hr));
                        } else if (renderHr == S_OK || renderHr == VFW_E_NO_DECOMPRESSOR){
                            renderHr = hr;
                        }
                        locker->relock();
                    }
                }
            }

            pins->Release();

            if (outputs == 0)
                rendered = true;
        }
        filter->Release();
    }

    if (m_audioOutput && !isConnected(m_audioOutput, PINDIR_INPUT)) {
        graph->RemoveFilter(m_audioOutput);

        m_executedTasks &= ~SetAudioOutput;
    }

    if (m_videoOutput && !isConnected(m_videoOutput, PINDIR_INPUT)) {
        graph->RemoveFilter(m_videoOutput);

        m_executedTasks &= ~SetVideoOutput;
    }

    graph->Release();

    if (!(m_pendingTasks & ReleaseFilters)) {
        if (rendered) {
            if (!(m_executedTasks & FinalizeLoad))
                m_pendingTasks |= FinalizeLoad;
        } else {
            m_pendingTasks = 0;

            m_graphStatus = InvalidMedia;

            if (!m_audioOutput && !m_videoOutput) {
                m_error = QMediaPlayer::ResourceError;
                m_errorString = QString();
            } else {
                switch (renderHr) {
                case VFW_E_UNSUPPORTED_AUDIO:
                case VFW_E_UNSUPPORTED_VIDEO:
                case VFW_E_UNSUPPORTED_STREAM:
                    m_error = QMediaPlayer::FormatError;
                    m_errorString = QString();
                    break;
                default:
                    m_error = QMediaPlayer::ResourceError;
                    m_errorString = QString();
                    qWarning("DirectShowPlayerService::doRender: Unresolved error code 0x%x (%s)",
                             uint(renderHr), qPrintable(comError(renderHr)));
                }
            }

            QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error)));
        }

        m_executedTasks |= Render;
    }
}

void DirectShowPlayerService::doFinalizeLoad(QMutexLocker *locker)
{
    if (m_graphStatus != Loaded) {
        if (IMediaEvent *event = com_cast<IMediaEvent>(m_graph, IID_IMediaEvent)) {
            event->GetEventHandle(reinterpret_cast<OAEVENT *>(&m_eventHandle));
            event->Release();
        }
        if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) {
            LONGLONG duration = 0;
            seeking->GetDuration(&duration);
            m_duration = duration / qt_directShowTimeScale;

            DWORD capabilities = 0;
            seeking->GetCapabilities(&capabilities);
            m_seekable = capabilities & AM_SEEKING_CanSeekAbsolute;

            seeking->Release();
        }
    }

    if ((m_executedTasks & SetOutputs) == SetOutputs) {
        m_streamTypes = AudioStream | VideoStream;
    } else {
        m_streamTypes = findStreamTypes(m_source);
    }

    m_executedTasks |= FinalizeLoad;

    m_graphStatus = Loaded;

    // Do not block gui thread while updating metadata from file.
    locker->unlock();
    DirectShowMetaDataControl::updateMetadata(m_url.toString(), m_metadata);
    locker->relock();

    QCoreApplication::postEvent(this, new QEvent(QEvent::Type(FinalizedLoad)));
}

void DirectShowPlayerService::releaseGraph()
{
    if (m_videoProbeControl)
        m_videoProbeControl->flushVideoFrame();

    if (m_graph) {
        if (m_executingTask != 0) {
            // {8E1C39A1-DE53-11cf-AA63-0080C744528D}
            static const GUID iid_IAMOpenProgress = {
                0x8E1C39A1, 0xDE53, 0x11cf, {0xAA, 0x63, 0x00, 0x80, 0xC7, 0x44, 0x52, 0x8D} };

            if (IAMOpenProgress *progress = com_cast<IAMOpenProgress>(
                    m_graph, iid_IAMOpenProgress)) {
                progress->AbortOperation();
                progress->Release();
            }
            m_graph->Abort();
        }

        m_pendingTasks = ReleaseGraph;

        ::SetEvent(m_taskHandle);

        m_loop->wait(&m_mutex);
        DirectShowUtils::CoUninitializeIfNeeded();
    }
}

void DirectShowPlayerService::doReleaseGraph(QMutexLocker *locker)
{
    Q_UNUSED(locker);

    if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) {
        control->Stop();
        control->Release();
    }

    doReleaseAudioProbe(locker);
    doReleaseVideoProbe(locker);

    if (m_source) {
        m_source->Release();
        m_source = nullptr;
    }

    m_eventHandle = nullptr;

    m_graph->Release();
    m_graph = nullptr;

    if (m_graphBuilder) {
        m_graphBuilder->Release();
        m_graphBuilder = nullptr;
    }

    m_loop->wake();
}

QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wmissing-field-initializers")

void DirectShowPlayerService::doSetVideoProbe(QMutexLocker *locker)
{
    Q_UNUSED(locker);

    if (!m_graph || !m_graphBuilder) {
        qCWarning(qtDirectShowPlugin, "Attempting to set a video probe without a valid graph!");
        return;
    }

    // Create the sample grabber, if necessary.
    if (!m_videoSampleGrabber) {
        m_videoSampleGrabber = new DirectShowSampleGrabber;
        connect(m_videoSampleGrabber, &DirectShowSampleGrabber::bufferAvailable, this, &DirectShowPlayerService::onVideoBufferAvailable);
    }

    if (FAILED(m_graph->AddFilter(m_videoSampleGrabber->filter(), L"Video Sample Grabber"))) {
        qCWarning(qtDirectShowPlugin, "Failed to add the video sample grabber into the graph!");
        return;
    }

    DirectShowMediaType mediaType({ MEDIATYPE_Video, MEDIASUBTYPE_ARGB32 });
    m_videoSampleGrabber->setMediaType(&mediaType);

    // Connect source filter to sample grabber filter.
    HRESULT hr = m_graphBuilder->RenderStream(nullptr, &MEDIATYPE_Video,
                                              m_source, nullptr, m_videoSampleGrabber->filter());
    if (FAILED(hr)) {
        qCWarning(qtDirectShowPlugin, "[0x%x] Failed to connect the video sample grabber", hr);
        return;
    }

    m_videoSampleGrabber->start(DirectShowSampleGrabber::CallbackMethod::BufferCB);
}

void DirectShowPlayerService::doSetAudioProbe(QMutexLocker *locker)
{
    Q_UNUSED(locker);

    if (!m_graph) {
        qCWarning(qtDirectShowPlugin, "Attempting to set an audio probe without a valid graph!");
        return;
    }

    // Create the sample grabber, if necessary.
    if (!m_audioSampleGrabber) {
        m_audioSampleGrabber = new DirectShowSampleGrabber;
        connect(m_audioSampleGrabber, &DirectShowSampleGrabber::bufferAvailable, this, &DirectShowPlayerService::onAudioBufferAvailable);
    }

    static const AM_MEDIA_TYPE mediaType { MEDIATYPE_Audio, MEDIASUBTYPE_PCM };
    m_audioSampleGrabber->setMediaType(&mediaType);

    if (FAILED(m_graph->AddFilter(m_audioSampleGrabber->filter(), L"Audio Sample Grabber"))) {
        qCWarning(qtDirectShowPlugin, "Failed to add the audio sample grabber into the graph!");
        return;
    }

    if (!DirectShowUtils::connectFilters(m_graph, m_source, m_audioSampleGrabber->filter(), true)) {
        // Connect source filter to sample grabber filter.
        HRESULT hr = m_graphBuilder
            ? m_graphBuilder->RenderStream(nullptr, &MEDIATYPE_Audio,
                                           m_source, nullptr, m_audioSampleGrabber->filter())
            : E_FAIL;
        if (FAILED(hr)) {
            qCWarning(qtDirectShowPlugin, "[0x%x] Failed to connect the audio sample grabber", hr);
            return;
        }
    }

    m_audioSampleGrabber->start(DirectShowSampleGrabber::CallbackMethod::BufferCB);
}

QT_WARNING_POP

void DirectShowPlayerService::doReleaseVideoProbe(QMutexLocker *locker)
{
    Q_UNUSED(locker);

    if (!m_graph)
        return;

    if (!m_videoSampleGrabber)
        return;

    m_videoSampleGrabber->stop();
    HRESULT hr = m_graph->RemoveFilter(m_videoSampleGrabber->filter());
    if (FAILED(hr)) {
        qCWarning(qtDirectShowPlugin, "Failed to remove the video sample grabber!");
        return;
    }

    m_videoSampleGrabber->deleteLater();
    m_videoSampleGrabber = nullptr;
}

void DirectShowPlayerService::doReleaseAudioProbe(QMutexLocker *locker)
{
    Q_UNUSED(locker);

    if (!m_graph)
        return;

    if (!m_audioSampleGrabber)
        return;

    m_audioSampleGrabber->stop();
    HRESULT hr = m_graph->RemoveFilter(m_audioSampleGrabber->filter());
    if (FAILED(hr)) {
        qCWarning(qtDirectShowPlugin, "Failed to remove the audio sample grabber!");
        return;
    }

    m_audioSampleGrabber->deleteLater();
    m_audioSampleGrabber = nullptr;
}

int DirectShowPlayerService::findStreamTypes(IBaseFilter *source) const
{
    QVarLengthArray<IBaseFilter *, 16> filters;
    source->AddRef();
    filters.append(source);

    int streamTypes = 0;

    while (!filters.isEmpty()) {
        IEnumPins *pins = nullptr;
        IBaseFilter *filter = filters[filters.size() - 1];
        filters.removeLast();

        if (SUCCEEDED(filter->EnumPins(&pins))) {
            for (IPin *pin = nullptr; pins->Next(1, &pin, nullptr) == S_OK; pin->Release()) {
                PIN_DIRECTION direction;
                if (pin->QueryDirection(&direction) == S_OK && direction == PINDIR_OUTPUT) {
                    DirectShowMediaType connectionType;
                    if (SUCCEEDED(pin->ConnectionMediaType(&connectionType))) {
                        IPin *peer = nullptr;

                        if (connectionType->majortype == MEDIATYPE_Audio) {
                            streamTypes |= AudioStream;
                        } else if (connectionType->majortype == MEDIATYPE_Video) {
                            streamTypes |= VideoStream;
                        } else if (SUCCEEDED(pin->ConnectedTo(&peer))) {
                            PIN_INFO peerInfo;
                            if (SUCCEEDED(peer->QueryPinInfo(&peerInfo)))
                                filters.append(peerInfo.pFilter);
                            peer->Release();
                        }
                    } else {
                        streamTypes |= findStreamType(pin);
                    }
                }
            }
            pins->Release();
        }
        filter->Release();
    }
    return streamTypes;
}

int DirectShowPlayerService::findStreamType(IPin *pin) const
{
    IEnumMediaTypes *types;

    if (SUCCEEDED(pin->EnumMediaTypes(&types))) {
        bool video = false;
        bool audio = false;
        bool other = false;

        for (AM_MEDIA_TYPE *type = nullptr;
                types->Next(1, &type, nullptr) == S_OK;
                DirectShowMediaType::deleteType(type)) {
            if (type->majortype == MEDIATYPE_Audio)
                audio = true;
            else if (type->majortype == MEDIATYPE_Video)
                video = true;
            else
                other = true;
        }
        types->Release();

        if (other)
            return 0;
        else if (audio && !video)
            return AudioStream;
        else if (!audio && video)
            return VideoStream;
        else
            return 0;
    } else {
        return 0;
    }
}

void DirectShowPlayerService::play()
{
    QMutexLocker locker(&m_mutex);

    m_pendingTasks &= ~Pause;
    m_pendingTasks |= Play;

    if (m_executedTasks & Render) {
        if (m_executedTasks & Stop) {
            m_atEnd = false;
            if (m_seekPosition == -1) {
                m_dontCacheNextSeekResult = true;
                m_seekPosition = 0;
                m_position = 0;
                m_pendingTasks |= Seek;
            }
            m_executedTasks ^= Stop;
        }

        ::SetEvent(m_taskHandle);
    }

    updateStatus();
}

void DirectShowPlayerService::doPlay(QMutexLocker *locker)
{
    // Invalidate if there is an error while loading.
    if (m_error != QMediaPlayer::NoError) {
        m_graphStatus = InvalidMedia;
        if (!m_errorString.isEmpty())
            qWarning("%s", qPrintable(m_errorString));
        m_errorString = QString();
        QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error)));
        return;
    }

    if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) {
        locker->unlock();
        HRESULT hr = control->Run();
        locker->relock();

        control->Release();

        if (SUCCEEDED(hr)) {
            m_executedTasks |= Play;

            QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange)));
        } else {
            m_error = QMediaPlayer::ResourceError;
            m_errorString = QString();
            qWarning("DirectShowPlayerService::doPlay: Unresolved error code 0x%x (%s)",
                     uint(hr), qPrintable(comError(hr)));

            QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error)));
        }
    }
}

void DirectShowPlayerService::pause()
{
    QMutexLocker locker(&m_mutex);

    m_pendingTasks &= ~Play;
    m_pendingTasks |= Pause;

    if (m_executedTasks & Render) {
        if (m_executedTasks & Stop) {
            if (m_seekPosition == -1) {
                m_dontCacheNextSeekResult = true;
                m_seekPosition = 0;
                m_position = 0;
                m_pendingTasks |= Seek;
            }
            m_executedTasks ^= Stop;
        }

        ::SetEvent(m_taskHandle);
    }

    updateStatus();
}

void DirectShowPlayerService::doPause(QMutexLocker *locker)
{
    if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) {
        locker->unlock();
        HRESULT hr = control->Pause();
        locker->relock();

        control->Release();

        if (SUCCEEDED(hr)) {
            IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking);
            if (!m_atEnd && seeking) {
                LONGLONG position = 0;

                seeking->GetCurrentPosition(&position);
                seeking->Release();

                m_position = position / qt_directShowTimeScale;
            } else {
                m_position = 0;
                m_atEnd = false;
            }

            m_executedTasks |= Pause;

            QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange)));
        } else {
            m_error = QMediaPlayer::ResourceError;
            m_errorString = QString();
            qWarning("DirectShowPlayerService::doPause: Unresolved error code 0x%x (%s)",
                     uint(hr), qPrintable(comError(hr)));

            QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error)));
        }
    }
}

void DirectShowPlayerService::stop()
{
    QMutexLocker locker(&m_mutex);

    m_pendingTasks &= ~(Play | Pause | Seek);

    if ((m_executingTask | m_executedTasks) & (Play | Pause | Seek)) {
        m_pendingTasks |= Stop;
        if (m_videoProbeControl)
            m_videoProbeControl->flushVideoFrame();

        ::SetEvent(m_taskHandle);

        m_loop->wait(&m_mutex);
    }

    updateStatus();
}

void DirectShowPlayerService::doStop(QMutexLocker *locker)
{
    Q_UNUSED(locker)
    if (m_executedTasks & (Play | Pause)) {
        if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) {
            control->Stop();
            control->Release();
        }

        m_seekPosition = 0;
        m_position = 0;
        m_dontCacheNextSeekResult = true;
        m_pendingTasks |= Seek;

        m_executedTasks &= ~(Play | Pause);

        QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange)));
    }

    m_executedTasks |= Stop;

    m_loop->wake();
}

void DirectShowPlayerService::setRate(qreal rate)
{
    QMutexLocker locker(&m_mutex);

    m_rate = rate;

    m_pendingTasks |= SetRate;

    if (m_executedTasks & FinalizeLoad)
        ::SetEvent(m_taskHandle);
}

void DirectShowPlayerService::doSetRate(QMutexLocker *locker)
{
    if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) {
        // Cache current values as we can't query IMediaSeeking during a seek due to the
        // possibility of a deadlock when flushing the VideoSurfaceFilter.
        LONGLONG currentPosition = 0;
        seeking->GetCurrentPosition(&currentPosition);
        m_position = currentPosition / qt_directShowTimeScale;

        LONGLONG minimum = 0;
        LONGLONG maximum = 0;
        m_playbackRange = SUCCEEDED(seeking->GetAvailable(&minimum, &maximum))
                ? QMediaTimeRange(minimum / qt_directShowTimeScale, maximum / qt_directShowTimeScale)
                : QMediaTimeRange();

        locker->unlock();
        HRESULT hr = seeking->SetRate(m_rate);
        locker->relock();

        if (!SUCCEEDED(hr)) {
            qWarning("%s: Audio device or filter does not support rate: %.2f. " \
                     "Falling back to previous value.", __FUNCTION__, m_rate);

            double rate = 0.0;
            m_rate = SUCCEEDED(seeking->GetRate(&rate))
                    ? rate
                    : 1.0;
        }

        seeking->Release();
    } else if (m_rate != 1.0) {
        m_rate = 1.0;
    }
    QCoreApplication::postEvent(this, new QEvent(QEvent::Type(RateChange)));
}

qint64 DirectShowPlayerService::position() const
{
    QMutexLocker locker(const_cast<QMutex *>(&m_mutex));

    if (m_graphStatus == Loaded) {
        if (m_executingTask == Seek || m_executingTask == SetRate || (m_pendingTasks & Seek))
            return m_position;
        if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) {
            LONGLONG position = 0;

            seeking->GetCurrentPosition(&position);
            seeking->Release();

            const_cast<qint64 &>(m_position) = position / qt_directShowTimeScale;

            return m_position;
        }
    }
    return 0;
}

QMediaTimeRange DirectShowPlayerService::availablePlaybackRanges() const
{
    QMutexLocker locker(const_cast<QMutex *>(&m_mutex));

    if (m_graphStatus == Loaded) {
        if (m_executingTask == Seek || m_executingTask == SetRate || (m_pendingTasks & Seek))
            return m_playbackRange;
        if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) {
            LONGLONG minimum = 0;
            LONGLONG maximum = 0;

            HRESULT hr = seeking->GetAvailable(&minimum, &maximum);
            seeking->Release();

            if (SUCCEEDED(hr))
                return QMediaTimeRange(minimum, maximum);
        }
    }
    return QMediaTimeRange();
}

void DirectShowPlayerService::seek(qint64 position)
{
    QMutexLocker locker(&m_mutex);

    m_seekPosition = position;

    m_pendingTasks |= Seek;

    if (m_executedTasks & FinalizeLoad)
        ::SetEvent(m_taskHandle);
}

void DirectShowPlayerService::doSeek(QMutexLocker *locker)
{
    if (m_seekPosition == -1)
        return;

    if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) {
        LONGLONG seekPosition = LONGLONG(m_seekPosition) * qt_directShowTimeScale;

        // Cache current values as we can't query IMediaSeeking during a seek due to the
        // possibility of a deadlock when flushing the VideoSurfaceFilter.
        LONGLONG currentPosition = 0;
        if (!m_dontCacheNextSeekResult) {
            seeking->GetCurrentPosition(&currentPosition);
            m_position = currentPosition / qt_directShowTimeScale;
        }

        LONGLONG minimum = 0;
        LONGLONG maximum = 0;
        m_playbackRange = SUCCEEDED(seeking->GetAvailable(&minimum, &maximum))
                ? QMediaTimeRange(
                        minimum / qt_directShowTimeScale, maximum / qt_directShowTimeScale)
                : QMediaTimeRange();

        locker->unlock();
        seeking->SetPositions(
                &seekPosition, AM_SEEKING_AbsolutePositioning, nullptr, AM_SEEKING_NoPositioning);
        locker->relock();

        if (!m_dontCacheNextSeekResult) {
            seeking->GetCurrentPosition(&currentPosition);
            m_position = currentPosition / qt_directShowTimeScale;
        }

        seeking->Release();

        QCoreApplication::postEvent(this, new QEvent(QEvent::Type(PositionChange)));
    }

    m_seekPosition = -1;
    m_dontCacheNextSeekResult = false;
}

int DirectShowPlayerService::bufferStatus() const
{
#if QT_CONFIG(wmsdk)
    QMutexLocker locker(const_cast<QMutex *>(&m_mutex));

    if (IWMReaderAdvanced2 *reader = com_cast<IWMReaderAdvanced2>(
            m_source, IID_IWMReaderAdvanced2)) {
        DWORD percentage = 0;

        reader->GetBufferProgress(&percentage, nullptr);
        reader->Release();

        return percentage;
    }
    return 0;
#else
    return 0;
#endif
}

void DirectShowPlayerService::setAudioOutput(IBaseFilter *filter)
{
    QMutexLocker locker(&m_mutex);

    if (m_graph) {
        if (m_audioOutput) {
            if (m_executedTasks & SetAudioOutput) {
                m_pendingTasks |= ReleaseAudioOutput;

                ::SetEvent(m_taskHandle);

                m_loop->wait(&m_mutex);
            }
            m_audioOutput->Release();
        }

        m_audioOutput = filter;

        if (m_audioOutput) {
            m_audioOutput->AddRef();

            m_pendingTasks |= SetAudioOutput;

            if (m_executedTasks & SetSource) {
                m_pendingTasks |= Render;

                ::SetEvent(m_taskHandle);
            }
        } else {
            m_pendingTasks &= ~ SetAudioOutput;
        }
    } else {
        if (m_audioOutput)
            m_audioOutput->Release();

        m_audioOutput = filter;

        if (m_audioOutput)
            m_audioOutput->AddRef();
    }

    m_playerControl->updateAudioOutput(m_audioOutput);
}

void DirectShowPlayerService::doReleaseAudioOutput(QMutexLocker *locker)
{
    Q_UNUSED(locker)
    m_pendingTasks |= m_executedTasks & (Play | Pause);

    if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) {
        control->Stop();
        control->Release();
    }

    IBaseFilter *decoder = getConnected(m_audioOutput, PINDIR_INPUT);
    if (!decoder) {
        decoder = m_audioOutput;
        decoder->AddRef();
    }

    // {DCFBDCF6-0DC2-45f5-9AB2-7C330EA09C29}
    static const GUID iid_IFilterChain = {
        0xDCFBDCF6, 0x0DC2, 0x45f5, {0x9A, 0xB2, 0x7C, 0x33, 0x0E, 0xA0, 0x9C, 0x29} };

    if (IFilterChain *chain = com_cast<IFilterChain>(m_graph, iid_IFilterChain)) {
        chain->RemoveChain(decoder, m_audioOutput);
        chain->Release();
    } else {
        m_graph->RemoveFilter(m_audioOutput);
    }

    decoder->Release();

    m_executedTasks &= ~SetAudioOutput;

    m_loop->wake();
}

void DirectShowPlayerService::setVideoOutput(IBaseFilter *filter)
{
    QMutexLocker locker(&m_mutex);

    if (m_graph) {
        if (m_videoOutput) {
            if (m_executedTasks & SetVideoOutput) {
                m_pendingTasks |= ReleaseVideoOutput;

                ::SetEvent(m_taskHandle);

                m_loop->wait(&m_mutex);
            }
            m_videoOutput->Release();
        }

        m_videoOutput = filter;

        if (m_videoOutput) {
            m_videoOutput->AddRef();

            m_pendingTasks |= SetVideoOutput;

            if (m_executedTasks & SetSource) {
                m_pendingTasks |= Render;

                ::SetEvent(m_taskHandle);
            }
        }
    } else {
        if (m_videoOutput)
            m_videoOutput->Release();

        m_videoOutput = filter;

        if (m_videoOutput)
            m_videoOutput->AddRef();
    }
}

void DirectShowPlayerService::updateAudioProbe()
{
    QMutexLocker locker(&m_mutex);

    // Set/Activate the audio probe.
    if (m_graph) {
        // If we don't have a audio probe, then stop and release the audio sample grabber
        if (!m_audioProbeControl && (m_executedTasks & SetAudioProbe)) {
            m_pendingTasks |= ReleaseAudioProbe;
            ::SetEvent(m_taskHandle);
            m_loop->wait(&m_mutex);
        } else if (m_audioProbeControl) {
            m_pendingTasks |= SetAudioProbe;
        }
    }
}

void DirectShowPlayerService::updateVideoProbe()
{
    QMutexLocker locker(&m_mutex);

    // Set/Activate the video probe.
    if (m_graph) {
        // If we don't have a video probe, then stop and release the video sample grabber
        if (!m_videoProbeControl && (m_executedTasks & SetVideoProbe)) {
            m_pendingTasks |= ReleaseVideoProbe;
            ::SetEvent(m_taskHandle);
            m_loop->wait(&m_mutex);
        } else if (m_videoProbeControl){
            m_pendingTasks |= SetVideoProbe;
        }
    }
}

void DirectShowPlayerService::doReleaseVideoOutput(QMutexLocker *locker)
{
    Q_UNUSED(locker)
    m_pendingTasks |= m_executedTasks & (Play | Pause);

    if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) {
        control->Stop();
        control->Release();
    }

    IBaseFilter *intermediate = nullptr;
    if (!SUCCEEDED(m_graph->FindFilterByName(L"Color Space Converter", &intermediate))) {
        intermediate = m_videoOutput;
        intermediate->AddRef();
    }

    IBaseFilter *decoder = getConnected(intermediate, PINDIR_INPUT);
    if (!decoder) {
        decoder = intermediate;
        decoder->AddRef();
    }

    // {DCFBDCF6-0DC2-45f5-9AB2-7C330EA09C29}
    static const GUID iid_IFilterChain = {
        0xDCFBDCF6, 0x0DC2, 0x45f5, {0x9A, 0xB2, 0x7C, 0x33, 0x0E, 0xA0, 0x9C, 0x29} };

    if (IFilterChain *chain = com_cast<IFilterChain>(m_graph, iid_IFilterChain)) {
        chain->RemoveChain(decoder, m_videoOutput);
        chain->Release();
    } else {
        m_graph->RemoveFilter(m_videoOutput);
    }

    intermediate->Release();
    decoder->Release();

    m_executedTasks &= ~SetVideoOutput;

    m_loop->wake();
}

void DirectShowPlayerService::customEvent(QEvent *event)
{
    if (event->type() == QEvent::Type(FinalizedLoad)) {
        QMutexLocker locker(&m_mutex);

        m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable);
        if (m_metadata.isEmpty())
            DirectShowMetaDataControl::updateMetadata(m_graph, m_source, m_metadata);

        m_metaDataControl->setMetadata(m_metadata);
        m_metadata.clear();

        updateStatus();
    } else if (event->type() == QEvent::Type(Error)) {
        QMutexLocker locker(&m_mutex);

        if (m_error != QMediaPlayer::NoError) {
            m_playerControl->updateError(m_error, m_errorString);
            m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable);
            m_playerControl->updateState(QMediaPlayer::StoppedState);
            updateStatus();
        }
    } else if (event->type() == QEvent::Type(RateChange)) {
        QMutexLocker locker(&m_mutex);

        m_playerControl->updatePlaybackRate(m_rate);
    } else if (event->type() == QEvent::Type(StatusChange)) {
        QMutexLocker locker(&m_mutex);

        updateStatus();
        m_playerControl->updatePosition(m_position);
    } else if (event->type() == QEvent::Type(DurationChange)) {
        QMutexLocker locker(&m_mutex);

        m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable);
    } else if (event->type() == QEvent::Type(EndOfMedia)) {
        QMutexLocker locker(&m_mutex);

        if (m_atEnd) {
            m_playerControl->updateState(QMediaPlayer::StoppedState);
            m_playerControl->updateStatus(QMediaPlayer::EndOfMedia);
            m_playerControl->updatePosition(m_position);
            if (m_videoProbeControl)
                m_videoProbeControl->flushVideoFrame();
        }
    } else if (event->type() == QEvent::Type(PositionChange)) {
        QMutexLocker locker(&m_mutex);

        if (m_playerControl->mediaStatus() == QMediaPlayer::EndOfMedia)
            m_playerControl->updateStatus(QMediaPlayer::LoadedMedia);
        m_playerControl->updatePosition(m_position);
        // Emits only when seek has been performed.
        if (m_videoRendererControl)
            emit m_videoRendererControl->positionChanged(m_position);
    } else {
        QMediaService::customEvent(event);
    }
}

void DirectShowPlayerService::videoOutputChanged()
{
    setVideoOutput(m_videoRendererControl->filter());
}

QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wmissing-field-initializers")

void DirectShowPlayerService::onAudioBufferAvailable(double time, const QByteArray &data)
{
    QMutexLocker locker(&m_mutex);
    if (!m_audioProbeControl || !m_audioSampleGrabber)
        return;

    DirectShowMediaType mt(AM_MEDIA_TYPE { GUID_NULL });
    const bool ok = m_audioSampleGrabber->getConnectedMediaType(&mt);
    if (!ok)
        return;

    if (mt->majortype != MEDIATYPE_Audio)
        return;

    if (mt->subtype != MEDIASUBTYPE_PCM)
        return;

    const bool isWfx = ((mt->formattype == FORMAT_WaveFormatEx) && (mt->cbFormat >= sizeof(WAVEFORMATEX)));
    WAVEFORMATEX *wfx = isWfx ? reinterpret_cast<WAVEFORMATEX *>(mt->pbFormat) : nullptr;

    if (!wfx)
        return;

    if (wfx->wFormatTag != WAVE_FORMAT_PCM && wfx->wFormatTag != WAVE_FORMAT_EXTENSIBLE)
        return;

    if ((wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) && (wfx->cbSize >= sizeof(WAVEFORMATEXTENSIBLE))) {
        WAVEFORMATEXTENSIBLE *wfxe = reinterpret_cast<WAVEFORMATEXTENSIBLE *>(wfx);
        if (wfxe->SubFormat != KSDATAFORMAT_SUBTYPE_PCM)
            return;
    }

    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);

    const quint64 startTime = quint64(time * 1000.);
    QAudioBuffer audioBuffer(data,
                             format,
                             startTime);

    Q_EMIT m_audioProbeControl->audioBufferProbed(audioBuffer);
}

void DirectShowPlayerService::onVideoBufferAvailable(double time, const QByteArray &data)
{
    Q_UNUSED(time);

    QMutexLocker locker(&m_mutex);
    if (!m_videoProbeControl || !m_videoSampleGrabber)
        return;

    DirectShowMediaType mt(AM_MEDIA_TYPE { GUID_NULL });
    const bool ok = m_videoSampleGrabber->getConnectedMediaType(&mt);
    if (!ok)
        return;

    if (mt->majortype != MEDIATYPE_Video)
        return;

    QVideoFrame::PixelFormat format = DirectShowMediaType::pixelFormatFromType(&mt);
    if (format == QVideoFrame::Format_Invalid) {
        qCWarning(qtDirectShowPlugin, "Invalid format, stopping video probes!");
        m_videoSampleGrabber->stop();
        return;
    }

    const QVideoSurfaceFormat &videoFormat = DirectShowMediaType::videoFormatFromType(&mt);
    if (!videoFormat.isValid())
        return;

    const QSize &size = videoFormat.frameSize();

    const int bytesPerLine = DirectShowMediaType::bytesPerLine(videoFormat);
    QVideoFrame frame(new QMemoryVideoBuffer(data, bytesPerLine),
                      size,
                      format);

    m_videoProbeControl->probeVideoFrame(frame);
}

QT_WARNING_POP

void DirectShowPlayerService::graphEvent(QMutexLocker *locker)
{
    Q_UNUSED(locker)
    if (IMediaEvent *event = com_cast<IMediaEvent>(m_graph, IID_IMediaEvent)) {
        long eventCode;
        LONG_PTR param1;
        LONG_PTR param2;

        while (event->GetEvent(&eventCode, &param1, &param2, 0) == S_OK) {
            switch (eventCode) {
            case EC_BUFFERING_DATA:
                m_buffering = param1;

                QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange)));
                break;
            case EC_COMPLETE:
                m_executedTasks &= ~(Play | Pause);
                m_executedTasks |= Stop;

                m_buffering = false;
                m_atEnd = true;

                if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) {
                    LONGLONG position = 0;

                    seeking->GetCurrentPosition(&position);
                    seeking->Release();

                    m_position = position / qt_directShowTimeScale;
                }

                QCoreApplication::postEvent(this, new QEvent(QEvent::Type(EndOfMedia)));
                break;
            case EC_LENGTH_CHANGED:
                if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) {
                    LONGLONG duration = 0;
                    seeking->GetDuration(&duration);
                    m_duration = duration / qt_directShowTimeScale;

                    DWORD capabilities = 0;
                    seeking->GetCapabilities(&capabilities);
                    m_seekable = capabilities & AM_SEEKING_CanSeekAbsolute;

                    seeking->Release();

                    QCoreApplication::postEvent(this, new QEvent(QEvent::Type(DurationChange)));
                }
                break;
            default:
                break;
            }

            event->FreeEventParams(eventCode, param1, param2);
        }
        event->Release();
    }
}

void DirectShowPlayerService::updateStatus()
{
    switch (m_graphStatus) {
    case NoMedia:
        m_playerControl->updateStatus(QMediaPlayer::NoMedia);
        break;
    case Loading:
        m_playerControl->updateStatus(QMediaPlayer::LoadingMedia);
        break;
    case Loaded:
        if ((m_executingTask | m_executedTasks) & (Play | Pause)) {
            if (m_buffering)
                m_playerControl->updateStatus(QMediaPlayer::BufferingMedia);
            else
                m_playerControl->updateStatus(QMediaPlayer::BufferedMedia);
        } else {
            m_playerControl->updateStatus(QMediaPlayer::LoadedMedia);
        }
        break;
    case InvalidMedia:
        m_playerControl->updateStatus(QMediaPlayer::InvalidMedia);
        break;
    default:
        m_playerControl->updateStatus(QMediaPlayer::UnknownMediaStatus);
    }
}

bool DirectShowPlayerService::isConnected(IBaseFilter *filter, PIN_DIRECTION direction) const
{
    bool connected = false;

    IEnumPins *pins = nullptr;

    if (SUCCEEDED(filter->EnumPins(&pins))) {
        for (IPin *pin = nullptr; pins->Next(1, &pin, nullptr) == S_OK; pin->Release()) {
            PIN_DIRECTION dir;
            if (SUCCEEDED(pin->QueryDirection(&dir)) && dir == direction) {
                IPin *peer = nullptr;
                if (SUCCEEDED(pin->ConnectedTo(&peer))) {
                    connected = true;

                    peer->Release();
                }
            }
        }
        pins->Release();
    }
    return connected;
}

IBaseFilter *DirectShowPlayerService::getConnected(
        IBaseFilter *filter, PIN_DIRECTION direction) const
{
    IBaseFilter *connected = nullptr;

    IEnumPins *pins = nullptr;

    if (SUCCEEDED(filter->EnumPins(&pins))) {
        for (IPin *pin = nullptr; pins->Next(1, &pin, nullptr) == S_OK; pin->Release()) {
            PIN_DIRECTION dir;
            if (SUCCEEDED(pin->QueryDirection(&dir)) && dir == direction) {
                IPin *peer = nullptr;
                if (SUCCEEDED(pin->ConnectedTo(&peer))) {
                    PIN_INFO info;

                    if (SUCCEEDED(peer->QueryPinInfo(&info))) {
                        if (connected) {
                            qWarning("DirectShowPlayerService::getConnected: "
                                "Multiple connected filters");
                            connected->Release();
                        }
                        connected = info.pFilter;
                    }
                    peer->Release();
                }
            }
        }
        pins->Release();
    }
    return connected;
}

void DirectShowPlayerService::run()
{
    QMutexLocker locker(&m_mutex);

    for (;;) {
        while (m_pendingTasks == 0) {
            DWORD result = 0;

            locker.unlock();
            if (m_eventHandle) {
                HANDLE handles[] = { m_taskHandle, m_eventHandle };

                result = ::WaitForMultipleObjects(2, handles, false, INFINITE);
            } else {
                result = ::WaitForSingleObject(m_taskHandle, INFINITE);
            }
            locker.relock();

            if (result == WAIT_OBJECT_0 + 1) {
                graphEvent(&locker);
            }
        }

        if (m_pendingTasks & ReleaseGraph) {
            m_pendingTasks ^= ReleaseGraph;
            m_executingTask = ReleaseGraph;

            doReleaseGraph(&locker);
            //if the graph is released, we should not process other operations later
            if (m_pendingTasks & Shutdown) {
                m_pendingTasks = 0;
                return;
            }
            m_pendingTasks = 0;
        } else if (m_pendingTasks & Shutdown) {
            return;
        } else if (m_pendingTasks & ReleaseAudioOutput) {
            m_pendingTasks ^= ReleaseAudioOutput;
            m_executingTask = ReleaseAudioOutput;

            doReleaseAudioOutput(&locker);
        } else if (m_pendingTasks & ReleaseVideoOutput) {
            m_pendingTasks ^= ReleaseVideoOutput;
            m_executingTask = ReleaseVideoOutput;

            doReleaseVideoOutput(&locker);
        } else if (m_pendingTasks & ReleaseAudioProbe) {
            m_pendingTasks ^= ReleaseAudioProbe;
            m_executingTask = ReleaseAudioProbe;

            doReleaseAudioProbe(&locker);
        } else if (m_pendingTasks & ReleaseVideoProbe) {
            m_pendingTasks ^= ReleaseVideoProbe;
            m_executingTask = ReleaseVideoProbe;

            doReleaseVideoProbe(&locker);
        } else if (m_pendingTasks & SetUrlSource) {
            m_pendingTasks ^= SetUrlSource;
            m_executingTask = SetUrlSource;

            doSetUrlSource(&locker);
        } else if (m_pendingTasks & SetStreamSource) {
            m_pendingTasks ^= SetStreamSource;
            m_executingTask = SetStreamSource;

            doSetStreamSource(&locker);
        } else if (m_pendingTasks & SetAudioProbe) {
            m_pendingTasks ^= SetAudioProbe;
            m_executingTask = SetAudioProbe;

            doSetAudioProbe(&locker);
        } else if (m_pendingTasks & SetVideoProbe) {
            m_pendingTasks ^= SetVideoProbe;
            m_executingTask = SetVideoProbe;

            doSetVideoProbe(&locker);
        } else if (m_pendingTasks & Render) {
            m_pendingTasks ^= Render;
            m_executingTask = Render;

            doRender(&locker);
        } else if (!(m_executedTasks & Render)) {
            m_pendingTasks &= ~(FinalizeLoad | SetRate | Stop | Pause | Seek | Play);
        } else if (m_pendingTasks & FinalizeLoad) {
            m_pendingTasks ^= FinalizeLoad;
            m_executingTask = FinalizeLoad;

            doFinalizeLoad(&locker);
        } else if (m_pendingTasks & Stop) {
            m_pendingTasks ^= Stop;
            m_executingTask = Stop;

            doStop(&locker);
        } else if (m_pendingTasks & SetRate) {
            m_pendingTasks ^= SetRate;
            m_executingTask = SetRate;

            doSetRate(&locker);
        } else if (m_pendingTasks & Pause) {
            m_pendingTasks ^= Pause;
            m_executingTask = Pause;

            doPause(&locker);
        } else if (m_pendingTasks & Seek) {
            m_pendingTasks ^= Seek;
            m_executingTask = Seek;

            doSeek(&locker);
        } else if (m_pendingTasks & Play) {
            m_pendingTasks ^= Play;
            m_executingTask = Play;

            doPlay(&locker);
        }
        m_executingTask = 0;
    }
}

QT_END_NAMESPACE
