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

#include "directshoweventloop.h"
#include "directshowglobal.h"
#include "directshowvideobuffer.h"

#include <QtCore/qthread.h>
#include <QtCore/qloggingcategory.h>
#include <qabstractvideosurface.h>

#include <mutex>

#include <initguid.h>

QT_BEGIN_NAMESPACE

Q_LOGGING_CATEGORY(qLcRenderFilter, "qt.multimedia.plugins.directshow.renderfilter")

// { e23cad72-153d-406c-bf3f-4c4b523d96f2 }
DEFINE_GUID(CLSID_VideoSurfaceFilter,
0xe23cad72, 0x153d, 0x406c, 0xbf, 0x3f, 0x4c, 0x4b, 0x52, 0x3d, 0x96, 0xf2);

class VideoSurfaceInputPin : public DirectShowInputPin
{
    COM_REF_MIXIN
public:
    VideoSurfaceInputPin(VideoSurfaceFilter *filter);

    STDMETHODIMP QueryInterface(REFIID riid, void **ppv) override;

    bool isMediaTypeSupported(const AM_MEDIA_TYPE *type) override;
    bool setMediaType(const AM_MEDIA_TYPE *type) override;

    HRESULT completeConnection(IPin *pin) override;
    HRESULT connectionEnded() override;

    // IPin
    STDMETHODIMP ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) override;
    STDMETHODIMP Disconnect() override;
    STDMETHODIMP EndOfStream() override;
    STDMETHODIMP BeginFlush() override;
    STDMETHODIMP EndFlush() override;

    // IMemInputPin
    STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps) override;
    STDMETHODIMP Receive(IMediaSample *pMediaSample) override;

private:
    VideoSurfaceFilter *m_videoSurfaceFilter;
};

VideoSurfaceInputPin::VideoSurfaceInputPin(VideoSurfaceFilter *filter)
    : DirectShowInputPin(filter, QStringLiteral("Input"))
    , m_videoSurfaceFilter(filter)
{
}

HRESULT VideoSurfaceInputPin::QueryInterface(REFIID riid, void **ppv)
{
    if (ppv == nullptr)
        return E_POINTER;
    if (riid == IID_IUnknown)
        *ppv = static_cast<IUnknown *>(static_cast<DirectShowPin *>(this));
    else if (riid == IID_IPin)
        *ppv = static_cast<IPin *>(this);
    else if (riid == IID_IMemInputPin)
        *ppv =static_cast<IMemInputPin*>(this);
    else
        return E_NOINTERFACE;
    AddRef();
    return S_OK;
}

bool VideoSurfaceInputPin::isMediaTypeSupported(const AM_MEDIA_TYPE *type)
{
    return m_videoSurfaceFilter->isMediaTypeSupported(type);
}

bool VideoSurfaceInputPin::setMediaType(const AM_MEDIA_TYPE *type)
{
    if (!DirectShowInputPin::setMediaType(type))
        return false;

    return m_videoSurfaceFilter->setMediaType(type);
}

HRESULT VideoSurfaceInputPin::completeConnection(IPin *pin)
{
    HRESULT hr = DirectShowInputPin::completeConnection(pin);
    if (FAILED(hr))
        return hr;

    return m_videoSurfaceFilter->completeConnection(pin);
}

HRESULT VideoSurfaceInputPin::connectionEnded()
{
    HRESULT hr = DirectShowInputPin::connectionEnded();
    if (FAILED(hr))
        return hr;

    return m_videoSurfaceFilter->connectionEnded();
}

HRESULT VideoSurfaceInputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)
{
    QMutexLocker lock(&m_videoSurfaceFilter->m_mutex);
    return DirectShowInputPin::ReceiveConnection(pConnector, pmt);
}

HRESULT VideoSurfaceInputPin::Disconnect()
{
    QMutexLocker lock(&m_videoSurfaceFilter->m_mutex);
    return DirectShowInputPin::Disconnect();
}

HRESULT VideoSurfaceInputPin::EndOfStream()
{
    QMutexLocker lock(&m_videoSurfaceFilter->m_mutex);
    const std::lock_guard<QRecursiveMutex> renderLocker(m_videoSurfaceFilter->m_renderMutex);

    HRESULT hr = DirectShowInputPin::EndOfStream();
    if (hr != S_OK)
        return hr;

    return m_videoSurfaceFilter->EndOfStream();
}

HRESULT VideoSurfaceInputPin::BeginFlush()
{
    QMutexLocker lock(&m_videoSurfaceFilter->m_mutex);
    {
        const std::lock_guard<QRecursiveMutex> renderLocker(m_videoSurfaceFilter->m_renderMutex);
        DirectShowInputPin::BeginFlush();
        m_videoSurfaceFilter->BeginFlush();
    }
    m_videoSurfaceFilter->resetEOS();

    return S_OK;
}

HRESULT VideoSurfaceInputPin::EndFlush()
{
    QMutexLocker lock(&m_videoSurfaceFilter->m_mutex);
    const std::lock_guard<QRecursiveMutex> renderLocker(m_videoSurfaceFilter->m_renderMutex);

    HRESULT hr = m_videoSurfaceFilter->EndFlush();
    if (SUCCEEDED(hr))
        hr = DirectShowInputPin::EndFlush();
    return hr;
}

HRESULT VideoSurfaceInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps)
{
    if (!pProps)
        return E_POINTER;

    // We need at least two allocated buffers, one for holding the frame currently being
    // rendered and another one to decode the following frame at the same time.
    pProps->cBuffers = 2;

    return S_OK;
}

HRESULT VideoSurfaceInputPin::Receive(IMediaSample *pMediaSample)
{
    HRESULT hr = m_videoSurfaceFilter->Receive(pMediaSample);
    if (FAILED(hr)) {
        QMutexLocker locker(&m_videoSurfaceFilter->m_mutex);
        if (m_videoSurfaceFilter->state() != State_Stopped && !m_flushing && !m_inErrorState) {
            m_videoSurfaceFilter->NotifyEvent(EC_ERRORABORT, hr, 0);
            {
                const std::lock_guard<QRecursiveMutex> renderLocker(m_videoSurfaceFilter->m_renderMutex);
                if (m_videoSurfaceFilter->m_running && !m_videoSurfaceFilter->m_EOSDelivered)
                    m_videoSurfaceFilter->notifyEOS();
            }
            m_inErrorState = true;
        }
    }

    return hr;
}


VideoSurfaceFilter::VideoSurfaceFilter(QAbstractVideoSurface *surface, DirectShowEventLoop *loop, QObject *parent)
    : QObject(parent)
    , m_loop(loop)
    , m_surface(surface)
    , m_renderEvent(CreateEvent(nullptr, FALSE, FALSE, nullptr))
    , m_flushEvent(CreateEvent(nullptr, TRUE, FALSE, nullptr))
{
    supportedFormatsChanged();
    connect(surface, &QAbstractVideoSurface::supportedFormatsChanged,
            this, &VideoSurfaceFilter::supportedFormatsChanged);
}

VideoSurfaceFilter::~VideoSurfaceFilter()
{
    clearPendingSample();

    if (m_pin)
        m_pin->Release();

    CloseHandle(m_flushEvent);
    CloseHandle(m_renderEvent);
}

HRESULT VideoSurfaceFilter::QueryInterface(REFIID riid, void **ppv)
{
    if (ppv == nullptr)
        return E_POINTER;
    if (riid == IID_IUnknown)
        *ppv = static_cast<IUnknown *>(static_cast<DirectShowBaseFilter *>(this));
    else if (riid == IID_IPersist || riid == IID_IMediaFilter || riid == IID_IBaseFilter)
        *ppv = static_cast<IBaseFilter *>(this);
    else if (riid == IID_IAMFilterMiscFlags)
        *ppv = static_cast<IAMFilterMiscFlags *>(this);
    else
        return E_NOINTERFACE;
    AddRef();
    return S_OK;
}

QList<DirectShowPin *> VideoSurfaceFilter::pins()
{
    if (!m_pin)
        m_pin = new VideoSurfaceInputPin(this);

    return QList<DirectShowPin *>() << m_pin;
}

HRESULT VideoSurfaceFilter::GetClassID(CLSID *pClassID)
{
    *pClassID = CLSID_VideoSurfaceFilter;
    return S_OK;
}

ULONG VideoSurfaceFilter::GetMiscFlags()
{
    return AM_FILTER_MISC_FLAGS_IS_RENDERER;
}

void VideoSurfaceFilter::supportedFormatsChanged()
{
    QWriteLocker writeLocker(&m_typesLock);

    qCDebug(qLcRenderFilter, "supportedFormatChanged");

    m_supportedTypes.clear();

    const QList<QVideoFrame::PixelFormat> formats = m_surface->supportedPixelFormats();
    m_supportedTypes.reserve(formats.count());

    for (QVideoFrame::PixelFormat format : formats) {
        GUID subtype = DirectShowMediaType::convertPixelFormat(format);
        if (!IsEqualGUID(subtype, MEDIASUBTYPE_None)) {
            qCDebug(qLcRenderFilter) << "  " << format;
            m_supportedTypes.append(subtype);
        }
    }
}

bool VideoSurfaceFilter::isMediaTypeSupported(const AM_MEDIA_TYPE *type)
{
    if (type->majortype != MEDIATYPE_Video || type->bFixedSizeSamples == FALSE)
        return false;

    QReadLocker readLocker(&m_typesLock);

    for (const GUID &supportedType : m_supportedTypes) {
        if (IsEqualGUID(supportedType, type->subtype))
            return true;
    }

    return false;
}

bool VideoSurfaceFilter::setMediaType(const AM_MEDIA_TYPE *type)
{
    if (!type) {
        qCDebug(qLcRenderFilter, "clear media type");
        m_surfaceFormat = QVideoSurfaceFormat();
        m_bytesPerLine = 0;
        return true;
    }
    m_surfaceFormat = DirectShowMediaType::videoFormatFromType(type);
    m_bytesPerLine = DirectShowMediaType::bytesPerLine(m_surfaceFormat);
    qCDebug(qLcRenderFilter) << "setMediaType -->" << m_surfaceFormat;
    return m_surfaceFormat.isValid();
}

HRESULT VideoSurfaceFilter::completeConnection(IPin *pin)
{
    Q_UNUSED(pin);

    qCDebug(qLcRenderFilter, "completeConnection");

    return startSurface() ? S_OK : VFW_E_TYPE_NOT_ACCEPTED;
}

HRESULT VideoSurfaceFilter::connectionEnded()
{
    qCDebug(qLcRenderFilter, "connectionEnded");

    stopSurface();

    return S_OK;
}

HRESULT VideoSurfaceFilter::Run(REFERENCE_TIME tStart)
{
    QMutexLocker locker(&m_mutex);

    if (m_state == State_Running)
        return S_OK;

    qCDebug(qLcRenderFilter, "Run (start=%lli)", tStart);

    HRESULT hr = DirectShowBaseFilter::Run(tStart);
    if (FAILED(hr))
        return hr;

    ResetEvent(m_flushEvent);

    IMemAllocator *allocator;
    if (SUCCEEDED(m_pin->GetAllocator(&allocator))) {
        allocator->Commit();
        allocator->Release();
    }

    const std::lock_guard<QRecursiveMutex> renderLocker(m_renderMutex);

    m_running = true;

    if (!m_pendingSample)
        checkEOS();
    else if (!scheduleSample(m_pendingSample))
        SetEvent(m_renderEvent); // render immediately

    return S_OK;
}

HRESULT VideoSurfaceFilter::Pause()
{
    QMutexLocker locker(&m_mutex);

    if (m_state == State_Paused)
        return S_OK;

    qCDebug(qLcRenderFilter, "Pause");

    HRESULT hr = DirectShowBaseFilter::Pause();
    if (FAILED(hr))
        return hr;

    m_renderMutex.lock();
    m_EOSDelivered = false;
    m_running = false;
    m_renderMutex.unlock();

    resetEOSTimer();
    ResetEvent(m_flushEvent);
    unscheduleSample();

    IMemAllocator *allocator;
    if (SUCCEEDED(m_pin->GetAllocator(&allocator))) {
        allocator->Commit();
        allocator->Release();
    }

    return S_OK;
}

HRESULT VideoSurfaceFilter::Stop()
{
    QMutexLocker locker(&m_mutex);

    if (m_state == State_Stopped)
        return S_OK;

    qCDebug(qLcRenderFilter, "Stop");

    DirectShowBaseFilter::Stop();

    clearPendingSample();

    m_renderMutex.lock();
    m_EOSDelivered = false;
    m_running = false;
    m_renderMutex.unlock();

    SetEvent(m_flushEvent);
    resetEOS();
    unscheduleSample();
    flushSurface();

    IMemAllocator *allocator;
    if (SUCCEEDED(m_pin->GetAllocator(&allocator))) {
        allocator->Decommit();
        allocator->Release();
    }

    return S_OK;
}

HRESULT VideoSurfaceFilter::EndOfStream()
{
    const std::lock_guard<QRecursiveMutex> renderLocker(m_renderMutex);

    qCDebug(qLcRenderFilter, "EndOfStream");

    m_EOS = true;

    if (!m_pendingSample && m_running)
        checkEOS();

    stopSurface();
    return S_OK;
}

HRESULT VideoSurfaceFilter::BeginFlush()
{
    qCDebug(qLcRenderFilter, "BeginFlush");

    SetEvent(m_flushEvent);
    unscheduleSample();
    clearPendingSample();

    return S_OK;
}

HRESULT VideoSurfaceFilter::EndFlush()
{
    qCDebug(qLcRenderFilter, "EndFlush");

    ResetEvent(m_flushEvent);
    return S_OK;
}

HRESULT VideoSurfaceFilter::Receive(IMediaSample *pMediaSample)
{
    {
        QMutexLocker locker(&m_mutex);

        qCDebug(qLcRenderFilter, "Receive (sample=%p)", pMediaSample);

        HRESULT hr = m_pin->DirectShowInputPin::Receive(pMediaSample);
        if (hr != S_OK) {
            qCDebug(qLcRenderFilter, "  can't receive sample (error %X)", uint(hr));
            return E_FAIL;
        }

        // If the format dynamically changed, the sample contains information about the new format.
        // We need to reset the format and restart the QAbstractVideoSurface.
        if (m_pin->currentSampleProperties()->pMediaType
                && (!m_pin->setMediaType(m_pin->currentSampleProperties()->pMediaType)
                    || !restartSurface())) {
                qCWarning(qLcRenderFilter, "  dynamic format change failed, aborting rendering");
                NotifyEvent(EC_ERRORABORT, VFW_E_TYPE_NOT_ACCEPTED, 0);
                return VFW_E_INVALIDMEDIATYPE;
        }

        {
            const std::lock_guard<QRecursiveMutex> locker(m_renderMutex);

            if (m_pendingSample || m_EOS)
                return E_UNEXPECTED;

            if (m_running && !scheduleSample(pMediaSample)) {
                qCWarning(qLcRenderFilter, "  sample can't be scheduled, discarding it");
                return S_OK;
            }

            m_pendingSample = pMediaSample;
            m_pendingSample->AddRef();
            m_pendingSampleEndTime = m_pin->currentSampleProperties()->tStop;
        }

        if (m_state == State_Paused) // Render immediately
            renderPendingSample();
    }

    qCDebug(qLcRenderFilter, "  waiting for render time");

    // Wait for render time. The clock will wake us up whenever the time comes.
    // It can also be interrupted by a flush, pause or stop.
    HANDLE waitObjects[] = { m_flushEvent, m_renderEvent };
    DWORD result = WAIT_TIMEOUT;
    while (result == WAIT_TIMEOUT)
        result = WaitForMultipleObjects(2, waitObjects, FALSE, INFINITE);

    if (result == WAIT_OBJECT_0) {
        // render interrupted (flush, pause, stop)
        qCDebug(qLcRenderFilter, " rendering of sample %p interrupted", pMediaSample);
        return S_OK;
    }

    m_adviseCookie = 0;

    QMutexLocker locker(&m_mutex);

    // State might have changed just before the lock
    if (m_state == State_Stopped) {
        qCDebug(qLcRenderFilter, "  state changed to Stopped, discarding sample (%p)", pMediaSample);
        return S_OK;
    }

    std::unique_lock<QRecursiveMutex> renderLocker(m_renderMutex);

    // Flush or pause might have happened just before the lock
    if (m_pendingSample && m_running) {
        renderLocker.unlock();
        renderPendingSample();
        renderLocker.lock();
    } else {
        qCDebug(qLcRenderFilter, "  discarding sample (%p)", pMediaSample);
    }

    clearPendingSample();
    checkEOS();
    ResetEvent(m_renderEvent);

    return S_OK;
}

bool VideoSurfaceFilter::scheduleSample(IMediaSample *sample)
{
    if (!sample)
        return false;

    qCDebug(qLcRenderFilter, "scheduleSample (sample=%p)", sample);

    REFERENCE_TIME sampleStart, sampleEnd;
    if (FAILED(sample->GetTime(&sampleStart, &sampleEnd)) || !m_clock) {
        qCDebug(qLcRenderFilter, "  render now");
        SetEvent(m_renderEvent); // Render immediately
        return true;
    }

    if (sampleEnd < sampleStart) { // incorrect times
        qCWarning(qLcRenderFilter, "  invalid sample times (start=%lli, end=%lli)", sampleStart, sampleEnd);
        return false;
    }

    HRESULT hr = m_clock->AdviseTime(m_startTime, sampleStart, (HEVENT)m_renderEvent, &m_adviseCookie);
    if (FAILED(hr)) {
        qCWarning(qLcRenderFilter, "  clock failed to advise time (error=%X)", uint(hr));
        return false;
    }

    return true;
}

void VideoSurfaceFilter::unscheduleSample()
{
    if (m_adviseCookie) {
        qCDebug(qLcRenderFilter, "unscheduleSample");
        m_clock->Unadvise(m_adviseCookie);
        m_adviseCookie = 0;
    }

    ResetEvent(m_renderEvent);
}

void VideoSurfaceFilter::clearPendingSample()
{
    const std::lock_guard<QRecursiveMutex> locker(m_renderMutex);
    if (m_pendingSample) {
        qCDebug(qLcRenderFilter, "clearPendingSample");
        m_pendingSample->Release();
        m_pendingSample = nullptr;
    }
}

void QT_WIN_CALLBACK EOSTimerCallback(UINT, UINT, DWORD_PTR dwUser, DWORD_PTR, DWORD_PTR)
{
    VideoSurfaceFilter *that = reinterpret_cast<VideoSurfaceFilter *>(dwUser);
    that->onEOSTimerTimeout();
}

void VideoSurfaceFilter::onEOSTimerTimeout()
{
    const std::lock_guard<QRecursiveMutex> locker(m_renderMutex);

    if (m_EOSTimer) {
        m_EOSTimer = 0;
        checkEOS();
    }
}

void VideoSurfaceFilter::checkEOS()
{
    const std::lock_guard<QRecursiveMutex> locker(m_renderMutex);

    if (!m_EOS || m_EOSDelivered || m_EOSTimer)
        return;

    if (!m_clock) {
        notifyEOS();
        return;
    }

    REFERENCE_TIME eosTime = m_startTime + m_pendingSampleEndTime;
    REFERENCE_TIME currentTime;
    m_clock->GetTime(&currentTime);
    LONG delay = LONG((eosTime - currentTime) / 10000);

    if (delay < 1) {
        notifyEOS();
    } else {
        qCDebug(qLcRenderFilter, "will trigger EOS in %li", delay);

        m_EOSTimer = timeSetEvent(delay,
                                  1,
                                  EOSTimerCallback,
                                  reinterpret_cast<DWORD_PTR>(this),
                                  TIME_ONESHOT | TIME_CALLBACK_FUNCTION | TIME_KILL_SYNCHRONOUS);

        if (!m_EOSTimer) {
            qDebug("Error with timer");
            notifyEOS();
        }
    }
}

void VideoSurfaceFilter::notifyEOS()
{
    const std::lock_guard<QRecursiveMutex> locker(m_renderMutex);

    if (!m_running)
        return;

    qCDebug(qLcRenderFilter, "notifyEOS, delivering EC_COMPLETE event");

    m_EOSTimer = 0;
    m_EOSDelivered = true;
    NotifyEvent(EC_COMPLETE, S_OK, (LONG_PTR)(IBaseFilter *)this);
}

void VideoSurfaceFilter::resetEOS()
{
    resetEOSTimer();

    const std::lock_guard<QRecursiveMutex> locker(m_renderMutex);

    if (m_EOS)
        qCDebug(qLcRenderFilter, "resetEOS (delivered=%s)", m_EOSDelivered ? "true" : "false");

    m_EOS = false;
    m_EOSDelivered = false;
    m_pendingSampleEndTime = 0;
}

void VideoSurfaceFilter::resetEOSTimer()
{
    if (m_EOSTimer) {
        timeKillEvent(m_EOSTimer);
        m_EOSTimer = 0;
    }
}

bool VideoSurfaceFilter::startSurface()
{
    if (QThread::currentThread() != thread()) {
        m_loop->postEvent(this, new QEvent(QEvent::Type(StartSurface)));
        m_waitSurface.wait(&m_mutex);
        return m_surfaceStarted;
    }
    m_surfaceStarted = m_surface->start(m_surfaceFormat);
    qCDebug(qLcRenderFilter, "startSurface %s", m_surfaceStarted ? "succeeded" : "failed");
    return m_surfaceStarted;
}

void VideoSurfaceFilter::stopSurface()
{
    if (!m_surfaceStarted)
        return;

    if (QThread::currentThread() != thread()) {
        m_loop->postEvent(this, new QEvent(QEvent::Type(StopSurface)));
        m_waitSurface.wait(&m_mutex);
    } else {
        qCDebug(qLcRenderFilter, "stopSurface");
        m_surface->stop();
        m_surfaceStarted = false;
    }
}

bool VideoSurfaceFilter::restartSurface()
{
    if (QThread::currentThread() != thread()) {
        m_loop->postEvent(this, new QEvent(QEvent::Type(RestartSurface)));
        m_waitSurface.wait(&m_mutex);
        return m_surfaceStarted;
    }
    m_surface->stop();
    m_surfaceStarted = m_surface->start(m_surfaceFormat);
    qCDebug(qLcRenderFilter, "restartSurface %s", m_surfaceStarted ? "succeeded" : "failed");
    return m_surfaceStarted;
}

void VideoSurfaceFilter::flushSurface()
{
    if (QThread::currentThread() != thread()) {
        m_loop->postEvent(this, new QEvent(QEvent::Type(FlushSurface)));
        m_waitSurface.wait(&m_mutex);
    } else {
        qCDebug(qLcRenderFilter, "flushSurface");
        m_surface->present(QVideoFrame());
    }
}

void VideoSurfaceFilter::renderPendingSample()
{
    if (QThread::currentThread() != thread()) {
        m_loop->postEvent(this, new QEvent(QEvent::Type(RenderSample)));
        m_waitSurface.wait(&m_mutex);
    } else {
        const std::lock_guard<QRecursiveMutex> locker(m_renderMutex);
        if (!m_pendingSample)
            return;

        qCDebug(qLcRenderFilter, "presentSample (sample=%p)", m_pendingSample);

        m_surface->present(QVideoFrame(new DirectShowVideoBuffer(m_pendingSample, m_bytesPerLine),
                                       m_surfaceFormat.frameSize(),
                                       m_surfaceFormat.pixelFormat()));
    }
}

bool VideoSurfaceFilter::event(QEvent *e)
{
    switch (e->type()) {
    case StartSurface: {
        QMutexLocker locker(&m_mutex);
        startSurface();
        m_waitSurface.wakeAll();
        return true;
    }
    case StopSurface: {
        QMutexLocker locker(&m_mutex);
        stopSurface();
        m_waitSurface.wakeAll();
        return true;
    }
    case RestartSurface: {
        QMutexLocker locker(&m_mutex);
        restartSurface();
        m_waitSurface.wakeAll();
        return true;
    }
    case FlushSurface: {
        QMutexLocker locker(&m_mutex);
        flushSurface();
        m_waitSurface.wakeAll();
        return true;
    }
    case RenderSample: {
        QMutexLocker locker(&m_mutex);
        renderPendingSample();
        m_waitSurface.wakeAll();
        return true;
    }
    default:
        break;
    }

    return QObject::event(e);
}

QT_END_NAMESPACE
