summaryrefslogtreecommitdiffstats
path: root/src/plugins/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/common')
-rw-r--r--src/plugins/common/evr.pri20
-rw-r--r--src/plugins/common/evr/evrcustompresenter.cpp2062
-rw-r--r--src/plugins/common/evr/evrcustompresenter.h377
-rw-r--r--src/plugins/common/evr/evrd3dpresentengine.cpp413
-rw-r--r--src/plugins/common/evr/evrd3dpresentengine.h152
-rw-r--r--src/plugins/common/evr/evrdefs.cpp48
-rw-r--r--src/plugins/common/evr/evrdefs.h353
-rw-r--r--src/plugins/common/evr/evrhelpers.cpp186
-rw-r--r--src/plugins/common/evr/evrhelpers.h101
-rw-r--r--src/plugins/common/evr/evrvideowindowcontrol.cpp362
-rw-r--r--src/plugins/common/evr/evrvideowindowcontrol.h109
11 files changed, 0 insertions, 4183 deletions
diff --git a/src/plugins/common/evr.pri b/src/plugins/common/evr.pri
deleted file mode 100644
index 2a1b383df..000000000
--- a/src/plugins/common/evr.pri
+++ /dev/null
@@ -1,20 +0,0 @@
-INCLUDEPATH += $$PWD/evr
-
-qtHaveModule(widgets): QT += widgets
-QT += gui-private
-
-LIBS += -lmf -lmfplat -lmfuuid -ld3d9 -ldxva2 -lwinmm -levr
-
-HEADERS += \
- $$PWD/evr/evrvideowindowcontrol.h \
- $$PWD/evr/evrcustompresenter.h \
- $$PWD/evr/evrd3dpresentengine.h \
- $$PWD/evr/evrhelpers.h \
- $$PWD/evr/evrdefs.h
-
-SOURCES += \
- $$PWD/evr/evrvideowindowcontrol.cpp \
- $$PWD/evr/evrcustompresenter.cpp \
- $$PWD/evr/evrd3dpresentengine.cpp \
- $$PWD/evr/evrhelpers.cpp \
- $$PWD/evr/evrdefs.cpp
diff --git a/src/plugins/common/evr/evrcustompresenter.cpp b/src/plugins/common/evr/evrcustompresenter.cpp
deleted file mode 100644
index b2dd0426c..000000000
--- a/src/plugins/common/evr/evrcustompresenter.cpp
+++ /dev/null
@@ -1,2062 +0,0 @@
-/****************************************************************************
-**
-** 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 "evrcustompresenter.h"
-
-#include "evrd3dpresentengine.h"
-#include "evrhelpers.h"
-
-#include <QtCore/qmutex.h>
-#include <QtCore/qvarlengtharray.h>
-#include <QtCore/qrect.h>
-#include <qabstractvideosurface.h>
-#include <qthread.h>
-#include <qcoreapplication.h>
-#include <qmath.h>
-#include <QtCore/qdebug.h>
-
-#include <mutex>
-
-#include <float.h>
-#include <evcode.h>
-
-QT_BEGIN_NAMESPACE
-
-const static MFRatio g_DefaultFrameRate = { 30, 1 };
-static const DWORD SCHEDULER_TIMEOUT = 5000;
-static const MFTIME ONE_SECOND = 10000000;
-static const LONG ONE_MSEC = 1000;
-
-// Function declarations.
-static HRESULT setDesiredSampleTime(IMFSample *sample, const LONGLONG& hnsSampleTime, const LONGLONG& hnsDuration);
-static HRESULT clearDesiredSampleTime(IMFSample *sample);
-static HRESULT setMixerSourceRect(IMFTransform *mixer, const MFVideoNormalizedRect& nrcSource);
-static QVideoFrame::PixelFormat pixelFormatFromMediaType(IMFMediaType *type);
-
-static inline LONG MFTimeToMsec(const LONGLONG& time)
-{
- return (LONG)(time / (ONE_SECOND / ONE_MSEC));
-}
-
-bool qt_evr_setCustomPresenter(IUnknown *evr, EVRCustomPresenter *presenter)
-{
- if (!evr || !presenter)
- return false;
-
- HRESULT result = E_FAIL;
-
- IMFVideoRenderer *renderer = NULL;
- if (SUCCEEDED(evr->QueryInterface(IID_PPV_ARGS(&renderer)))) {
- result = renderer->InitializeRenderer(NULL, presenter);
- renderer->Release();
- }
-
- return result == S_OK;
-}
-
-class PresentSampleEvent : public QEvent
-{
-public:
- PresentSampleEvent(IMFSample *sample)
- : QEvent(QEvent::Type(EVRCustomPresenter::PresentSample))
- , m_sample(sample)
- {
- if (m_sample)
- m_sample->AddRef();
- }
-
- ~PresentSampleEvent() override
- {
- if (m_sample)
- m_sample->Release();
- }
-
- IMFSample *sample() const { return m_sample; }
-
-private:
- IMFSample *m_sample;
-};
-
-Scheduler::Scheduler(EVRCustomPresenter *presenter)
- : m_presenter(presenter)
- , m_clock(NULL)
- , m_threadID(0)
- , m_schedulerThread(0)
- , m_threadReadyEvent(0)
- , m_flushEvent(0)
- , m_playbackRate(1.0f)
- , m_perFrameInterval(0)
- , m_perFrame_1_4th(0)
- , m_lastSampleTime(0)
-{
-}
-
-Scheduler::~Scheduler()
-{
- qt_evr_safe_release(&m_clock);
- for (int i = 0; i < m_scheduledSamples.size(); ++i)
- m_scheduledSamples[i]->Release();
- m_scheduledSamples.clear();
-}
-
-void Scheduler::setFrameRate(const MFRatio& fps)
-{
- UINT64 AvgTimePerFrame = 0;
-
- // Convert to a duration.
- MFFrameRateToAverageTimePerFrame(fps.Numerator, fps.Denominator, &AvgTimePerFrame);
-
- m_perFrameInterval = (MFTIME)AvgTimePerFrame;
-
- // Calculate 1/4th of this value, because we use it frequently.
- m_perFrame_1_4th = m_perFrameInterval / 4;
-}
-
-HRESULT Scheduler::startScheduler(IMFClock *clock)
-{
- if (m_schedulerThread)
- return E_UNEXPECTED;
-
- HRESULT hr = S_OK;
- DWORD dwID = 0;
- HANDLE hObjects[2];
- DWORD dwWait = 0;
-
- if (m_clock)
- m_clock->Release();
- m_clock = clock;
- if (m_clock)
- m_clock->AddRef();
-
- // Set a high the timer resolution (ie, short timer period).
- timeBeginPeriod(1);
-
- // Create an event to wait for the thread to start.
- m_threadReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (!m_threadReadyEvent) {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto done;
- }
-
- // Create an event to wait for flush commands to complete.
- m_flushEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (!m_flushEvent) {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto done;
- }
-
- // Create the scheduler thread.
- m_schedulerThread = CreateThread(NULL, 0, schedulerThreadProc, (LPVOID)this, 0, &dwID);
- if (!m_schedulerThread) {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto done;
- }
-
- // Wait for the thread to signal the "thread ready" event.
- hObjects[0] = m_threadReadyEvent;
- hObjects[1] = m_schedulerThread;
- dwWait = WaitForMultipleObjects(2, hObjects, FALSE, INFINITE); // Wait for EITHER of these handles.
- if (WAIT_OBJECT_0 != dwWait) {
- // The thread terminated early for some reason. This is an error condition.
- CloseHandle(m_schedulerThread);
- m_schedulerThread = NULL;
-
- hr = E_UNEXPECTED;
- goto done;
- }
-
- m_threadID = dwID;
-
-done:
- // Regardless success/failure, we are done using the "thread ready" event.
- if (m_threadReadyEvent) {
- CloseHandle(m_threadReadyEvent);
- m_threadReadyEvent = NULL;
- }
- return hr;
-}
-
-HRESULT Scheduler::stopScheduler()
-{
- if (!m_schedulerThread)
- return S_OK;
-
- // Ask the scheduler thread to exit.
- PostThreadMessage(m_threadID, Terminate, 0, 0);
-
- // Wait for the thread to exit.
- WaitForSingleObject(m_schedulerThread, INFINITE);
-
- // Close handles.
- CloseHandle(m_schedulerThread);
- m_schedulerThread = NULL;
-
- CloseHandle(m_flushEvent);
- m_flushEvent = NULL;
-
- // Discard samples.
- m_mutex.lock();
- for (int i = 0; i < m_scheduledSamples.size(); ++i)
- m_scheduledSamples[i]->Release();
- m_scheduledSamples.clear();
- m_mutex.unlock();
-
- // Restore the timer resolution.
- timeEndPeriod(1);
-
- return S_OK;
-}
-
-HRESULT Scheduler::flush()
-{
- if (m_schedulerThread) {
- // Ask the scheduler thread to flush.
- PostThreadMessage(m_threadID, Flush, 0 , 0);
-
- // Wait for the scheduler thread to signal the flush event,
- // OR for the thread to terminate.
- HANDLE objects[] = { m_flushEvent, m_schedulerThread };
-
- WaitForMultipleObjects(ARRAYSIZE(objects), objects, FALSE, SCHEDULER_TIMEOUT);
- }
-
- return S_OK;
-}
-
-bool Scheduler::areSamplesScheduled()
-{
- QMutexLocker locker(&m_mutex);
- return m_scheduledSamples.count() > 0;
-}
-
-HRESULT Scheduler::scheduleSample(IMFSample *sample, bool presentNow)
-{
- if (!m_schedulerThread)
- return MF_E_NOT_INITIALIZED;
-
- HRESULT hr = S_OK;
- DWORD dwExitCode = 0;
-
- GetExitCodeThread(m_schedulerThread, &dwExitCode);
- if (dwExitCode != STILL_ACTIVE)
- return E_FAIL;
-
- if (presentNow || !m_clock) {
- m_presenter->presentSample(sample);
- } else {
- // Queue the sample and ask the scheduler thread to wake up.
- m_mutex.lock();
- sample->AddRef();
- m_scheduledSamples.enqueue(sample);
- m_mutex.unlock();
-
- if (SUCCEEDED(hr))
- PostThreadMessage(m_threadID, Schedule, 0, 0);
- }
-
- return hr;
-}
-
-HRESULT Scheduler::processSamplesInQueue(LONG *nextSleep)
-{
- HRESULT hr = S_OK;
- LONG wait = 0;
- IMFSample *sample = NULL;
-
- // Process samples until the queue is empty or until the wait time > 0.
- while (!m_scheduledSamples.isEmpty()) {
- m_mutex.lock();
- sample = m_scheduledSamples.dequeue();
- m_mutex.unlock();
-
- // Process the next sample in the queue. If the sample is not ready
- // for presentation. the value returned in wait is > 0, which
- // means the scheduler should sleep for that amount of time.
-
- hr = processSample(sample, &wait);
- qt_evr_safe_release(&sample);
-
- if (FAILED(hr) || wait > 0)
- break;
- }
-
- // If the wait time is zero, it means we stopped because the queue is
- // empty (or an error occurred). Set the wait time to infinite; this will
- // make the scheduler thread sleep until it gets another thread message.
- if (wait == 0)
- wait = INFINITE;
-
- *nextSleep = wait;
- return hr;
-}
-
-HRESULT Scheduler::processSample(IMFSample *sample, LONG *pNextSleep)
-{
- HRESULT hr = S_OK;
-
- LONGLONG hnsPresentationTime = 0;
- LONGLONG hnsTimeNow = 0;
- MFTIME hnsSystemTime = 0;
-
- bool presentNow = true;
- LONG nextSleep = 0;
-
- if (m_clock) {
- // Get the sample's time stamp. It is valid for a sample to
- // have no time stamp.
- hr = sample->GetSampleTime(&hnsPresentationTime);
-
- // Get the clock time. (But if the sample does not have a time stamp,
- // we don't need the clock time.)
- if (SUCCEEDED(hr))
- hr = m_clock->GetCorrelatedTime(0, &hnsTimeNow, &hnsSystemTime);
-
- // Calculate the time until the sample's presentation time.
- // A negative value means the sample is late.
- LONGLONG hnsDelta = hnsPresentationTime - hnsTimeNow;
- if (m_playbackRate < 0) {
- // For reverse playback, the clock runs backward. Therefore, the
- // delta is reversed.
- hnsDelta = - hnsDelta;
- }
-
- if (hnsDelta < - m_perFrame_1_4th) {
- // This sample is late.
- presentNow = true;
- } else if (hnsDelta > (3 * m_perFrame_1_4th)) {
- // This sample is still too early. Go to sleep.
- nextSleep = MFTimeToMsec(hnsDelta - (3 * m_perFrame_1_4th));
-
- // Adjust the sleep time for the clock rate. (The presentation clock runs
- // at m_fRate, but sleeping uses the system clock.)
- if (m_playbackRate != 0)
- nextSleep = (LONG)(nextSleep / qFabs(m_playbackRate));
-
- // Don't present yet.
- presentNow = false;
- }
- }
-
- if (presentNow) {
- m_presenter->presentSample(sample);
- } else {
- // The sample is not ready yet. Return it to the queue.
- m_mutex.lock();
- sample->AddRef();
- m_scheduledSamples.prepend(sample);
- m_mutex.unlock();
- }
-
- *pNextSleep = nextSleep;
-
- return hr;
-}
-
-DWORD WINAPI Scheduler::schedulerThreadProc(LPVOID parameter)
-{
- Scheduler* scheduler = reinterpret_cast<Scheduler*>(parameter);
- if (!scheduler)
- return -1;
- return scheduler->schedulerThreadProcPrivate();
-}
-
-DWORD Scheduler::schedulerThreadProcPrivate()
-{
- HRESULT hr = S_OK;
- MSG msg;
- LONG wait = INFINITE;
- bool exitThread = false;
-
- // Force the system to create a message queue for this thread.
- // (See MSDN documentation for PostThreadMessage.)
- PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
-
- // Signal to the scheduler that the thread is ready.
- SetEvent(m_threadReadyEvent);
-
- while (!exitThread) {
- // Wait for a thread message OR until the wait time expires.
- DWORD result = MsgWaitForMultipleObjects(0, NULL, FALSE, wait, QS_POSTMESSAGE);
-
- if (result == WAIT_TIMEOUT) {
- // If we timed out, then process the samples in the queue
- hr = processSamplesInQueue(&wait);
- if (FAILED(hr))
- exitThread = true;
- }
-
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
- bool processSamples = true;
-
- switch (msg.message) {
- case Terminate:
- exitThread = true;
- break;
- case Flush:
- // Flushing: Clear the sample queue and set the event.
- m_mutex.lock();
- for (int i = 0; i < m_scheduledSamples.size(); ++i)
- m_scheduledSamples[i]->Release();
- m_scheduledSamples.clear();
- m_mutex.unlock();
- wait = INFINITE;
- SetEvent(m_flushEvent);
- break;
- case Schedule:
- // Process as many samples as we can.
- if (processSamples) {
- hr = processSamplesInQueue(&wait);
- if (FAILED(hr))
- exitThread = true;
- processSamples = (wait != (LONG)INFINITE);
- }
- break;
- }
- }
-
- }
-
- return (SUCCEEDED(hr) ? 0 : 1);
-}
-
-
-SamplePool::SamplePool()
- : m_initialized(false)
-{
-}
-
-SamplePool::~SamplePool()
-{
- clear();
-}
-
-HRESULT SamplePool::getSample(IMFSample **sample)
-{
- QMutexLocker locker(&m_mutex);
-
- if (!m_initialized)
- return MF_E_NOT_INITIALIZED;
-
- if (m_videoSampleQueue.isEmpty())
- return MF_E_SAMPLEALLOCATOR_EMPTY;
-
- // Get a sample from the allocated queue.
-
- // It doesn't matter if we pull them from the head or tail of the list,
- // but when we get it back, we want to re-insert it onto the opposite end.
- // (see ReturnSample)
-
- IMFSample *taken = m_videoSampleQueue.takeFirst();
-
- // Give the sample to the caller.
- *sample = taken;
- (*sample)->AddRef();
-
- taken->Release();
-
- return S_OK;
-}
-
-HRESULT SamplePool::returnSample(IMFSample *sample)
-{
- QMutexLocker locker(&m_mutex);
-
- if (!m_initialized)
- return MF_E_NOT_INITIALIZED;
-
- m_videoSampleQueue.append(sample);
- sample->AddRef();
-
- return S_OK;
-}
-
-HRESULT SamplePool::initialize(QList<IMFSample*> &samples)
-{
- QMutexLocker locker(&m_mutex);
-
- if (m_initialized)
- return MF_E_INVALIDREQUEST;
-
- // Move these samples into our allocated queue.
- for (auto sample : qAsConst(samples)) {
- sample->AddRef();
- m_videoSampleQueue.append(sample);
- }
-
- m_initialized = true;
-
- for (auto sample : qAsConst(samples))
- sample->Release();
- samples.clear();
- return S_OK;
-}
-
-HRESULT SamplePool::clear()
-{
- QMutexLocker locker(&m_mutex);
-
- for (auto sample : qAsConst(m_videoSampleQueue))
- sample->Release();
- m_videoSampleQueue.clear();
- m_initialized = false;
-
- return S_OK;
-}
-
-
-EVRCustomPresenter::EVRCustomPresenter(QAbstractVideoSurface *surface)
- : QObject()
- , m_sampleFreeCB(this, &EVRCustomPresenter::onSampleFree)
- , m_refCount(1)
- , m_renderState(RenderShutdown)
- , m_scheduler(this)
- , m_tokenCounter(0)
- , m_sampleNotify(false)
- , m_repaint(false)
- , m_prerolled(false)
- , m_endStreaming(false)
- , m_playbackRate(1.0f)
- , m_presentEngine(new D3DPresentEngine)
- , m_clock(0)
- , m_mixer(0)
- , m_mediaEventSink(0)
- , m_mediaType(0)
- , m_surface(0)
- , m_canRenderToSurface(false)
- , m_positionOffset(0)
-{
- // Initial source rectangle = (0,0,1,1)
- m_sourceRect.top = 0;
- m_sourceRect.left = 0;
- m_sourceRect.bottom = 1;
- m_sourceRect.right = 1;
-
- setSurface(surface);
-}
-
-EVRCustomPresenter::~EVRCustomPresenter()
-{
- m_scheduler.flush();
- m_scheduler.stopScheduler();
- m_samplePool.clear();
-
- qt_evr_safe_release(&m_clock);
- qt_evr_safe_release(&m_mixer);
- qt_evr_safe_release(&m_mediaEventSink);
- qt_evr_safe_release(&m_mediaType);
-
- delete m_presentEngine;
-}
-
-HRESULT EVRCustomPresenter::QueryInterface(REFIID riid, void ** ppvObject)
-{
- if (!ppvObject)
- return E_POINTER;
- if (riid == IID_IMFGetService) {
- *ppvObject = static_cast<IMFGetService*>(this);
- } else if (riid == IID_IMFTopologyServiceLookupClient) {
- *ppvObject = static_cast<IMFTopologyServiceLookupClient*>(this);
- } else if (riid == IID_IMFVideoDeviceID) {
- *ppvObject = static_cast<IMFVideoDeviceID*>(this);
- } else if (riid == IID_IMFVideoPresenter) {
- *ppvObject = static_cast<IMFVideoPresenter*>(this);
- } else if (riid == IID_IMFRateSupport) {
- *ppvObject = static_cast<IMFRateSupport*>(this);
- } else if (riid == IID_IUnknown) {
- *ppvObject = static_cast<IUnknown*>(static_cast<IMFGetService*>(this));
- } else if (riid == IID_IMFClockStateSink) {
- *ppvObject = static_cast<IMFClockStateSink*>(this);
- } else {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
-}
-
-ULONG EVRCustomPresenter::AddRef()
-{
- return InterlockedIncrement(&m_refCount);
-}
-
-ULONG EVRCustomPresenter::Release()
-{
- ULONG uCount = InterlockedDecrement(&m_refCount);
- if (uCount == 0)
- delete this;
- return uCount;
-}
-
-HRESULT EVRCustomPresenter::GetService(REFGUID guidService, REFIID riid, LPVOID *ppvObject)
-{
- HRESULT hr = S_OK;
-
- if (!ppvObject)
- return E_POINTER;
-
- // The only service GUID that we support is MR_VIDEO_RENDER_SERVICE.
- if (guidService != mr_VIDEO_RENDER_SERVICE)
- return MF_E_UNSUPPORTED_SERVICE;
-
- // First try to get the service interface from the D3DPresentEngine object.
- hr = m_presentEngine->getService(guidService, riid, ppvObject);
- if (FAILED(hr))
- // Next, check if this object supports the interface.
- hr = QueryInterface(riid, ppvObject);
-
- return hr;
-}
-
-HRESULT EVRCustomPresenter::GetDeviceID(IID* deviceID)
-{
- if (!deviceID)
- return E_POINTER;
-
- *deviceID = iid_IDirect3DDevice9;
-
- return S_OK;
-}
-
-HRESULT EVRCustomPresenter::InitServicePointers(IMFTopologyServiceLookup *lookup)
-{
- if (!lookup)
- return E_POINTER;
-
- HRESULT hr = S_OK;
- DWORD objectCount = 0;
-
- const std::lock_guard<QRecursiveMutex> locker(m_mutex);
-
- // Do not allow initializing when playing or paused.
- if (isActive())
- return MF_E_INVALIDREQUEST;
-
- qt_evr_safe_release(&m_clock);
- qt_evr_safe_release(&m_mixer);
- qt_evr_safe_release(&m_mediaEventSink);
-
- // Ask for the clock. Optional, because the EVR might not have a clock.
- objectCount = 1;
-
- lookup->LookupService(MF_SERVICE_LOOKUP_GLOBAL, 0,
- mr_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&m_clock),
- &objectCount
- );
-
- // Ask for the mixer. (Required.)
- objectCount = 1;
-
- hr = lookup->LookupService(MF_SERVICE_LOOKUP_GLOBAL, 0,
- mr_VIDEO_MIXER_SERVICE, IID_PPV_ARGS(&m_mixer),
- &objectCount
- );
-
- if (FAILED(hr))
- return hr;
-
- // Make sure that we can work with this mixer.
- hr = configureMixer(m_mixer);
- if (FAILED(hr))
- return hr;
-
- // Ask for the EVR's event-sink interface. (Required.)
- objectCount = 1;
-
- hr = lookup->LookupService(MF_SERVICE_LOOKUP_GLOBAL, 0,
- mr_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&m_mediaEventSink),
- &objectCount
- );
-
- if (SUCCEEDED(hr))
- m_renderState = RenderStopped;
-
- return hr;
-}
-
-HRESULT EVRCustomPresenter::ReleaseServicePointers()
-{
- // Enter the shut-down state.
- m_mutex.lock();
-
- m_renderState = RenderShutdown;
-
- m_mutex.unlock();
-
- // Flush any samples that were scheduled.
- flush();
-
- // Clear the media type and release related resources.
- setMediaType(NULL);
-
- // Release all services that were acquired from InitServicePointers.
- qt_evr_safe_release(&m_clock);
- qt_evr_safe_release(&m_mixer);
- qt_evr_safe_release(&m_mediaEventSink);
-
- return S_OK;
-}
-
-bool EVRCustomPresenter::isValid() const
-{
- return m_presentEngine->isValid() && m_canRenderToSurface;
-}
-
-HRESULT EVRCustomPresenter::ProcessMessage(MFVP_MESSAGE_TYPE message, ULONG_PTR param)
-{
- HRESULT hr = S_OK;
-
- const std::lock_guard<QRecursiveMutex> locker(m_mutex);
-
- hr = checkShutdown();
- if (FAILED(hr))
- return hr;
-
- switch (message) {
- // Flush all pending samples.
- case MFVP_MESSAGE_FLUSH:
- hr = flush();
- break;
-
- // Renegotiate the media type with the mixer.
- case MFVP_MESSAGE_INVALIDATEMEDIATYPE:
- hr = renegotiateMediaType();
- break;
-
- // The mixer received a new input sample.
- case MFVP_MESSAGE_PROCESSINPUTNOTIFY:
- hr = processInputNotify();
- break;
-
- // Streaming is about to start.
- case MFVP_MESSAGE_BEGINSTREAMING:
- hr = beginStreaming();
- break;
-
- // Streaming has ended. (The EVR has stopped.)
- case MFVP_MESSAGE_ENDSTREAMING:
- hr = endStreaming();
- break;
-
- // All input streams have ended.
- case MFVP_MESSAGE_ENDOFSTREAM:
- // Set the EOS flag.
- m_endStreaming = true;
- // Check if it's time to send the EC_COMPLETE event to the EVR.
- hr = checkEndOfStream();
- break;
-
- // Frame-stepping is starting.
- case MFVP_MESSAGE_STEP:
- hr = prepareFrameStep(DWORD(param));
- break;
-
- // Cancels frame-stepping.
- case MFVP_MESSAGE_CANCELSTEP:
- hr = cancelFrameStep();
- break;
-
- default:
- hr = E_INVALIDARG; // Unknown message. This case should never occur.
- break;
- }
-
- return hr;
-}
-
-HRESULT EVRCustomPresenter::GetCurrentMediaType(IMFVideoMediaType **mediaType)
-{
- HRESULT hr = S_OK;
-
- if (!mediaType)
- return E_POINTER;
-
- *mediaType = NULL;
-
- const std::lock_guard<QRecursiveMutex> locker(m_mutex);
-
- hr = checkShutdown();
- if (FAILED(hr))
- return hr;
-
- if (!m_mediaType)
- return MF_E_NOT_INITIALIZED;
-
- return m_mediaType->QueryInterface(IID_PPV_ARGS(mediaType));
-}
-
-HRESULT EVRCustomPresenter::OnClockStart(MFTIME, LONGLONG clockStartOffset)
-{
- const std::lock_guard<QRecursiveMutex> locker(m_mutex);
-
- // We cannot start after shutdown.
- HRESULT hr = checkShutdown();
- if (FAILED(hr))
- return hr;
-
- // Check if the clock is already active (not stopped).
- if (isActive()) {
- m_renderState = RenderStarted;
-
- // If the clock position changes while the clock is active, it
- // is a seek request. We need to flush all pending samples.
- if (clockStartOffset != PRESENTATION_CURRENT_POSITION)
- flush();
- } else {
- m_renderState = RenderStarted;
-
- // The clock has started from the stopped state.
-
- // Possibly we are in the middle of frame-stepping OR have samples waiting
- // in the frame-step queue. Deal with these two cases first:
- hr = startFrameStep();
- if (FAILED(hr))
- return hr;
- }
-
- // Now try to get new output samples from the mixer.
- processOutputLoop();
-
- return hr;
-}
-
-HRESULT EVRCustomPresenter::OnClockRestart(MFTIME)
-{
- const std::lock_guard<QRecursiveMutex> locker(m_mutex);
-
- HRESULT hr = checkShutdown();
- if (FAILED(hr))
- return hr;
-
- // The EVR calls OnClockRestart only while paused.
-
- m_renderState = RenderStarted;
-
- // Possibly we are in the middle of frame-stepping OR we have samples waiting
- // in the frame-step queue. Deal with these two cases first:
- hr = startFrameStep();
- if (FAILED(hr))
- return hr;
-
- // Now resume the presentation loop.
- processOutputLoop();
-
- return hr;
-}
-
-HRESULT EVRCustomPresenter::OnClockStop(MFTIME)
-{
- const std::lock_guard<QRecursiveMutex> locker(m_mutex);
-
- HRESULT hr = checkShutdown();
- if (FAILED(hr))
- return hr;
-
- if (m_renderState != RenderStopped) {
- m_renderState = RenderStopped;
- flush();
-
- // If we are in the middle of frame-stepping, cancel it now.
- if (m_frameStep.state != FrameStepNone)
- cancelFrameStep();
- }
-
- return S_OK;
-}
-
-HRESULT EVRCustomPresenter::OnClockPause(MFTIME)
-{
- const std::lock_guard<QRecursiveMutex> locker(m_mutex);
-
- // We cannot pause the clock after shutdown.
- HRESULT hr = checkShutdown();
-
- if (SUCCEEDED(hr))
- m_renderState = RenderPaused;
-
- return hr;
-}
-
-HRESULT EVRCustomPresenter::OnClockSetRate(MFTIME, float rate)
-{
- // Note:
- // The presenter reports its maximum rate through the IMFRateSupport interface.
- // Here, we assume that the EVR honors the maximum rate.
-
- const std::lock_guard<QRecursiveMutex> locker(m_mutex);
-
- HRESULT hr = checkShutdown();
- if (FAILED(hr))
- return hr;
-
- // If the rate is changing from zero (scrubbing) to non-zero, cancel the
- // frame-step operation.
- if ((m_playbackRate == 0.0f) && (rate != 0.0f)) {
- cancelFrameStep();
- for (auto sample : qAsConst(m_frameStep.samples))
- sample->Release();
- m_frameStep.samples.clear();
- }
-
- m_playbackRate = rate;
-
- // Tell the scheduler about the new rate.
- m_scheduler.setClockRate(rate);
-
- return S_OK;
-}
-
-HRESULT EVRCustomPresenter::GetSlowestRate(MFRATE_DIRECTION, BOOL, float *rate)
-{
- if (!rate)
- return E_POINTER;
-
- const std::lock_guard<QRecursiveMutex> locker(m_mutex);
-
- HRESULT hr = checkShutdown();
-
- if (SUCCEEDED(hr)) {
- // There is no minimum playback rate, so the minimum is zero.
- *rate = 0;
- }
-
- return S_OK;
-}
-
-HRESULT EVRCustomPresenter::GetFastestRate(MFRATE_DIRECTION direction, BOOL thin, float *rate)
-{
- if (!rate)
- return E_POINTER;
-
- const std::lock_guard<QRecursiveMutex> locker(m_mutex);
-
- float maxRate = 0.0f;
-
- HRESULT hr = checkShutdown();
- if (FAILED(hr))
- return hr;
-
- // Get the maximum *forward* rate.
- maxRate = getMaxRate(thin);
-
- // For reverse playback, it's the negative of maxRate.
- if (direction == MFRATE_REVERSE)
- maxRate = -maxRate;
-
- *rate = maxRate;
-
- return S_OK;
-}
-
-HRESULT EVRCustomPresenter::IsRateSupported(BOOL thin, float rate, float *nearestSupportedRate)
-{
- const std::lock_guard<QRecursiveMutex> locker(m_mutex);
-
- float maxRate = 0.0f;
- float nearestRate = rate; // If we support rate, that is the nearest.
-
- HRESULT hr = checkShutdown();
- if (FAILED(hr))
- return hr;
-
- // Find the maximum forward rate.
- // Note: We have no minimum rate (that is, we support anything down to 0).
- maxRate = getMaxRate(thin);
-
- if (qFabs(rate) > maxRate) {
- // The (absolute) requested rate exceeds the maximum rate.
- hr = MF_E_UNSUPPORTED_RATE;
-
- // The nearest supported rate is maxRate.
- nearestRate = maxRate;
- if (rate < 0) {
- // Negative for reverse playback.
- nearestRate = -nearestRate;
- }
- }
-
- // Return the nearest supported rate.
- if (nearestSupportedRate)
- *nearestSupportedRate = nearestRate;
-
- return hr;
-}
-
-void EVRCustomPresenter::supportedFormatsChanged()
-{
- const std::lock_guard<QRecursiveMutex> locker(m_mutex);
-
- m_canRenderToSurface = false;
- m_presentEngine->setHint(D3DPresentEngine::RenderToTexture, false);
-
- // check if we can render to the surface (compatible formats)
- if (m_surface) {
- QList<QVideoFrame::PixelFormat> formats = m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle);
- if (m_presentEngine->supportsTextureRendering() && formats.contains(QVideoFrame::Format_RGB32)) {
- m_presentEngine->setHint(D3DPresentEngine::RenderToTexture, true);
- m_canRenderToSurface = true;
- } else {
- formats = m_surface->supportedPixelFormats(QAbstractVideoBuffer::NoHandle);
- for (QVideoFrame::PixelFormat format : qAsConst(formats)) {
- if (SUCCEEDED(m_presentEngine->checkFormat(qt_evr_D3DFormatFromPixelFormat(format)))) {
- m_canRenderToSurface = true;
- break;
- }
- }
- }
- }
-
- // TODO: if media type already set, renegotiate?
-}
-
-void EVRCustomPresenter::setSurface(QAbstractVideoSurface *surface)
-{
- m_mutex.lock();
-
- if (m_surface) {
- disconnect(m_surface, &QAbstractVideoSurface::supportedFormatsChanged,
- this, &EVRCustomPresenter::supportedFormatsChanged);
- }
-
- m_surface = surface;
-
- if (m_surface) {
- connect(m_surface, &QAbstractVideoSurface::supportedFormatsChanged,
- this, &EVRCustomPresenter::supportedFormatsChanged);
- }
-
- m_mutex.unlock();
-
- supportedFormatsChanged();
-}
-
-HRESULT EVRCustomPresenter::configureMixer(IMFTransform *mixer)
-{
- // Set the zoom rectangle (ie, the source clipping rectangle).
- return setMixerSourceRect(mixer, m_sourceRect);
-}
-
-HRESULT EVRCustomPresenter::renegotiateMediaType()
-{
- HRESULT hr = S_OK;
- bool foundMediaType = false;
-
- IMFMediaType *mixerType = NULL;
- IMFMediaType *optimalType = NULL;
-
- if (!m_mixer)
- return MF_E_INVALIDREQUEST;
-
- // Loop through all of the mixer's proposed output types.
- DWORD typeIndex = 0;
- while (!foundMediaType && (hr != MF_E_NO_MORE_TYPES)) {
- qt_evr_safe_release(&mixerType);
- qt_evr_safe_release(&optimalType);
-
- // Step 1. Get the next media type supported by mixer.
- hr = m_mixer->GetOutputAvailableType(0, typeIndex++, &mixerType);
- if (FAILED(hr))
- break;
-
- // From now on, if anything in this loop fails, try the next type,
- // until we succeed or the mixer runs out of types.
-
- // Step 2. Check if we support this media type.
- if (SUCCEEDED(hr))
- hr = isMediaTypeSupported(mixerType);
-
- // Step 3. Adjust the mixer's type to match our requirements.
- if (SUCCEEDED(hr))
- hr = createOptimalVideoType(mixerType, &optimalType);
-
- // Step 4. Check if the mixer will accept this media type.
- if (SUCCEEDED(hr))
- hr = m_mixer->SetOutputType(0, optimalType, MFT_SET_TYPE_TEST_ONLY);
-
- // Step 5. Try to set the media type on ourselves.
- if (SUCCEEDED(hr))
- hr = setMediaType(optimalType);
-
- // Step 6. Set output media type on mixer.
- if (SUCCEEDED(hr)) {
- hr = m_mixer->SetOutputType(0, optimalType, 0);
-
- // If something went wrong, clear the media type.
- if (FAILED(hr))
- setMediaType(NULL);
- }
-
- if (SUCCEEDED(hr))
- foundMediaType = true;
- }
-
- qt_evr_safe_release(&mixerType);
- qt_evr_safe_release(&optimalType);
-
- return hr;
-}
-
-HRESULT EVRCustomPresenter::flush()
-{
- m_prerolled = false;
-
- // The scheduler might have samples that are waiting for
- // their presentation time. Tell the scheduler to flush.
-
- // This call blocks until the scheduler threads discards all scheduled samples.
- m_scheduler.flush();
-
- // Flush the frame-step queue.
- for (auto sample : qAsConst(m_frameStep.samples))
- sample->Release();
- m_frameStep.samples.clear();
-
- if (m_renderState == RenderStopped && m_surface && m_surface->isActive()) {
- // Repaint with black.
- presentSample(NULL);
- }
-
- return S_OK;
-}
-
-HRESULT EVRCustomPresenter::processInputNotify()
-{
- HRESULT hr = S_OK;
-
- // Set the flag that says the mixer has a new sample.
- m_sampleNotify = true;
-
- if (!m_mediaType) {
- // We don't have a valid media type yet.
- hr = MF_E_TRANSFORM_TYPE_NOT_SET;
- } else {
- // Try to process an output sample.
- processOutputLoop();
- }
- return hr;
-}
-
-HRESULT EVRCustomPresenter::beginStreaming()
-{
- HRESULT hr = S_OK;
-
- // Start the scheduler thread.
- hr = m_scheduler.startScheduler(m_clock);
-
- return hr;
-}
-
-HRESULT EVRCustomPresenter::endStreaming()
-{
- HRESULT hr = S_OK;
-
- // Stop the scheduler thread.
- hr = m_scheduler.stopScheduler();
-
- return hr;
-}
-
-HRESULT EVRCustomPresenter::checkEndOfStream()
-{
- if (!m_endStreaming) {
- // The EVR did not send the MFVP_MESSAGE_ENDOFSTREAM message.
- return S_OK;
- }
-
- if (m_sampleNotify) {
- // The mixer still has input.
- return S_OK;
- }
-
- if (m_scheduler.areSamplesScheduled()) {
- // Samples are still scheduled for rendering.
- return S_OK;
- }
-
- // Everything is complete. Now we can tell the EVR that we are done.
- notifyEvent(EC_COMPLETE, (LONG_PTR)S_OK, 0);
- m_endStreaming = false;
-
- stopSurface();
- return S_OK;
-}
-
-HRESULT EVRCustomPresenter::prepareFrameStep(DWORD steps)
-{
- HRESULT hr = S_OK;
-
- // Cache the step count.
- m_frameStep.steps += steps;
-
- // Set the frame-step state.
- m_frameStep.state = FrameStepWaitingStart;
-
- // If the clock is are already running, we can start frame-stepping now.
- // Otherwise, we will start when the clock starts.
- if (m_renderState == RenderStarted)
- hr = startFrameStep();
-
- return hr;
-}
-
-HRESULT EVRCustomPresenter::startFrameStep()
-{
- HRESULT hr = S_OK;
- IMFSample *sample = NULL;
-
- if (m_frameStep.state == FrameStepWaitingStart) {
- // We have a frame-step request, and are waiting for the clock to start.
- // Set the state to "pending," which means we are waiting for samples.
- m_frameStep.state = FrameStepPending;
-
- // If the frame-step queue already has samples, process them now.
- while (!m_frameStep.samples.isEmpty() && (m_frameStep.state == FrameStepPending)) {
- sample = m_frameStep.samples.takeFirst();
-
- hr = deliverFrameStepSample(sample);
- if (FAILED(hr))
- goto done;
-
- qt_evr_safe_release(&sample);
-
- // We break from this loop when:
- // (a) the frame-step queue is empty, or
- // (b) the frame-step operation is complete.
- }
- } else if (m_frameStep.state == FrameStepNone) {
- // We are not frame stepping. Therefore, if the frame-step queue has samples,
- // we need to process them normally.
- while (!m_frameStep.samples.isEmpty()) {
- sample = m_frameStep.samples.takeFirst();
-
- hr = deliverSample(sample, false);
- if (FAILED(hr))
- goto done;
-
- qt_evr_safe_release(&sample);
- }
- }
-
-done:
- qt_evr_safe_release(&sample);
- return hr;
-}
-
-HRESULT EVRCustomPresenter::completeFrameStep(IMFSample *sample)
-{
- HRESULT hr = S_OK;
- MFTIME sampleTime = 0;
- MFTIME systemTime = 0;
-
- // Update our state.
- m_frameStep.state = FrameStepComplete;
- m_frameStep.sampleNoRef = 0;
-
- // Notify the EVR that the frame-step is complete.
- notifyEvent(EC_STEP_COMPLETE, FALSE, 0); // FALSE = completed (not cancelled)
-
- // If we are scrubbing (rate == 0), also send the "scrub time" event.
- if (isScrubbing()) {
- // Get the time stamp from the sample.
- hr = sample->GetSampleTime(&sampleTime);
- if (FAILED(hr)) {
- // No time stamp. Use the current presentation time.
- if (m_clock)
- m_clock->GetCorrelatedTime(0, &sampleTime, &systemTime);
-
- hr = S_OK; // (Not an error condition.)
- }
-
- notifyEvent(EC_SCRUB_TIME, DWORD(sampleTime), DWORD(((sampleTime) >> 32) & 0xffffffff));
- }
- return hr;
-}
-
-HRESULT EVRCustomPresenter::cancelFrameStep()
-{
- FrameStepState oldState = m_frameStep.state;
-
- m_frameStep.state = FrameStepNone;
- m_frameStep.steps = 0;
- m_frameStep.sampleNoRef = 0;
- // Don't clear the frame-step queue yet, because we might frame step again.
-
- if (oldState > FrameStepNone && oldState < FrameStepComplete) {
- // We were in the middle of frame-stepping when it was cancelled.
- // Notify the EVR.
- notifyEvent(EC_STEP_COMPLETE, TRUE, 0); // TRUE = cancelled
- }
- return S_OK;
-}
-
-HRESULT EVRCustomPresenter::createOptimalVideoType(IMFMediaType *proposedType, IMFMediaType **optimalType)
-{
- HRESULT hr = S_OK;
-
- RECT rcOutput;
- ZeroMemory(&rcOutput, sizeof(rcOutput));
-
- MFVideoArea displayArea;
- ZeroMemory(&displayArea, sizeof(displayArea));
-
- IMFMediaType *mtOptimal = NULL;
-
- UINT64 size;
- int width;
- int height;
-
- // Clone the proposed type.
-
- hr = MFCreateMediaType(&mtOptimal);
- if (FAILED(hr))
- goto done;
-
- hr = proposedType->CopyAllItems(mtOptimal);
- if (FAILED(hr))
- goto done;
-
- // Modify the new type.
-
- hr = proposedType->GetUINT64(MF_MT_FRAME_SIZE, &size);
- width = int(HI32(size));
- height = int(LO32(size));
- rcOutput.left = 0;
- rcOutput.top = 0;
- rcOutput.right = width;
- rcOutput.bottom = height;
-
- // Set the geometric aperture, and disable pan/scan.
- displayArea = qt_evr_makeMFArea(0, 0, rcOutput.right, rcOutput.bottom);
-
- hr = mtOptimal->SetUINT32(MF_MT_PAN_SCAN_ENABLED, FALSE);
- if (FAILED(hr))
- goto done;
-
- hr = mtOptimal->SetBlob(MF_MT_GEOMETRIC_APERTURE, reinterpret_cast<UINT8*>(&displayArea),
- sizeof(displayArea));
- if (FAILED(hr))
- goto done;
-
- // Set the pan/scan aperture and the minimum display aperture. We don't care
- // about them per se, but the mixer will reject the type if these exceed the
- // frame dimentions.
- hr = mtOptimal->SetBlob(MF_MT_PAN_SCAN_APERTURE, reinterpret_cast<UINT8*>(&displayArea),
- sizeof(displayArea));
- if (FAILED(hr))
- goto done;
-
- hr = mtOptimal->SetBlob(MF_MT_MINIMUM_DISPLAY_APERTURE, reinterpret_cast<UINT8*>(&displayArea),
- sizeof(displayArea));
- if (FAILED(hr))
- goto done;
-
- // Return the pointer to the caller.
- *optimalType = mtOptimal;
- (*optimalType)->AddRef();
-
-done:
- qt_evr_safe_release(&mtOptimal);
- return hr;
-
-}
-
-HRESULT EVRCustomPresenter::setMediaType(IMFMediaType *mediaType)
-{
- // Note: mediaType can be NULL (to clear the type)
-
- // Clearing the media type is allowed in any state (including shutdown).
- if (!mediaType) {
- stopSurface();
- qt_evr_safe_release(&m_mediaType);
- releaseResources();
- return S_OK;
- }
-
- MFRatio fps = { 0, 0 };
- QList<IMFSample*> sampleQueue;
-
- // Cannot set the media type after shutdown.
- HRESULT hr = checkShutdown();
- if (FAILED(hr))
- goto done;
-
- // Check if the new type is actually different.
- // Note: This function safely handles NULL input parameters.
- if (qt_evr_areMediaTypesEqual(m_mediaType, mediaType))
- goto done; // Nothing more to do.
-
- // We're really changing the type. First get rid of the old type.
- qt_evr_safe_release(&m_mediaType);
- releaseResources();
-
- // Initialize the presenter engine with the new media type.
- // The presenter engine allocates the samples.
-
- hr = m_presentEngine->createVideoSamples(mediaType, sampleQueue);
- if (FAILED(hr))
- goto done;
-
- // Mark each sample with our token counter. If this batch of samples becomes
- // invalid, we increment the counter, so that we know they should be discarded.
- for (auto sample : qAsConst(sampleQueue)) {
- hr = sample->SetUINT32(MFSamplePresenter_SampleCounter, m_tokenCounter);
- if (FAILED(hr))
- goto done;
- }
-
- // Add the samples to the sample pool.
- hr = m_samplePool.initialize(sampleQueue);
- if (FAILED(hr))
- goto done;
-
- // Set the frame rate on the scheduler.
- if (SUCCEEDED(qt_evr_getFrameRate(mediaType, &fps)) && (fps.Numerator != 0) && (fps.Denominator != 0)) {
- m_scheduler.setFrameRate(fps);
- } else {
- // NOTE: The mixer's proposed type might not have a frame rate, in which case
- // we'll use an arbitrary default. (Although it's unlikely the video source
- // does not have a frame rate.)
- m_scheduler.setFrameRate(g_DefaultFrameRate);
- }
-
- // Store the media type.
- m_mediaType = mediaType;
- m_mediaType->AddRef();
-
- startSurface();
-
-done:
- if (FAILED(hr))
- releaseResources();
- return hr;
-}
-
-HRESULT EVRCustomPresenter::isMediaTypeSupported(IMFMediaType *proposed)
-{
- D3DFORMAT d3dFormat = D3DFMT_UNKNOWN;
- BOOL compressed = FALSE;
- MFVideoInterlaceMode interlaceMode = MFVideoInterlace_Unknown;
- MFVideoArea videoCropArea;
- UINT32 width = 0, height = 0;
-
- // Validate the format.
- HRESULT hr = qt_evr_getFourCC(proposed, reinterpret_cast<DWORD*>(&d3dFormat));
- if (FAILED(hr))
- return hr;
-
- QVideoFrame::PixelFormat pixelFormat = pixelFormatFromMediaType(proposed);
- if (pixelFormat == QVideoFrame::Format_Invalid)
- return MF_E_INVALIDMEDIATYPE;
-
- // When not rendering to texture, only accept pixel formats supported by the video surface
- if (!m_presentEngine->isTextureRenderingEnabled()
- && m_surface
- && !m_surface->supportedPixelFormats().contains(pixelFormat)) {
- return MF_E_INVALIDMEDIATYPE;
- }
-
- // Reject compressed media types.
- hr = proposed->IsCompressedFormat(&compressed);
- if (FAILED(hr))
- return hr;
-
- if (compressed)
- return MF_E_INVALIDMEDIATYPE;
-
- // The D3DPresentEngine checks whether surfaces can be created using this format
- hr = m_presentEngine->checkFormat(d3dFormat);
- if (FAILED(hr))
- return hr;
-
- // Reject interlaced formats.
- hr = proposed->GetUINT32(MF_MT_INTERLACE_MODE, reinterpret_cast<UINT32*>(&interlaceMode));
- if (FAILED(hr))
- return hr;
-
- if (interlaceMode != MFVideoInterlace_Progressive)
- return MF_E_INVALIDMEDIATYPE;
-
- hr = MFGetAttributeSize(proposed, MF_MT_FRAME_SIZE, &width, &height);
- if (FAILED(hr))
- return hr;
-
- // Validate the various apertures (cropping regions) against the frame size.
- // Any of these apertures may be unspecified in the media type, in which case
- // we ignore it. We just want to reject invalid apertures.
-
- if (SUCCEEDED(proposed->GetBlob(MF_MT_PAN_SCAN_APERTURE,
- reinterpret_cast<UINT8*>(&videoCropArea),
- sizeof(videoCropArea), nullptr))) {
- hr = qt_evr_validateVideoArea(videoCropArea, width, height);
- }
- if (SUCCEEDED(proposed->GetBlob(MF_MT_GEOMETRIC_APERTURE,
- reinterpret_cast<UINT8*>(&videoCropArea),
- sizeof(videoCropArea), nullptr))) {
- hr = qt_evr_validateVideoArea(videoCropArea, width, height);
- }
- if (SUCCEEDED(proposed->GetBlob(MF_MT_MINIMUM_DISPLAY_APERTURE,
- reinterpret_cast<UINT8*>(&videoCropArea),
- sizeof(videoCropArea), nullptr))) {
- hr = qt_evr_validateVideoArea(videoCropArea, width, height);
- }
- return hr;
-}
-
-void EVRCustomPresenter::processOutputLoop()
-{
- HRESULT hr = S_OK;
-
- // Process as many samples as possible.
- while (hr == S_OK) {
- // If the mixer doesn't have a new input sample, break from the loop.
- if (!m_sampleNotify) {
- hr = MF_E_TRANSFORM_NEED_MORE_INPUT;
- break;
- }
-
- // Try to process a sample.
- hr = processOutput();
-
- // NOTE: ProcessOutput can return S_FALSE to indicate it did not
- // process a sample. If so, break out of the loop.
- }
-
- if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
- // The mixer has run out of input data. Check for end-of-stream.
- checkEndOfStream();
- }
-}
-
-HRESULT EVRCustomPresenter::processOutput()
-{
- HRESULT hr = S_OK;
- DWORD status = 0;
- LONGLONG mixerStartTime = 0, mixerEndTime = 0;
- MFTIME systemTime = 0;
- BOOL repaint = m_repaint; // Temporarily store this state flag.
-
- MFT_OUTPUT_DATA_BUFFER dataBuffer;
- ZeroMemory(&dataBuffer, sizeof(dataBuffer));
-
- IMFSample *sample = NULL;
-
- // If the clock is not running, we present the first sample,
- // and then don't present any more until the clock starts.
-
- if ((m_renderState != RenderStarted) && !m_repaint && m_prerolled)
- return S_FALSE;
-
- // Make sure we have a pointer to the mixer.
- if (!m_mixer)
- return MF_E_INVALIDREQUEST;
-
- // Try to get a free sample from the video sample pool.
- hr = m_samplePool.getSample(&sample);
- if (hr == MF_E_SAMPLEALLOCATOR_EMPTY) // No free samples. Try again when a sample is released.
- return S_FALSE;
- if (FAILED(hr))
- return hr;
-
- // From now on, we have a valid video sample pointer, where the mixer will
- // write the video data.
-
- if (m_repaint) {
- // Repaint request. Ask the mixer for the most recent sample.
- setDesiredSampleTime(sample, m_scheduler.lastSampleTime(), m_scheduler.frameDuration());
-
- m_repaint = false; // OK to clear this flag now.
- } else {
- // Not a repaint request. Clear the desired sample time; the mixer will
- // give us the next frame in the stream.
- clearDesiredSampleTime(sample);
-
- if (m_clock) {
- // Latency: Record the starting time for ProcessOutput.
- m_clock->GetCorrelatedTime(0, &mixerStartTime, &systemTime);
- }
- }
-
- // Now we are ready to get an output sample from the mixer.
- dataBuffer.dwStreamID = 0;
- dataBuffer.pSample = sample;
- dataBuffer.dwStatus = 0;
-
- hr = m_mixer->ProcessOutput(0, 1, &dataBuffer, &status);
-
- if (FAILED(hr)) {
- // Return the sample to the pool.
- HRESULT hr2 = m_samplePool.returnSample(sample);
- if (FAILED(hr2)) {
- hr = hr2;
- goto done;
- }
- // Handle some known error codes from ProcessOutput.
- if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
- // The mixer's format is not set. Negotiate a new format.
- hr = renegotiateMediaType();
- } else if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
- // There was a dynamic media type change. Clear our media type.
- setMediaType(NULL);
- } else if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
- // The mixer needs more input.
- // We have to wait for the mixer to get more input.
- m_sampleNotify = false;
- }
- } else {
- // We got an output sample from the mixer.
-
- if (m_clock && !repaint) {
- // Latency: Record the ending time for the ProcessOutput operation,
- // and notify the EVR of the latency.
-
- m_clock->GetCorrelatedTime(0, &mixerEndTime, &systemTime);
-
- LONGLONG latencyTime = mixerEndTime - mixerStartTime;
- notifyEvent(EC_PROCESSING_LATENCY, reinterpret_cast<LONG_PTR>(&latencyTime), 0);
- }
-
- // Set up notification for when the sample is released.
- hr = trackSample(sample);
- if (FAILED(hr))
- goto done;
-
- // Schedule the sample.
- if ((m_frameStep.state == FrameStepNone) || repaint) {
- hr = deliverSample(sample, repaint);
- if (FAILED(hr))
- goto done;
- } else {
- // We are frame-stepping (and this is not a repaint request).
- hr = deliverFrameStepSample(sample);
- if (FAILED(hr))
- goto done;
- }
-
- m_prerolled = true; // We have presented at least one sample now.
- }
-
-done:
- qt_evr_safe_release(&sample);
-
- // Important: Release any events returned from the ProcessOutput method.
- qt_evr_safe_release(&dataBuffer.pEvents);
- return hr;
-}
-
-HRESULT EVRCustomPresenter::deliverSample(IMFSample *sample, bool repaint)
-{
- // If we are not actively playing, OR we are scrubbing (rate = 0) OR this is a
- // repaint request, then we need to present the sample immediately. Otherwise,
- // schedule it normally.
-
- bool presentNow = ((m_renderState != RenderStarted) || isScrubbing() || repaint);
-
- HRESULT hr = m_scheduler.scheduleSample(sample, presentNow);
-
- if (FAILED(hr)) {
- // Notify the EVR that we have failed during streaming. The EVR will notify the
- // pipeline.
-
- notifyEvent(EC_ERRORABORT, hr, 0);
- }
-
- return hr;
-}
-
-HRESULT EVRCustomPresenter::deliverFrameStepSample(IMFSample *sample)
-{
- HRESULT hr = S_OK;
- IUnknown *unk = NULL;
-
- // For rate 0, discard any sample that ends earlier than the clock time.
- if (isScrubbing() && m_clock && qt_evr_isSampleTimePassed(m_clock, sample)) {
- // Discard this sample.
- } else if (m_frameStep.state >= FrameStepScheduled) {
- // A frame was already submitted. Put this sample on the frame-step queue,
- // in case we are asked to step to the next frame. If frame-stepping is
- // cancelled, this sample will be processed normally.
- sample->AddRef();
- m_frameStep.samples.append(sample);
- } else {
- // We're ready to frame-step.
-
- // Decrement the number of steps.
- if (m_frameStep.steps > 0)
- m_frameStep.steps--;
-
- if (m_frameStep.steps > 0) {
- // This is not the last step. Discard this sample.
- } else if (m_frameStep.state == FrameStepWaitingStart) {
- // This is the right frame, but the clock hasn't started yet. Put the
- // sample on the frame-step queue. When the clock starts, the sample
- // will be processed.
- sample->AddRef();
- m_frameStep.samples.append(sample);
- } else {
- // This is the right frame *and* the clock has started. Deliver this sample.
- hr = deliverSample(sample, false);
- if (FAILED(hr))
- goto done;
-
- // Query for IUnknown so that we can identify the sample later.
- // Per COM rules, an object always returns the same pointer when QI'ed for IUnknown.
- hr = sample->QueryInterface(IID_PPV_ARGS(&unk));
- if (FAILED(hr))
- goto done;
-
- m_frameStep.sampleNoRef = reinterpret_cast<DWORD_PTR>(unk); // No add-ref.
-
- // NOTE: We do not AddRef the IUnknown pointer, because that would prevent the
- // sample from invoking the OnSampleFree callback after the sample is presented.
- // We use this IUnknown pointer purely to identify the sample later; we never
- // attempt to dereference the pointer.
-
- m_frameStep.state = FrameStepScheduled;
- }
- }
-done:
- qt_evr_safe_release(&unk);
- return hr;
-}
-
-HRESULT EVRCustomPresenter::trackSample(IMFSample *sample)
-{
- IMFTrackedSample *tracked = NULL;
-
- HRESULT hr = sample->QueryInterface(IID_PPV_ARGS(&tracked));
-
- if (SUCCEEDED(hr))
- hr = tracked->SetAllocator(&m_sampleFreeCB, NULL);
-
- qt_evr_safe_release(&tracked);
- return hr;
-}
-
-void EVRCustomPresenter::releaseResources()
-{
- // Increment the token counter to indicate that all existing video samples
- // are "stale." As these samples get released, we'll dispose of them.
- //
- // Note: The token counter is required because the samples are shared
- // between more than one thread, and they are returned to the presenter
- // through an asynchronous callback (onSampleFree). Without the token, we
- // might accidentally re-use a stale sample after the ReleaseResources
- // method returns.
-
- m_tokenCounter++;
-
- flush();
-
- m_samplePool.clear();
-
- m_presentEngine->releaseResources();
-}
-
-HRESULT EVRCustomPresenter::onSampleFree(IMFAsyncResult *result)
-{
- IUnknown *object = NULL;
- IMFSample *sample = NULL;
- IUnknown *unk = NULL;
- UINT32 token;
-
- // Get the sample from the async result object.
- HRESULT hr = result->GetObject(&object);
- if (FAILED(hr))
- goto done;
-
- hr = object->QueryInterface(IID_PPV_ARGS(&sample));
- if (FAILED(hr))
- goto done;
-
- // If this sample was submitted for a frame-step, the frame step operation
- // is complete.
-
- if (m_frameStep.state == FrameStepScheduled) {
- // Query the sample for IUnknown and compare it to our cached value.
- hr = sample->QueryInterface(IID_PPV_ARGS(&unk));
- if (FAILED(hr))
- goto done;
-
- if (m_frameStep.sampleNoRef == reinterpret_cast<DWORD_PTR>(unk)) {
- // Notify the EVR.
- hr = completeFrameStep(sample);
- if (FAILED(hr))
- goto done;
- }
-
- // Note: Although object is also an IUnknown pointer, it is not
- // guaranteed to be the exact pointer value returned through
- // QueryInterface. Therefore, the second QueryInterface call is
- // required.
- }
-
- m_mutex.lock();
-
- token = MFGetAttributeUINT32(sample, MFSamplePresenter_SampleCounter, (UINT32)-1);
-
- if (token == m_tokenCounter) {
- // Return the sample to the sample pool.
- hr = m_samplePool.returnSample(sample);
- if (SUCCEEDED(hr)) {
- // A free sample is available. Process more data if possible.
- processOutputLoop();
- }
- }
-
- m_mutex.unlock();
-
-done:
- if (FAILED(hr))
- notifyEvent(EC_ERRORABORT, hr, 0);
- qt_evr_safe_release(&object);
- qt_evr_safe_release(&sample);
- qt_evr_safe_release(&unk);
- return hr;
-}
-
-float EVRCustomPresenter::getMaxRate(bool thin)
-{
- // Non-thinned:
- // If we have a valid frame rate and a monitor refresh rate, the maximum
- // playback rate is equal to the refresh rate. Otherwise, the maximum rate
- // is unbounded (FLT_MAX).
-
- // Thinned: The maximum rate is unbounded.
-
- float maxRate = FLT_MAX;
- MFRatio fps = { 0, 0 };
- UINT monitorRateHz = 0;
-
- if (!thin && m_mediaType) {
- qt_evr_getFrameRate(m_mediaType, &fps);
- monitorRateHz = m_presentEngine->refreshRate();
-
- if (fps.Denominator && fps.Numerator && monitorRateHz) {
- // Max Rate = Refresh Rate / Frame Rate
- maxRate = (float)MulDiv(monitorRateHz, fps.Denominator, fps.Numerator);
- }
- }
-
- return maxRate;
-}
-
-bool EVRCustomPresenter::event(QEvent *e)
-{
- switch (int(e->type())) {
- case StartSurface:
- startSurface();
- return true;
- case StopSurface:
- stopSurface();
- return true;
- case PresentSample:
- presentSample(static_cast<PresentSampleEvent *>(e)->sample());
- return true;
- default:
- break;
- }
- return QObject::event(e);
-}
-
-void EVRCustomPresenter::startSurface()
-{
- if (thread() != QThread::currentThread()) {
- QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StartSurface)));
- return;
- }
-
- if (!m_surface || m_surface->isActive())
- return;
-
- QVideoSurfaceFormat format = m_presentEngine->videoSurfaceFormat();
- if (!format.isValid())
- return;
-
- m_surface->start(format);
-}
-
-void EVRCustomPresenter::stopSurface()
-{
- if (thread() != QThread::currentThread()) {
- QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StopSurface)));
- return;
- }
-
- if (!m_surface || !m_surface->isActive())
- return;
-
- m_surface->stop();
-}
-
-void EVRCustomPresenter::presentSample(IMFSample *sample)
-{
- if (thread() != QThread::currentThread()) {
- QCoreApplication::postEvent(this, new PresentSampleEvent(sample));
- return;
- }
-
- if (!m_surface || !m_presentEngine->videoSurfaceFormat().isValid())
- return;
-
- QVideoFrame frame = m_presentEngine->makeVideoFrame(sample);
-
- // Since start/end times are related to a position when the clock is started,
- // to have times from the beginning, need to adjust it by adding seeked position.
- if (m_positionOffset) {
- if (frame.startTime())
- frame.setStartTime(frame.startTime() + m_positionOffset);
- if (frame.endTime())
- frame.setEndTime(frame.endTime() + m_positionOffset);
- }
-
- if (!m_surface->isActive() || m_surface->surfaceFormat() != m_presentEngine->videoSurfaceFormat()) {
- m_surface->stop();
- if (!m_surface->start(m_presentEngine->videoSurfaceFormat()))
- return;
- }
-
- m_surface->present(frame);
-}
-
-void EVRCustomPresenter::positionChanged(qint64 position)
-{
- m_positionOffset = position * 1000;
-}
-
-HRESULT setDesiredSampleTime(IMFSample *sample, const LONGLONG &sampleTime, const LONGLONG &duration)
-{
- if (!sample)
- return E_POINTER;
-
- HRESULT hr = S_OK;
- IMFDesiredSample *desired = NULL;
-
- hr = sample->QueryInterface(IID_PPV_ARGS(&desired));
- if (SUCCEEDED(hr))
- desired->SetDesiredSampleTimeAndDuration(sampleTime, duration);
-
- qt_evr_safe_release(&desired);
- return hr;
-}
-
-HRESULT clearDesiredSampleTime(IMFSample *sample)
-{
- if (!sample)
- return E_POINTER;
-
- HRESULT hr = S_OK;
-
- IMFDesiredSample *desired = NULL;
- IUnknown *unkSwapChain = NULL;
-
- // We store some custom attributes on the sample, so we need to cache them
- // and reset them.
- //
- // This works around the fact that IMFDesiredSample::Clear() removes all of the
- // attributes from the sample.
-
- UINT32 counter = MFGetAttributeUINT32(sample, MFSamplePresenter_SampleCounter, (UINT32)-1);
-
- hr = sample->QueryInterface(IID_PPV_ARGS(&desired));
- if (SUCCEEDED(hr)) {
- desired->Clear();
-
- hr = sample->SetUINT32(MFSamplePresenter_SampleCounter, counter);
- if (FAILED(hr))
- goto done;
- }
-
-done:
- qt_evr_safe_release(&unkSwapChain);
- qt_evr_safe_release(&desired);
- return hr;
-}
-
-HRESULT setMixerSourceRect(IMFTransform *mixer, const MFVideoNormalizedRect &sourceRect)
-{
- if (!mixer)
- return E_POINTER;
-
- IMFAttributes *attributes = NULL;
-
- HRESULT hr = mixer->GetAttributes(&attributes);
- if (SUCCEEDED(hr)) {
- hr = attributes->SetBlob(video_ZOOM_RECT, reinterpret_cast<const UINT8*>(&sourceRect),
- sizeof(sourceRect));
- attributes->Release();
- }
- return hr;
-}
-
-static QVideoFrame::PixelFormat pixelFormatFromMediaType(IMFMediaType *type)
-{
- GUID majorType;
- if (FAILED(type->GetMajorType(&majorType)))
- return QVideoFrame::Format_Invalid;
- if (majorType != MFMediaType_Video)
- return QVideoFrame::Format_Invalid;
-
- GUID subtype;
- if (FAILED(type->GetGUID(MF_MT_SUBTYPE, &subtype)))
- return QVideoFrame::Format_Invalid;
-
- if (subtype == MFVideoFormat_RGB32)
- return QVideoFrame::Format_RGB32;
- if (subtype == MFVideoFormat_ARGB32)
- return QVideoFrame::Format_ARGB32;
- if (subtype == MFVideoFormat_RGB24)
- return QVideoFrame::Format_RGB24;
- if (subtype == MFVideoFormat_RGB565)
- return QVideoFrame::Format_RGB565;
- if (subtype == MFVideoFormat_RGB555)
- return QVideoFrame::Format_RGB555;
- if (subtype == MFVideoFormat_AYUV)
- return QVideoFrame::Format_AYUV444;
- if (subtype == MFVideoFormat_I420)
- return QVideoFrame::Format_YUV420P;
- if (subtype == MFVideoFormat_UYVY)
- return QVideoFrame::Format_UYVY;
- if (subtype == MFVideoFormat_YV12)
- return QVideoFrame::Format_YV12;
- if (subtype == MFVideoFormat_NV12)
- return QVideoFrame::Format_NV12;
-
- return QVideoFrame::Format_Invalid;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/common/evr/evrcustompresenter.h b/src/plugins/common/evr/evrcustompresenter.h
deleted file mode 100644
index c1c21580e..000000000
--- a/src/plugins/common/evr/evrcustompresenter.h
+++ /dev/null
@@ -1,377 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#ifndef EVRCUSTOMPRESENTER_H
-#define EVRCUSTOMPRESENTER_H
-
-#include <QObject>
-#include <qmutex.h>
-#include <qqueue.h>
-#include <qevent.h>
-#include <qvideosurfaceformat.h>
-
-#include "evrdefs.h"
-
-QT_BEGIN_NAMESPACE
-
-class EVRCustomPresenter;
-class D3DPresentEngine;
-
-class QAbstractVideoSurface;
-
-template<class T>
-class AsyncCallback : public IMFAsyncCallback
-{
- Q_DISABLE_COPY(AsyncCallback)
-public:
- typedef HRESULT (T::*InvokeFn)(IMFAsyncResult *asyncResult);
-
- AsyncCallback(T *parent, InvokeFn fn) : m_parent(parent), m_invokeFn(fn)
- {
- }
-
- // IUnknown
- STDMETHODIMP QueryInterface(REFIID iid, void** ppv) override
- {
- if (!ppv)
- return E_POINTER;
-
- if (iid == __uuidof(IUnknown)) {
- *ppv = static_cast<IUnknown*>(static_cast<IMFAsyncCallback*>(this));
- } else if (iid == __uuidof(IMFAsyncCallback)) {
- *ppv = static_cast<IMFAsyncCallback*>(this);
- } else {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
- }
-
- STDMETHODIMP_(ULONG) AddRef() override {
- // Delegate to parent class.
- return m_parent->AddRef();
- }
- STDMETHODIMP_(ULONG) Release() override {
- // Delegate to parent class.
- return m_parent->Release();
- }
-
- // IMFAsyncCallback methods
- STDMETHODIMP GetParameters(DWORD*, DWORD*) override
- {
- // Implementation of this method is optional.
- return E_NOTIMPL;
- }
-
- STDMETHODIMP Invoke(IMFAsyncResult* asyncResult) override
- {
- return (m_parent->*m_invokeFn)(asyncResult);
- }
-
- T *m_parent;
- InvokeFn m_invokeFn;
-};
-
-class Scheduler
-{
- Q_DISABLE_COPY(Scheduler)
-public:
- enum ScheduleEvent
- {
- Terminate = WM_USER,
- Schedule = WM_USER + 1,
- Flush = WM_USER + 2
- };
-
- Scheduler(EVRCustomPresenter *presenter);
- ~Scheduler();
-
- void setFrameRate(const MFRatio &fps);
- void setClockRate(float rate) { m_playbackRate = rate; }
-
- const LONGLONG &lastSampleTime() const { return m_lastSampleTime; }
- const LONGLONG &frameDuration() const { return m_perFrameInterval; }
-
- HRESULT startScheduler(IMFClock *clock);
- HRESULT stopScheduler();
-
- HRESULT scheduleSample(IMFSample *sample, bool presentNow);
- HRESULT processSamplesInQueue(LONG *nextSleep);
- HRESULT processSample(IMFSample *sample, LONG *nextSleep);
- HRESULT flush();
-
- bool areSamplesScheduled();
-
- // ThreadProc for the scheduler thread.
- static DWORD WINAPI schedulerThreadProc(LPVOID parameter);
-
-private:
- DWORD schedulerThreadProcPrivate();
-
- EVRCustomPresenter *m_presenter;
-
- QQueue<IMFSample*> m_scheduledSamples; // Samples waiting to be presented.
-
- IMFClock *m_clock; // Presentation clock. Can be NULL.
-
- DWORD m_threadID;
- HANDLE m_schedulerThread;
- HANDLE m_threadReadyEvent;
- HANDLE m_flushEvent;
-
- float m_playbackRate;
- MFTIME m_perFrameInterval; // Duration of each frame.
- LONGLONG m_perFrame_1_4th; // 1/4th of the frame duration.
- MFTIME m_lastSampleTime; // Most recent sample time.
-
- QMutex m_mutex;
-};
-
-class SamplePool
-{
- Q_DISABLE_COPY(SamplePool)
-public:
- SamplePool();
- ~SamplePool();
-
- HRESULT initialize(QList<IMFSample*> &samples);
- HRESULT clear();
-
- HRESULT getSample(IMFSample **sample);
- HRESULT returnSample(IMFSample *sample);
-
-private:
- QMutex m_mutex;
- QList<IMFSample*> m_videoSampleQueue;
- bool m_initialized;
-};
-
-class EVRCustomPresenter
- : public QObject
- , public IMFVideoDeviceID
- , public IMFVideoPresenter // Inherits IMFClockStateSink
- , public IMFRateSupport
- , public IMFGetService
- , public IMFTopologyServiceLookupClient
-{
- Q_DISABLE_COPY(EVRCustomPresenter)
-public:
- // Defines the state of the presenter.
- enum RenderState
- {
- RenderStarted = 1,
- RenderStopped,
- RenderPaused,
- RenderShutdown // Initial state.
- };
-
- // Defines the presenter's state with respect to frame-stepping.
- enum FrameStepState
- {
- FrameStepNone, // Not frame stepping.
- FrameStepWaitingStart, // Frame stepping, but the clock is not started.
- FrameStepPending, // Clock is started. Waiting for samples.
- FrameStepScheduled, // Submitted a sample for rendering.
- FrameStepComplete // Sample was rendered.
- };
-
- enum PresenterEvents
- {
- StartSurface = QEvent::User,
- StopSurface = QEvent::User + 1,
- PresentSample = QEvent::User + 2
- };
-
- EVRCustomPresenter(QAbstractVideoSurface *surface = 0);
- ~EVRCustomPresenter() override;
-
- bool isValid() const;
-
- // IUnknown methods
- STDMETHODIMP QueryInterface(REFIID riid, void ** ppv) override;
- STDMETHODIMP_(ULONG) AddRef() override;
- STDMETHODIMP_(ULONG) Release() override;
-
- // IMFGetService methods
- STDMETHODIMP GetService(REFGUID guidService, REFIID riid, LPVOID *ppvObject) override;
-
- // IMFVideoPresenter methods
- STDMETHODIMP ProcessMessage(MFVP_MESSAGE_TYPE message, ULONG_PTR param) override;
- STDMETHODIMP GetCurrentMediaType(IMFVideoMediaType** mediaType) override;
-
- // IMFClockStateSink methods
- STDMETHODIMP OnClockStart(MFTIME systemTime, LONGLONG clockStartOffset) override;
- STDMETHODIMP OnClockStop(MFTIME systemTime) override;
- STDMETHODIMP OnClockPause(MFTIME systemTime) override;
- STDMETHODIMP OnClockRestart(MFTIME systemTime) override;
- STDMETHODIMP OnClockSetRate(MFTIME systemTime, float rate) override;
-
- // IMFRateSupport methods
- STDMETHODIMP GetSlowestRate(MFRATE_DIRECTION direction, BOOL thin, float *rate) override;
- STDMETHODIMP GetFastestRate(MFRATE_DIRECTION direction, BOOL thin, float *rate) override;
- STDMETHODIMP IsRateSupported(BOOL thin, float rate, float *nearestSupportedRate) override;
-
- // IMFVideoDeviceID methods
- STDMETHODIMP GetDeviceID(IID* deviceID) override;
-
- // IMFTopologyServiceLookupClient methods
- STDMETHODIMP InitServicePointers(IMFTopologyServiceLookup *lookup) override;
- STDMETHODIMP ReleaseServicePointers() override;
-
- void supportedFormatsChanged();
- void setSurface(QAbstractVideoSurface *surface);
-
- void startSurface();
- void stopSurface();
- void presentSample(IMFSample *sample);
-
- bool event(QEvent *) override;
-
-public Q_SLOTS:
- void positionChanged(qint64 position);
-
-private:
- HRESULT checkShutdown() const
- {
- if (m_renderState == RenderShutdown)
- return MF_E_SHUTDOWN;
- else
- return S_OK;
- }
-
- // The "active" state is started or paused.
- inline bool isActive() const
- {
- return ((m_renderState == RenderStarted) || (m_renderState == RenderPaused));
- }
-
- // Scrubbing occurs when the frame rate is 0.
- inline bool isScrubbing() const { return m_playbackRate == 0.0f; }
-
- // Send an event to the EVR through its IMediaEventSink interface.
- void notifyEvent(long eventCode, LONG_PTR param1, LONG_PTR param2)
- {
- if (m_mediaEventSink)
- m_mediaEventSink->Notify(eventCode, param1, param2);
- }
-
- float getMaxRate(bool thin);
-
- // Mixer operations
- HRESULT configureMixer(IMFTransform *mixer);
-
- // Formats
- HRESULT createOptimalVideoType(IMFMediaType* proposed, IMFMediaType **optimal);
- HRESULT setMediaType(IMFMediaType *mediaType);
- HRESULT isMediaTypeSupported(IMFMediaType *mediaType);
-
- // Message handlers
- HRESULT flush();
- HRESULT renegotiateMediaType();
- HRESULT processInputNotify();
- HRESULT beginStreaming();
- HRESULT endStreaming();
- HRESULT checkEndOfStream();
-
- // Managing samples
- void processOutputLoop();
- HRESULT processOutput();
- HRESULT deliverSample(IMFSample *sample, bool repaint);
- HRESULT trackSample(IMFSample *sample);
- void releaseResources();
-
- // Frame-stepping
- HRESULT prepareFrameStep(DWORD steps);
- HRESULT startFrameStep();
- HRESULT deliverFrameStepSample(IMFSample *sample);
- HRESULT completeFrameStep(IMFSample *sample);
- HRESULT cancelFrameStep();
-
- // Callback when a video sample is released.
- HRESULT onSampleFree(IMFAsyncResult *result);
- AsyncCallback<EVRCustomPresenter> m_sampleFreeCB;
-
- // Holds information related to frame-stepping.
- struct FrameStep
- {
- FrameStepState state = FrameStepNone;
- QList<IMFSample*> samples;
- DWORD steps = 0;
- DWORD_PTR sampleNoRef = 0;
- };
-
- long m_refCount;
-
- RenderState m_renderState;
- FrameStep m_frameStep;
-
- QRecursiveMutex m_mutex;
-
- // Samples and scheduling
- Scheduler m_scheduler; // Manages scheduling of samples.
- SamplePool m_samplePool; // Pool of allocated samples.
- DWORD m_tokenCounter; // Counter. Incremented whenever we create new samples.
-
- // Rendering state
- bool m_sampleNotify; // Did the mixer signal it has an input sample?
- bool m_repaint; // Do we need to repaint the last sample?
- bool m_prerolled; // Have we presented at least one sample?
- bool m_endStreaming; // Did we reach the end of the stream (EOS)?
-
- MFVideoNormalizedRect m_sourceRect;
- float m_playbackRate;
-
- D3DPresentEngine *m_presentEngine; // Rendering engine. (Never null if the constructor succeeds.)
-
- IMFClock *m_clock; // The EVR's clock.
- IMFTransform *m_mixer; // The EVR's mixer.
- IMediaEventSink *m_mediaEventSink; // The EVR's event-sink interface.
- IMFMediaType *m_mediaType; // Output media type
-
- QAbstractVideoSurface *m_surface;
- bool m_canRenderToSurface;
- qint64 m_positionOffset; // Seek position in microseconds.
-};
-
-bool qt_evr_setCustomPresenter(IUnknown *evr, EVRCustomPresenter *presenter);
-
-QT_END_NAMESPACE
-
-#endif // EVRCUSTOMPRESENTER_H
diff --git a/src/plugins/common/evr/evrd3dpresentengine.cpp b/src/plugins/common/evr/evrd3dpresentengine.cpp
deleted file mode 100644
index 964504e48..000000000
--- a/src/plugins/common/evr/evrd3dpresentengine.cpp
+++ /dev/null
@@ -1,413 +0,0 @@
-/****************************************************************************
-**
-** 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 "evrd3dpresentengine.h"
-
-#include "evrhelpers.h"
-
-#include <qabstractvideobuffer.h>
-#include <QAbstractVideoSurface>
-#include <qvideoframe.h>
-#include <QDebug>
-#include <qthread.h>
-#include <QOffscreenSurface>
-
-static const int PRESENTER_BUFFER_COUNT = 3;
-
-QT_BEGIN_NAMESPACE
-
-class IMFSampleVideoBuffer: public QAbstractVideoBuffer
-{
-public:
- IMFSampleVideoBuffer(D3DPresentEngine *engine, IMFSample *sample, QAbstractVideoBuffer::HandleType handleType)
- : QAbstractVideoBuffer(handleType)
- , m_engine(engine)
- , m_sample(sample)
- , m_surface(0)
- , m_mapMode(NotMapped)
- {
- if (m_sample) {
- m_sample->AddRef();
-
- IMFMediaBuffer *buffer;
- if (SUCCEEDED(m_sample->GetBufferByIndex(0, &buffer))) {
- MFGetService(buffer,
- mr_BUFFER_SERVICE,
- iid_IDirect3DSurface9,
- reinterpret_cast<void **>(&m_surface));
- buffer->Release();
- }
- }
- }
-
- ~IMFSampleVideoBuffer() override
- {
- if (m_surface) {
- if (m_mapMode != NotMapped)
- m_surface->UnlockRect();
- m_surface->Release();
- }
- if (m_sample)
- m_sample->Release();
- }
-
- QVariant handle() const override;
-
- MapMode mapMode() const override { return m_mapMode; }
- uchar *map(MapMode, int*, int*) override;
- void unmap() override;
-
-private:
- mutable D3DPresentEngine *m_engine;
- IMFSample *m_sample;
- IDirect3DSurface9 *m_surface;
- MapMode m_mapMode;
- mutable unsigned int m_textureId = 0;
-};
-
-uchar *IMFSampleVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine)
-{
- if (!m_surface || m_mapMode != NotMapped)
- return 0;
-
- D3DSURFACE_DESC desc;
- if (FAILED(m_surface->GetDesc(&desc)))
- return 0;
-
- D3DLOCKED_RECT rect;
- if (FAILED(m_surface->LockRect(&rect, NULL, mode == ReadOnly ? D3DLOCK_READONLY : 0)))
- return 0;
-
- m_mapMode = mode;
-
- if (numBytes)
- *numBytes = (int)(rect.Pitch * desc.Height);
-
- if (bytesPerLine)
- *bytesPerLine = (int)rect.Pitch;
-
- return reinterpret_cast<uchar *>(rect.pBits);
-}
-
-void IMFSampleVideoBuffer::unmap()
-{
- if (m_mapMode == NotMapped)
- return;
-
- m_mapMode = NotMapped;
- m_surface->UnlockRect();
-}
-
-QVariant IMFSampleVideoBuffer::handle() const
-{
- return m_textureId;
-}
-
-
-D3DPresentEngine::D3DPresentEngine()
- : m_deviceResetToken(0)
- , m_D3D9(0)
- , m_device(0)
- , m_deviceManager(0)
- , m_useTextureRendering(false)
-{
- ZeroMemory(&m_displayMode, sizeof(m_displayMode));
-
- HRESULT hr = initializeD3D();
-
- if (SUCCEEDED(hr)) {
- hr = createD3DDevice();
- if (FAILED(hr))
- qWarning("Failed to create D3D device");
- } else {
- qWarning("Failed to initialize D3D");
- }
-}
-
-D3DPresentEngine::~D3DPresentEngine()
-{
- releaseResources();
-
- qt_evr_safe_release(&m_device);
- qt_evr_safe_release(&m_deviceManager);
- qt_evr_safe_release(&m_D3D9);
-}
-
-HRESULT D3DPresentEngine::initializeD3D()
-{
- HRESULT hr = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_D3D9);
-
- if (SUCCEEDED(hr))
- hr = DXVA2CreateDirect3DDeviceManager9(&m_deviceResetToken, &m_deviceManager);
-
- return hr;
-}
-
-HRESULT D3DPresentEngine::createD3DDevice()
-{
- HRESULT hr = S_OK;
- HWND hwnd = NULL;
- UINT uAdapterID = D3DADAPTER_DEFAULT;
- DWORD vp = 0;
-
- D3DCAPS9 ddCaps;
- ZeroMemory(&ddCaps, sizeof(ddCaps));
-
- IDirect3DDevice9Ex* device = NULL;
-
- if (!m_D3D9 || !m_deviceManager)
- return MF_E_NOT_INITIALIZED;
-
- hwnd = ::GetShellWindow();
-
- D3DPRESENT_PARAMETERS pp;
- ZeroMemory(&pp, sizeof(pp));
-
- pp.BackBufferWidth = 1;
- pp.BackBufferHeight = 1;
- pp.BackBufferFormat = D3DFMT_UNKNOWN;
- pp.BackBufferCount = 1;
- pp.Windowed = TRUE;
- pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
- pp.BackBufferFormat = D3DFMT_UNKNOWN;
- pp.hDeviceWindow = hwnd;
- pp.Flags = D3DPRESENTFLAG_VIDEO;
- pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
-
- hr = m_D3D9->GetDeviceCaps(uAdapterID, D3DDEVTYPE_HAL, &ddCaps);
- if (FAILED(hr))
- goto done;
-
- if (ddCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
- vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
- else
- vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
-
- hr = m_D3D9->CreateDeviceEx(
- uAdapterID,
- D3DDEVTYPE_HAL,
- pp.hDeviceWindow,
- vp | D3DCREATE_NOWINDOWCHANGES | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE,
- &pp,
- NULL,
- &device
- );
- if (FAILED(hr))
- goto done;
-
- hr = m_D3D9->GetAdapterDisplayMode(uAdapterID, &m_displayMode);
- if (FAILED(hr))
- goto done;
-
- hr = m_deviceManager->ResetDevice(device, m_deviceResetToken);
- if (FAILED(hr))
- goto done;
-
- qt_evr_safe_release(&m_device);
-
- m_device = device;
- m_device->AddRef();
-
-done:
- qt_evr_safe_release(&device);
- return hr;
-}
-
-bool D3DPresentEngine::isValid() const
-{
- return m_device != NULL;
-}
-
-void D3DPresentEngine::releaseResources()
-{
- m_surfaceFormat = QVideoSurfaceFormat();
-}
-
-HRESULT D3DPresentEngine::getService(REFGUID, REFIID riid, void** ppv)
-{
- HRESULT hr = S_OK;
-
- if (riid == __uuidof(IDirect3DDeviceManager9)) {
- if (m_deviceManager == NULL) {
- hr = MF_E_UNSUPPORTED_SERVICE;
- } else {
- *ppv = m_deviceManager;
- m_deviceManager->AddRef();
- }
- } else {
- hr = MF_E_UNSUPPORTED_SERVICE;
- }
-
- return hr;
-}
-
-HRESULT D3DPresentEngine::checkFormat(D3DFORMAT format)
-{
- if (!m_D3D9 || !m_device)
- return E_FAIL;
-
- HRESULT hr = S_OK;
-
- D3DDISPLAYMODE mode;
- D3DDEVICE_CREATION_PARAMETERS params;
-
- hr = m_device->GetCreationParameters(&params);
- if (FAILED(hr))
- return hr;
-
- UINT uAdapter = params.AdapterOrdinal;
- D3DDEVTYPE type = params.DeviceType;
-
- hr = m_D3D9->GetAdapterDisplayMode(uAdapter, &mode);
- if (FAILED(hr))
- return hr;
-
- hr = m_D3D9->CheckDeviceFormat(uAdapter, type, mode.Format,
- D3DUSAGE_RENDERTARGET,
- D3DRTYPE_SURFACE,
- format);
-
- if (m_useTextureRendering && format != D3DFMT_X8R8G8B8 && format != D3DFMT_A8R8G8B8) {
- // The texture is always in RGB32 so the d3d driver must support conversion from the
- // requested format to RGB32.
- hr = m_D3D9->CheckDeviceFormatConversion(uAdapter, type, format, D3DFMT_X8R8G8B8);
- }
-
- return hr;
-}
-
-bool D3DPresentEngine::supportsTextureRendering() const
-{
- return false;
-}
-
-void D3DPresentEngine::setHint(Hint hint, bool enable)
-{
- if (hint == RenderToTexture)
- m_useTextureRendering = enable && supportsTextureRendering();
-}
-
-HRESULT D3DPresentEngine::createVideoSamples(IMFMediaType *format, QList<IMFSample*> &videoSampleQueue)
-{
- if (!format)
- return MF_E_UNEXPECTED;
-
- HRESULT hr = S_OK;
-
- IDirect3DSurface9 *surface = NULL;
- IMFSample *videoSample = NULL;
-
- releaseResources();
-
- UINT32 width = 0, height = 0;
- hr = MFGetAttributeSize(format, MF_MT_FRAME_SIZE, &width, &height);
- if (FAILED(hr))
- return hr;
-
- DWORD d3dFormat = 0;
- hr = qt_evr_getFourCC(format, &d3dFormat);
- if (FAILED(hr))
- return hr;
-
- // Create the video samples.
- for (int i = 0; i < PRESENTER_BUFFER_COUNT; i++) {
- hr = m_device->CreateRenderTarget(width, height,
- (D3DFORMAT)d3dFormat,
- D3DMULTISAMPLE_NONE,
- 0,
- TRUE,
- &surface, NULL);
- if (FAILED(hr))
- goto done;
-
- hr = MFCreateVideoSampleFromSurface(surface, &videoSample);
- if (FAILED(hr))
- goto done;
-
- videoSample->AddRef();
- videoSampleQueue.append(videoSample);
-
- qt_evr_safe_release(&videoSample);
- qt_evr_safe_release(&surface);
- }
-
-done:
- if (SUCCEEDED(hr)) {
- m_surfaceFormat = QVideoSurfaceFormat(QSize(width, height),
- m_useTextureRendering ? QVideoFrame::Format_RGB32
- : qt_evr_pixelFormatFromD3DFormat(d3dFormat),
- m_useTextureRendering ? QAbstractVideoBuffer::GLTextureHandle
- : QAbstractVideoBuffer::NoHandle);
- UINT32 horizontal = 1, vertical = 1;
- hr = MFGetAttributeRatio(format, MF_MT_PIXEL_ASPECT_RATIO, &horizontal, &vertical);
- if (SUCCEEDED(hr))
- m_surfaceFormat.setPixelAspectRatio(horizontal, vertical);
- } else {
- releaseResources();
- }
-
- qt_evr_safe_release(&videoSample);
- qt_evr_safe_release(&surface);
- return hr;
-}
-
-QVideoFrame D3DPresentEngine::makeVideoFrame(IMFSample *sample)
-{
- if (!sample)
- return QVideoFrame();
-
- QVideoFrame frame(new IMFSampleVideoBuffer(this, sample, m_surfaceFormat.handleType()),
- m_surfaceFormat.frameSize(),
- m_surfaceFormat.pixelFormat());
-
- // WMF uses 100-nanosecond units, Qt uses microseconds
- LONGLONG startTime = 0;
- auto hr = sample->GetSampleTime(&startTime);
- if (SUCCEEDED(hr)) {
- frame.setStartTime(startTime * 0.1);
-
- LONGLONG duration = -1;
- if (SUCCEEDED(sample->GetSampleDuration(&duration)))
- frame.setEndTime((startTime + duration) * 0.1);
- }
-
- return frame;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/common/evr/evrd3dpresentengine.h b/src/plugins/common/evr/evrd3dpresentengine.h
deleted file mode 100644
index eb2def7b2..000000000
--- a/src/plugins/common/evr/evrd3dpresentengine.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#ifndef EVRD3DPRESENTENGINE_H
-#define EVRD3DPRESENTENGINE_H
-
-#include <QMutex>
-#include <QVideoSurfaceFormat>
-
-#include <d3d9.h>
-
-struct IDirect3D9Ex;
-struct IDirect3DDevice9Ex;
-struct IDirect3DDeviceManager9;
-struct IDirect3DSurface9;
-struct IDirect3DTexture9;
-struct IMFSample;
-struct IMFMediaType;
-
-// Randomly generated GUIDs
-static const GUID MFSamplePresenter_SampleCounter =
-{ 0xb0bb83cc, 0xf10f, 0x4e2e, { 0xaa, 0x2b, 0x29, 0xea, 0x5e, 0x92, 0xef, 0x85 } };
-
-QT_BEGIN_NAMESPACE
-
-class QAbstractVideoSurface;
-
-#ifdef MAYBE_ANGLE
-
-class OpenGLResources;
-
-class EGLWrapper
-{
- Q_DISABLE_COPY(EGLWrapper)
-public:
- EGLWrapper();
-
- __eglMustCastToProperFunctionPointerType getProcAddress(const char *procname);
- EGLSurface createPbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
- EGLBoolean destroySurface(EGLDisplay dpy, EGLSurface surface);
- EGLBoolean bindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
- EGLBoolean releaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
-
-private:
- typedef __eglMustCastToProperFunctionPointerType (EGLAPIENTRYP EglGetProcAddress)(const char *procname);
- typedef EGLSurface (EGLAPIENTRYP EglCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
- typedef EGLBoolean (EGLAPIENTRYP EglDestroySurface)(EGLDisplay dpy, EGLSurface surface);
- typedef EGLBoolean (EGLAPIENTRYP EglBindTexImage)(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
- typedef EGLBoolean (EGLAPIENTRYP EglReleaseTexImage)(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
-
- EglGetProcAddress m_eglGetProcAddress;
- EglCreatePbufferSurface m_eglCreatePbufferSurface;
- EglDestroySurface m_eglDestroySurface;
- EglBindTexImage m_eglBindTexImage;
- EglReleaseTexImage m_eglReleaseTexImage;
-};
-
-#endif // MAYBE_ANGLE
-
-class D3DPresentEngine
-{
- Q_DISABLE_COPY(D3DPresentEngine)
-public:
- enum Hint
- {
- RenderToTexture
- };
-
- D3DPresentEngine();
- virtual ~D3DPresentEngine();
-
- bool isValid() const;
- void setHint(Hint hint, bool enable = true);
-
- HRESULT getService(REFGUID guidService, REFIID riid, void** ppv);
- HRESULT checkFormat(D3DFORMAT format);
- UINT refreshRate() const { return m_displayMode.RefreshRate; }
-
- bool supportsTextureRendering() const;
- bool isTextureRenderingEnabled() const { return m_useTextureRendering; }
-
- HRESULT createVideoSamples(IMFMediaType *format, QList<IMFSample*>& videoSampleQueue);
- QVideoSurfaceFormat videoSurfaceFormat() const { return m_surfaceFormat; }
- QVideoFrame makeVideoFrame(IMFSample* sample);
-
- void releaseResources();
-
-private:
- HRESULT initializeD3D();
- HRESULT createD3DDevice();
-
-
- UINT m_deviceResetToken;
- D3DDISPLAYMODE m_displayMode;
-
- IDirect3D9Ex *m_D3D9;
- IDirect3DDevice9Ex *m_device;
- IDirect3DDeviceManager9 *m_deviceManager;
-
- QVideoSurfaceFormat m_surfaceFormat;
-
- bool m_useTextureRendering;
-
-#ifdef MAYBE_ANGLE
- unsigned int updateTexture(IDirect3DSurface9 *src);
-
- OpenGLResources *m_glResources;
- IDirect3DTexture9 *m_texture;
-#endif
-
- friend class IMFSampleVideoBuffer;
-};
-
-QT_END_NAMESPACE
-
-#endif // EVRD3DPRESENTENGINE_H
diff --git a/src/plugins/common/evr/evrdefs.cpp b/src/plugins/common/evr/evrdefs.cpp
deleted file mode 100644
index e143ada0b..000000000
--- a/src/plugins/common/evr/evrdefs.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/****************************************************************************
-**
-** 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 "evrdefs.h"
-
-const CLSID clsid_EnhancedVideoRenderer = { 0xfa10746c, 0x9b63, 0x4b6c, {0xbc, 0x49, 0xfc, 0x30, 0xe, 0xa5, 0xf2, 0x56} };
-const GUID mr_VIDEO_RENDER_SERVICE = { 0x1092a86c, 0xab1a, 0x459a, {0xa3, 0x36, 0x83, 0x1f, 0xbc, 0x4d, 0x11, 0xff} };
-const GUID mr_VIDEO_MIXER_SERVICE = { 0x73cd2fc, 0x6cf4, 0x40b7, {0x88, 0x59, 0xe8, 0x95, 0x52, 0xc8, 0x41, 0xf8} };
-const GUID mr_BUFFER_SERVICE = { 0xa562248c, 0x9ac6, 0x4ffc, {0x9f, 0xba, 0x3a, 0xf8, 0xf8, 0xad, 0x1a, 0x4d} };
-const GUID video_ZOOM_RECT = { 0x7aaa1638, 0x1b7f, 0x4c93, {0xbd, 0x89, 0x5b, 0x9c, 0x9f, 0xb6, 0xfc, 0xf0} };
-const GUID iid_IDirect3DDevice9 = { 0xd0223b96, 0xbf7a, 0x43fd, {0x92, 0xbd, 0xa4, 0x3b, 0xd, 0x82, 0xb9, 0xeb} };
-const GUID iid_IDirect3DSurface9 = { 0xcfbaf3a, 0x9ff6, 0x429a, {0x99, 0xb3, 0xa2, 0x79, 0x6a, 0xf8, 0xb8, 0x9b} };
diff --git a/src/plugins/common/evr/evrdefs.h b/src/plugins/common/evr/evrdefs.h
deleted file mode 100644
index 4f3dd832a..000000000
--- a/src/plugins/common/evr/evrdefs.h
+++ /dev/null
@@ -1,353 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#ifndef EVRDEFS_H
-#define EVRDEFS_H
-
-#include <d3d9.h>
-#include <evr9.h>
-#include <evr.h>
-#include <dxva2api.h>
-#include <mfapi.h>
-#include <mfidl.h>
-#include <mferror.h>
-
-extern const CLSID clsid_EnhancedVideoRenderer;
-extern const GUID mr_VIDEO_RENDER_SERVICE;
-extern const GUID mr_VIDEO_MIXER_SERVICE;
-extern const GUID mr_BUFFER_SERVICE;
-extern const GUID video_ZOOM_RECT;
-extern const GUID iid_IDirect3DDevice9;
-extern const GUID iid_IDirect3DSurface9;
-
-// The following is required to compile with MinGW
-
-extern "C" {
-HRESULT WINAPI MFCreateVideoSampleFromSurface(IUnknown *pUnkSurface, IMFSample **ppSample);
-HRESULT WINAPI Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex**);
-}
-
-#ifndef PRESENTATION_CURRENT_POSITION
-#define PRESENTATION_CURRENT_POSITION 0x7fffffffffffffff
-#endif
-
-#ifndef MF_E_SHUTDOWN
-#define MF_E_SHUTDOWN ((HRESULT)0xC00D3E85L)
-#endif
-
-#ifndef MF_E_SAMPLEALLOCATOR_EMPTY
-#define MF_E_SAMPLEALLOCATOR_EMPTY ((HRESULT)0xC00D4A3EL)
-#endif
-
-#ifndef MF_E_TRANSFORM_STREAM_CHANGE
-#define MF_E_TRANSFORM_STREAM_CHANGE ((HRESULT)0xC00D6D61L)
-#endif
-
-#ifndef MF_E_TRANSFORM_NEED_MORE_INPUT
-#define MF_E_TRANSFORM_NEED_MORE_INPUT ((HRESULT)0xC00D6D72L)
-#endif
-
-#if defined(__GNUC__) && !defined(_MFVideoNormalizedRect_)
-#define _MFVideoNormalizedRect_
-typedef struct MFVideoNormalizedRect {
- float left;
- float top;
- float right;
- float bottom;
-} MFVideoNormalizedRect;
-#endif
-
-#include <initguid.h>
-
-#ifndef __IMFGetService_INTERFACE_DEFINED__
-#define __IMFGetService_INTERFACE_DEFINED__
-DEFINE_GUID(IID_IMFGetService, 0xfa993888, 0x4383, 0x415a, 0xa9,0x30, 0xdd,0x47,0x2a,0x8c,0xf6,0xf7);
-MIDL_INTERFACE("fa993888-4383-415a-a930-dd472a8cf6f7")
-IMFGetService : public IUnknown
-{
- virtual HRESULT STDMETHODCALLTYPE GetService(REFGUID, REFIID, LPVOID *) = 0;
-};
-#ifdef __CRT_UUID_DECL
-__CRT_UUID_DECL(IMFGetService, 0xfa993888, 0x4383, 0x415a, 0xa9,0x30, 0xdd,0x47,0x2a,0x8c,0xf6,0xf7)
-#endif
-#endif // __IMFGetService_INTERFACE_DEFINED__
-
-#ifndef __IMFVideoDisplayControl_INTERFACE_DEFINED__
-#define __IMFVideoDisplayControl_INTERFACE_DEFINED__
-typedef enum MFVideoAspectRatioMode
-{
- MFVideoARMode_None = 0,
- MFVideoARMode_PreservePicture = 0x1,
- MFVideoARMode_PreservePixel = 0x2,
- MFVideoARMode_NonLinearStretch = 0x4,
- MFVideoARMode_Mask = 0x7
-} MFVideoAspectRatioMode;
-
-DEFINE_GUID(IID_IMFVideoDisplayControl, 0xa490b1e4, 0xab84, 0x4d31, 0xa1,0xb2, 0x18,0x1e,0x03,0xb1,0x07,0x7a);
-MIDL_INTERFACE("a490b1e4-ab84-4d31-a1b2-181e03b1077a")
-IMFVideoDisplayControl : public IUnknown
-{
- virtual HRESULT STDMETHODCALLTYPE GetNativeVideoSize(SIZE *, SIZE *) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetIdealVideoSize(SIZE *, SIZE *) = 0;
- virtual HRESULT STDMETHODCALLTYPE SetVideoPosition(const MFVideoNormalizedRect *, const LPRECT) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetVideoPosition(MFVideoNormalizedRect *, LPRECT) = 0;
- virtual HRESULT STDMETHODCALLTYPE SetAspectRatioMode(DWORD) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetAspectRatioMode(DWORD *) = 0;
- virtual HRESULT STDMETHODCALLTYPE SetVideoWindow(HWND) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetVideoWindow(HWND *) = 0;
- virtual HRESULT STDMETHODCALLTYPE RepaintVideo(void) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetCurrentImage(BITMAPINFOHEADER *, BYTE **, DWORD *, LONGLONG *) = 0;
- virtual HRESULT STDMETHODCALLTYPE SetBorderColor(COLORREF) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetBorderColor(COLORREF *) = 0;
- virtual HRESULT STDMETHODCALLTYPE SetRenderingPrefs(DWORD) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetRenderingPrefs(DWORD *) = 0;
- virtual HRESULT STDMETHODCALLTYPE SetFullscreen(BOOL) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetFullscreen(BOOL *) = 0;
-};
-#ifdef __CRT_UUID_DECL
-__CRT_UUID_DECL(IMFVideoDisplayControl, 0xa490b1e4, 0xab84, 0x4d31, 0xa1,0xb2, 0x18,0x1e,0x03,0xb1,0x07,0x7a)
-#endif
-#endif // __IMFVideoDisplayControl_INTERFACE_DEFINED__
-
-#ifndef __IMFVideoProcessor_INTERFACE_DEFINED__
-#define __IMFVideoProcessor_INTERFACE_DEFINED__
-DEFINE_GUID(IID_IMFVideoProcessor, 0x6AB0000C, 0xFECE, 0x4d1f, 0xA2,0xAC, 0xA9,0x57,0x35,0x30,0x65,0x6E);
-MIDL_INTERFACE("6AB0000C-FECE-4d1f-A2AC-A9573530656E")
-IMFVideoProcessor : public IUnknown
-{
- virtual HRESULT STDMETHODCALLTYPE GetAvailableVideoProcessorModes(UINT *, GUID **) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetVideoProcessorCaps(LPGUID, DXVA2_VideoProcessorCaps *) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetVideoProcessorMode(LPGUID) = 0;
- virtual HRESULT STDMETHODCALLTYPE SetVideoProcessorMode(LPGUID) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetProcAmpRange(DWORD, DXVA2_ValueRange *) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetProcAmpValues(DWORD, DXVA2_ProcAmpValues *) = 0;
- virtual HRESULT STDMETHODCALLTYPE SetProcAmpValues(DWORD, DXVA2_ProcAmpValues *) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetFilteringRange(DWORD, DXVA2_ValueRange *) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetFilteringValue(DWORD, DXVA2_Fixed32 *) = 0;
- virtual HRESULT STDMETHODCALLTYPE SetFilteringValue(DWORD, DXVA2_Fixed32 *) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetBackgroundColor(COLORREF *) = 0;
- virtual HRESULT STDMETHODCALLTYPE SetBackgroundColor(COLORREF) = 0;
-};
-#ifdef __CRT_UUID_DECL
-__CRT_UUID_DECL(IMFVideoProcessor, 0x6AB0000C, 0xFECE, 0x4d1f, 0xA2,0xAC, 0xA9,0x57,0x35,0x30,0x65,0x6E)
-#endif
-#endif // __IMFVideoProcessor_INTERFACE_DEFINED__
-
-#ifndef __IMFVideoDeviceID_INTERFACE_DEFINED__
-#define __IMFVideoDeviceID_INTERFACE_DEFINED__
-DEFINE_GUID(IID_IMFVideoDeviceID, 0xA38D9567, 0x5A9C, 0x4f3c, 0xB2,0x93, 0x8E,0xB4,0x15,0xB2,0x79,0xBA);
-MIDL_INTERFACE("A38D9567-5A9C-4f3c-B293-8EB415B279BA")
-IMFVideoDeviceID : public IUnknown
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE GetDeviceID(IID *pDeviceID) = 0;
-};
-#ifdef __CRT_UUID_DECL
-__CRT_UUID_DECL(IMFVideoDeviceID, 0xA38D9567, 0x5A9C, 0x4f3c, 0xB2,0x93, 0x8E,0xB4,0x15,0xB2,0x79,0xBA)
-#endif
-#endif // __IMFVideoDeviceID_INTERFACE_DEFINED__
-
-#ifndef __IMFClockStateSink_INTERFACE_DEFINED__
-#define __IMFClockStateSink_INTERFACE_DEFINED__
-DEFINE_GUID(IID_IMFClockStateSink, 0xF6696E82, 0x74F7, 0x4f3d, 0xA1,0x78, 0x8A,0x5E,0x09,0xC3,0x65,0x9F);
-MIDL_INTERFACE("F6696E82-74F7-4f3d-A178-8A5E09C3659F")
-IMFClockStateSink : public IUnknown
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE OnClockStart(MFTIME hnsSystemTime, LONGLONG llClockStartOffset) = 0;
- virtual HRESULT STDMETHODCALLTYPE OnClockStop(MFTIME hnsSystemTime) = 0;
- virtual HRESULT STDMETHODCALLTYPE OnClockPause(MFTIME hnsSystemTime) = 0;
- virtual HRESULT STDMETHODCALLTYPE OnClockRestart(MFTIME hnsSystemTime) = 0;
- virtual HRESULT STDMETHODCALLTYPE OnClockSetRate(MFTIME hnsSystemTime, float flRate) = 0;
-};
-#ifdef __CRT_UUID_DECL
-__CRT_UUID_DECL(IMFClockStateSink, 0xF6696E82, 0x74F7, 0x4f3d, 0xA1,0x78, 0x8A,0x5E,0x09,0xC3,0x65,0x9F)
-#endif
-#endif // __IMFClockStateSink_INTERFACE_DEFINED__
-
-#ifndef __IMFVideoPresenter_INTERFACE_DEFINED__
-#define __IMFVideoPresenter_INTERFACE_DEFINED__
-typedef enum MFVP_MESSAGE_TYPE
-{
- MFVP_MESSAGE_FLUSH = 0,
- MFVP_MESSAGE_INVALIDATEMEDIATYPE = 0x1,
- MFVP_MESSAGE_PROCESSINPUTNOTIFY = 0x2,
- MFVP_MESSAGE_BEGINSTREAMING = 0x3,
- MFVP_MESSAGE_ENDSTREAMING = 0x4,
- MFVP_MESSAGE_ENDOFSTREAM = 0x5,
- MFVP_MESSAGE_STEP = 0x6,
- MFVP_MESSAGE_CANCELSTEP = 0x7
-} MFVP_MESSAGE_TYPE;
-
-DEFINE_GUID(IID_IMFVideoPresenter, 0x29AFF080, 0x182A, 0x4a5d, 0xAF,0x3B, 0x44,0x8F,0x3A,0x63,0x46,0xCB);
-MIDL_INTERFACE("29AFF080-182A-4a5d-AF3B-448F3A6346CB")
-IMFVideoPresenter : public IMFClockStateSink
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE ProcessMessage(MFVP_MESSAGE_TYPE eMessage, ULONG_PTR ulParam) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetCurrentMediaType(IMFVideoMediaType **ppMediaType) = 0;
-};
-#ifdef __CRT_UUID_DECL
-__CRT_UUID_DECL(IMFVideoPresenter, 0x29AFF080, 0x182A, 0x4a5d, 0xAF,0x3B, 0x44,0x8F,0x3A,0x63,0x46,0xCB)
-#endif
-#endif // __IMFVideoPresenter_INTERFACE_DEFINED__
-
-#ifndef __IMFRateSupport_INTERFACE_DEFINED__
-#define __IMFRateSupport_INTERFACE_DEFINED__
-DEFINE_GUID(IID_IMFRateSupport, 0x0a9ccdbc, 0xd797, 0x4563, 0x96,0x67, 0x94,0xec,0x5d,0x79,0x29,0x2d);
-MIDL_INTERFACE("0a9ccdbc-d797-4563-9667-94ec5d79292d")
-IMFRateSupport : public IUnknown
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE GetSlowestRate(MFRATE_DIRECTION eDirection, BOOL fThin, float *pflRate) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetFastestRate(MFRATE_DIRECTION eDirection, BOOL fThin, float *pflRate) = 0;
- virtual HRESULT STDMETHODCALLTYPE IsRateSupported(BOOL fThin, float flRate, float *pflNearestSupportedRate) = 0;
-};
-#ifdef __CRT_UUID_DECL
-__CRT_UUID_DECL(IMFRateSupport, 0x0a9ccdbc, 0xd797, 0x4563, 0x96,0x67, 0x94,0xec,0x5d,0x79,0x29,0x2d)
-#endif
-#endif // __IMFRateSupport_INTERFACE_DEFINED__
-
-#ifndef __IMFTopologyServiceLookup_INTERFACE_DEFINED__
-#define __IMFTopologyServiceLookup_INTERFACE_DEFINED__
-typedef enum _MF_SERVICE_LOOKUP_TYPE
-{
- MF_SERVICE_LOOKUP_UPSTREAM = 0,
- MF_SERVICE_LOOKUP_UPSTREAM_DIRECT = (MF_SERVICE_LOOKUP_UPSTREAM + 1),
- MF_SERVICE_LOOKUP_DOWNSTREAM = (MF_SERVICE_LOOKUP_UPSTREAM_DIRECT + 1),
- MF_SERVICE_LOOKUP_DOWNSTREAM_DIRECT = (MF_SERVICE_LOOKUP_DOWNSTREAM + 1),
- MF_SERVICE_LOOKUP_ALL = (MF_SERVICE_LOOKUP_DOWNSTREAM_DIRECT + 1),
- MF_SERVICE_LOOKUP_GLOBAL = (MF_SERVICE_LOOKUP_ALL + 1)
-} MF_SERVICE_LOOKUP_TYPE;
-
-DEFINE_GUID(IID_IMFTopologyServiceLookup, 0xfa993889, 0x4383, 0x415a, 0xa9,0x30, 0xdd,0x47,0x2a,0x8c,0xf6,0xf7);
-MIDL_INTERFACE("fa993889-4383-415a-a930-dd472a8cf6f7")
-IMFTopologyServiceLookup : public IUnknown
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE LookupService(MF_SERVICE_LOOKUP_TYPE Type,
- DWORD dwIndex,
- REFGUID guidService,
- REFIID riid,
- LPVOID *ppvObjects,
- DWORD *pnObjects) = 0;
-};
-#ifdef __CRT_UUID_DECL
-__CRT_UUID_DECL(IMFTopologyServiceLookup, 0xfa993889, 0x4383, 0x415a, 0xa9,0x30, 0xdd,0x47,0x2a,0x8c,0xf6,0xf7)
-#endif
-#endif // __IMFTopologyServiceLookup_INTERFACE_DEFINED__
-
-#ifndef __IMFTopologyServiceLookupClient_INTERFACE_DEFINED__
-#define __IMFTopologyServiceLookupClient_INTERFACE_DEFINED__
-DEFINE_GUID(IID_IMFTopologyServiceLookupClient, 0xfa99388a, 0x4383, 0x415a, 0xa9,0x30, 0xdd,0x47,0x2a,0x8c,0xf6,0xf7);
-MIDL_INTERFACE("fa99388a-4383-415a-a930-dd472a8cf6f7")
-IMFTopologyServiceLookupClient : public IUnknown
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE InitServicePointers(IMFTopologyServiceLookup *pLookup) = 0;
- virtual HRESULT STDMETHODCALLTYPE ReleaseServicePointers(void) = 0;
-};
-#ifdef __CRT_UUID_DECL
-__CRT_UUID_DECL(IMFTopologyServiceLookupClient, 0xfa99388a, 0x4383, 0x415a, 0xa9,0x30, 0xdd,0x47,0x2a,0x8c,0xf6,0xf7)
-#endif
-#endif // __IMFTopologyServiceLookupClient_INTERFACE_DEFINED__
-
-#ifndef __IMediaEventSink_INTERFACE_DEFINED__
-#define __IMediaEventSink_INTERFACE_DEFINED__
-DEFINE_GUID(IID_IMediaEventSink, 0x56a868a2, 0x0ad4, 0x11ce, 0xb0,0x3a, 0x00,0x20,0xaf,0x0b,0xa7,0x70);
-MIDL_INTERFACE("56a868a2-0ad4-11ce-b03a-0020af0ba770")
-IMediaEventSink : public IUnknown
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE Notify(long EventCode, LONG_PTR EventParam1, LONG_PTR EventParam2) = 0;
-};
-#ifdef __CRT_UUID_DECL
-__CRT_UUID_DECL(IMediaEventSink, 0x56a868a2, 0x0ad4, 0x11ce, 0xb0,0x3a, 0x00,0x20,0xaf,0x0b,0xa7,0x70)
-#endif
-#endif // __IMediaEventSink_INTERFACE_DEFINED__
-
-#ifndef __IMFVideoRenderer_INTERFACE_DEFINED__
-#define __IMFVideoRenderer_INTERFACE_DEFINED__
-DEFINE_GUID(IID_IMFVideoRenderer, 0xDFDFD197, 0xA9CA, 0x43d8, 0xB3,0x41, 0x6A,0xF3,0x50,0x37,0x92,0xCD);
-MIDL_INTERFACE("DFDFD197-A9CA-43d8-B341-6AF3503792CD")
-IMFVideoRenderer : public IUnknown
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE InitializeRenderer(IMFTransform *pVideoMixer,
- IMFVideoPresenter *pVideoPresenter) = 0;
-};
-#ifdef __CRT_UUID_DECL
-__CRT_UUID_DECL(IMFVideoRenderer, 0xDFDFD197, 0xA9CA, 0x43d8, 0xB3,0x41, 0x6A,0xF3,0x50,0x37,0x92,0xCD)
-#endif
-#endif // __IMFVideoRenderer_INTERFACE_DEFINED__
-
-#ifndef __IMFTrackedSample_INTERFACE_DEFINED__
-#define __IMFTrackedSample_INTERFACE_DEFINED__
-DEFINE_GUID(IID_IMFTrackedSample, 0x245BF8E9, 0x0755, 0x40f7, 0x88,0xA5, 0xAE,0x0F,0x18,0xD5,0x5E,0x17);
-MIDL_INTERFACE("245BF8E9-0755-40f7-88A5-AE0F18D55E17")
-IMFTrackedSample : public IUnknown
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE SetAllocator(IMFAsyncCallback *pSampleAllocator, IUnknown *pUnkState) = 0;
-};
-#ifdef __CRT_UUID_DECL
-__CRT_UUID_DECL(IMFTrackedSample, 0x245BF8E9, 0x0755, 0x40f7, 0x88,0xA5, 0xAE,0x0F,0x18,0xD5,0x5E,0x17)
-#endif
-#endif // __IMFTrackedSample_INTERFACE_DEFINED__
-
-#ifndef __IMFDesiredSample_INTERFACE_DEFINED__
-#define __IMFDesiredSample_INTERFACE_DEFINED__
-DEFINE_GUID(IID_IMFDesiredSample, 0x56C294D0, 0x753E, 0x4260, 0x8D,0x61, 0xA3,0xD8,0x82,0x0B,0x1D,0x54);
-MIDL_INTERFACE("56C294D0-753E-4260-8D61-A3D8820B1D54")
-IMFDesiredSample : public IUnknown
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE GetDesiredSampleTimeAndDuration(LONGLONG *phnsSampleTime,
- LONGLONG *phnsSampleDuration) = 0;
- virtual void STDMETHODCALLTYPE SetDesiredSampleTimeAndDuration(LONGLONG hnsSampleTime,
- LONGLONG hnsSampleDuration) = 0;
- virtual void STDMETHODCALLTYPE Clear( void) = 0;
-};
-#ifdef __CRT_UUID_DECL
-__CRT_UUID_DECL(IMFDesiredSample, 0x56C294D0, 0x753E, 0x4260, 0x8D,0x61, 0xA3,0xD8,0x82,0x0B,0x1D,0x54)
-#endif
-#endif
-
-#endif // EVRDEFS_H
-
diff --git a/src/plugins/common/evr/evrhelpers.cpp b/src/plugins/common/evr/evrhelpers.cpp
deleted file mode 100644
index a315f1a73..000000000
--- a/src/plugins/common/evr/evrhelpers.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/****************************************************************************
-**
-** 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 "evrhelpers.h"
-
-#ifndef D3DFMT_YV12
-#define D3DFMT_YV12 (D3DFORMAT)MAKEFOURCC ('Y', 'V', '1', '2')
-#endif
-#ifndef D3DFMT_NV12
-#define D3DFMT_NV12 (D3DFORMAT)MAKEFOURCC ('N', 'V', '1', '2')
-#endif
-
-QT_BEGIN_NAMESPACE
-
-HRESULT qt_evr_getFourCC(IMFMediaType *type, DWORD *fourCC)
-{
- if (!fourCC)
- return E_POINTER;
-
- HRESULT hr = S_OK;
- GUID guidSubType = GUID_NULL;
-
- if (SUCCEEDED(hr))
- hr = type->GetGUID(MF_MT_SUBTYPE, &guidSubType);
-
- if (SUCCEEDED(hr))
- *fourCC = guidSubType.Data1;
-
- return hr;
-}
-
-bool qt_evr_areMediaTypesEqual(IMFMediaType *type1, IMFMediaType *type2)
-{
- if (!type1 && !type2)
- return true;
- if (!type1 || !type2)
- return false;
-
- DWORD dwFlags = 0;
- HRESULT hr = type1->IsEqual(type2, &dwFlags);
-
- return (hr == S_OK);
-}
-
-HRESULT qt_evr_validateVideoArea(const MFVideoArea& area, UINT32 width, UINT32 height)
-{
- float fOffsetX = qt_evr_MFOffsetToFloat(area.OffsetX);
- float fOffsetY = qt_evr_MFOffsetToFloat(area.OffsetY);
-
- if ( ((LONG)fOffsetX + area.Area.cx > (LONG)width) ||
- ((LONG)fOffsetY + area.Area.cy > (LONG)height) ) {
- return MF_E_INVALIDMEDIATYPE;
- }
- return S_OK;
-}
-
-bool qt_evr_isSampleTimePassed(IMFClock *clock, IMFSample *sample)
-{
- if (!sample || !clock)
- return false;
-
- HRESULT hr = S_OK;
- MFTIME hnsTimeNow = 0;
- MFTIME hnsSystemTime = 0;
- MFTIME hnsSampleStart = 0;
- MFTIME hnsSampleDuration = 0;
-
- hr = clock->GetCorrelatedTime(0, &hnsTimeNow, &hnsSystemTime);
-
- if (SUCCEEDED(hr))
- hr = sample->GetSampleTime(&hnsSampleStart);
-
- if (SUCCEEDED(hr))
- hr = sample->GetSampleDuration(&hnsSampleDuration);
-
- if (SUCCEEDED(hr)) {
- if (hnsSampleStart + hnsSampleDuration < hnsTimeNow)
- return true;
- }
-
- return false;
-}
-
-QVideoFrame::PixelFormat qt_evr_pixelFormatFromD3DFormat(DWORD format)
-{
- switch (format) {
- case D3DFMT_R8G8B8:
- return QVideoFrame::Format_RGB24;
- case D3DFMT_A8R8G8B8:
- return QVideoFrame::Format_ARGB32;
- case D3DFMT_X8R8G8B8:
- return QVideoFrame::Format_RGB32;
- case D3DFMT_R5G6B5:
- return QVideoFrame::Format_RGB565;
- case D3DFMT_X1R5G5B5:
- return QVideoFrame::Format_RGB555;
- case D3DFMT_A8:
- return QVideoFrame::Format_Y8;
- case D3DFMT_A8B8G8R8:
- return QVideoFrame::Format_BGRA32;
- case D3DFMT_X8B8G8R8:
- return QVideoFrame::Format_BGR32;
- case D3DFMT_UYVY:
- return QVideoFrame::Format_UYVY;
- case D3DFMT_YUY2:
- return QVideoFrame::Format_YUYV;
- case D3DFMT_NV12:
- return QVideoFrame::Format_NV12;
- case D3DFMT_YV12:
- return QVideoFrame::Format_YV12;
- case D3DFMT_UNKNOWN:
- default:
- return QVideoFrame::Format_Invalid;
- }
-}
-
-D3DFORMAT qt_evr_D3DFormatFromPixelFormat(QVideoFrame::PixelFormat format)
-{
- switch (format) {
- case QVideoFrame::Format_RGB24:
- return D3DFMT_R8G8B8;
- case QVideoFrame::Format_ARGB32:
- return D3DFMT_A8R8G8B8;
- case QVideoFrame::Format_RGB32:
- return D3DFMT_X8R8G8B8;
- case QVideoFrame::Format_RGB565:
- return D3DFMT_R5G6B5;
- case QVideoFrame::Format_RGB555:
- return D3DFMT_X1R5G5B5;
- case QVideoFrame::Format_Y8:
- return D3DFMT_A8;
- case QVideoFrame::Format_BGRA32:
- return D3DFMT_A8B8G8R8;
- case QVideoFrame::Format_BGR32:
- return D3DFMT_X8B8G8R8;
- case QVideoFrame::Format_UYVY:
- return D3DFMT_UYVY;
- case QVideoFrame::Format_YUYV:
- return D3DFMT_YUY2;
- case QVideoFrame::Format_NV12:
- return D3DFMT_NV12;
- case QVideoFrame::Format_YV12:
- return D3DFMT_YV12;
- case QVideoFrame::Format_Invalid:
- default:
- return D3DFMT_UNKNOWN;
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/common/evr/evrhelpers.h b/src/plugins/common/evr/evrhelpers.h
deleted file mode 100644
index b5bdf5ead..000000000
--- a/src/plugins/common/evr/evrhelpers.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#ifndef EVRHELPERS_H
-#define EVRHELPERS_H
-
-#include "evrdefs.h"
-#include <qvideoframe.h>
-
-QT_BEGIN_NAMESPACE
-
-template<class T>
-static inline void qt_evr_safe_release(T **unk)
-{
- if (*unk) {
- (*unk)->Release();
- *unk = NULL;
- }
-}
-
-HRESULT qt_evr_getFourCC(IMFMediaType *type, DWORD *fourCC);
-
-bool qt_evr_areMediaTypesEqual(IMFMediaType *type1, IMFMediaType *type2);
-
-HRESULT qt_evr_validateVideoArea(const MFVideoArea& area, UINT32 width, UINT32 height);
-
-bool qt_evr_isSampleTimePassed(IMFClock *clock, IMFSample *sample);
-
-inline float qt_evr_MFOffsetToFloat(const MFOffset& offset)
-{
- return offset.value + (float(offset.fract) / 65536);
-}
-
-inline MFOffset qt_evr_makeMFOffset(float v)
-{
- MFOffset offset;
- offset.value = short(v);
- offset.fract = WORD(65536 * (v-offset.value));
- return offset;
-}
-
-inline MFVideoArea qt_evr_makeMFArea(float x, float y, DWORD width, DWORD height)
-{
- MFVideoArea area;
- area.OffsetX = qt_evr_makeMFOffset(x);
- area.OffsetY = qt_evr_makeMFOffset(y);
- area.Area.cx = width;
- area.Area.cy = height;
- return area;
-}
-
-inline HRESULT qt_evr_getFrameRate(IMFMediaType *pType, MFRatio *pRatio)
-{
- return MFGetAttributeRatio(pType, MF_MT_FRAME_RATE,
- reinterpret_cast<UINT32*>(&pRatio->Numerator),
- reinterpret_cast<UINT32*>(&pRatio->Denominator));
-}
-
-QVideoFrame::PixelFormat qt_evr_pixelFormatFromD3DFormat(DWORD format);
-D3DFORMAT qt_evr_D3DFormatFromPixelFormat(QVideoFrame::PixelFormat format);
-
-QT_END_NAMESPACE
-
-#endif // EVRHELPERS_H
-
diff --git a/src/plugins/common/evr/evrvideowindowcontrol.cpp b/src/plugins/common/evr/evrvideowindowcontrol.cpp
deleted file mode 100644
index 95f63c2e7..000000000
--- a/src/plugins/common/evr/evrvideowindowcontrol.cpp
+++ /dev/null
@@ -1,362 +0,0 @@
-/****************************************************************************
-**
-** 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 "evrvideowindowcontrol.h"
-
-#ifndef QT_NO_WIDGETS
-#include <qwidget.h>
-#endif
-
-EvrVideoWindowControl::EvrVideoWindowControl(QObject *parent)
- : QVideoWindowControl(parent)
- , m_windowId(0)
- , m_windowColor(RGB(0, 0, 0))
- , m_dirtyValues(0)
- , m_aspectRatioMode(Qt::KeepAspectRatio)
- , m_brightness(0)
- , m_contrast(0)
- , m_hue(0)
- , m_saturation(0)
- , m_fullScreen(false)
- , m_displayControl(0)
- , m_processor(0)
-{
-}
-
-EvrVideoWindowControl::~EvrVideoWindowControl()
-{
- clear();
-}
-
-bool EvrVideoWindowControl::setEvr(IUnknown *evr)
-{
- clear();
-
- if (!evr)
- return true;
-
- IMFGetService *service = NULL;
-
- if (SUCCEEDED(evr->QueryInterface(IID_PPV_ARGS(&service)))
- && SUCCEEDED(service->GetService(mr_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&m_displayControl)))) {
-
- service->GetService(mr_VIDEO_MIXER_SERVICE, IID_PPV_ARGS(&m_processor));
-
- setWinId(m_windowId);
- setDisplayRect(m_displayRect);
- setAspectRatioMode(m_aspectRatioMode);
- m_dirtyValues = DXVA2_ProcAmp_Brightness | DXVA2_ProcAmp_Contrast | DXVA2_ProcAmp_Hue | DXVA2_ProcAmp_Saturation;
- applyImageControls();
- }
-
- if (service)
- service->Release();
-
- return m_displayControl != NULL;
-}
-
-void EvrVideoWindowControl::clear()
-{
- if (m_displayControl)
- m_displayControl->Release();
- m_displayControl = NULL;
-
- if (m_processor)
- m_processor->Release();
- m_processor = NULL;
-}
-
-WId EvrVideoWindowControl::winId() const
-{
- return m_windowId;
-}
-
-void EvrVideoWindowControl::setWinId(WId id)
-{
- m_windowId = id;
-
-#ifndef QT_NO_WIDGETS
- if (QWidget *widget = QWidget::find(m_windowId)) {
- const QColor color = widget->palette().color(QPalette::Window);
-
- m_windowColor = RGB(color.red(), color.green(), color.blue());
- }
-#endif
-
- if (m_displayControl)
- m_displayControl->SetVideoWindow(HWND(m_windowId));
-}
-
-QRect EvrVideoWindowControl::displayRect() const
-{
- return m_displayRect;
-}
-
-void EvrVideoWindowControl::setDisplayRect(const QRect &rect)
-{
- m_displayRect = rect;
-
- if (m_displayControl) {
- RECT displayRect = { rect.left(), rect.top(), rect.right() + 1, rect.bottom() + 1 };
- QSize sourceSize = nativeSize();
-
- RECT sourceRect = { 0, 0, sourceSize.width(), sourceSize.height() };
-
- if (m_aspectRatioMode == Qt::KeepAspectRatioByExpanding) {
- QSize clippedSize = rect.size();
- clippedSize.scale(sourceRect.right, sourceRect.bottom, Qt::KeepAspectRatio);
-
- sourceRect.left = (sourceRect.right - clippedSize.width()) / 2;
- sourceRect.top = (sourceRect.bottom - clippedSize.height()) / 2;
- sourceRect.right = sourceRect.left + clippedSize.width();
- sourceRect.bottom = sourceRect.top + clippedSize.height();
- }
-
- if (sourceSize.width() > 0 && sourceSize.height() > 0) {
- MFVideoNormalizedRect sourceNormRect;
- sourceNormRect.left = float(sourceRect.left) / float(sourceRect.right);
- sourceNormRect.top = float(sourceRect.top) / float(sourceRect.bottom);
- sourceNormRect.right = float(sourceRect.right) / float(sourceRect.right);
- sourceNormRect.bottom = float(sourceRect.bottom) / float(sourceRect.bottom);
- m_displayControl->SetVideoPosition(&sourceNormRect, &displayRect);
- } else {
- m_displayControl->SetVideoPosition(NULL, &displayRect);
- }
-
- // To refresh content immediately.
- repaint();
- }
-}
-
-bool EvrVideoWindowControl::isFullScreen() const
-{
- return m_fullScreen;
-}
-
-void EvrVideoWindowControl::setFullScreen(bool fullScreen)
-{
- if (m_fullScreen == fullScreen)
- return;
- emit fullScreenChanged(m_fullScreen = fullScreen);
-}
-
-void EvrVideoWindowControl::repaint()
-{
- QSize size = nativeSize();
- if (size.width() > 0 && size.height() > 0
- && m_displayControl
- && SUCCEEDED(m_displayControl->RepaintVideo())) {
- return;
- }
-
- PAINTSTRUCT paint;
- if (HDC dc = ::BeginPaint(HWND(m_windowId), &paint)) {
- HPEN pen = ::CreatePen(PS_SOLID, 1, m_windowColor);
- HBRUSH brush = ::CreateSolidBrush(m_windowColor);
- ::SelectObject(dc, pen);
- ::SelectObject(dc, brush);
-
- ::Rectangle(
- dc,
- m_displayRect.left(),
- m_displayRect.top(),
- m_displayRect.right() + 1,
- m_displayRect.bottom() + 1);
-
- ::DeleteObject(pen);
- ::DeleteObject(brush);
- ::EndPaint(HWND(m_windowId), &paint);
- }
-}
-
-QSize EvrVideoWindowControl::nativeSize() const
-{
- QSize size;
- if (m_displayControl) {
- SIZE sourceSize;
- if (SUCCEEDED(m_displayControl->GetNativeVideoSize(&sourceSize, 0)))
- size = QSize(sourceSize.cx, sourceSize.cy);
- }
- return size;
-}
-
-Qt::AspectRatioMode EvrVideoWindowControl::aspectRatioMode() const
-{
- return m_aspectRatioMode;
-}
-
-void EvrVideoWindowControl::setAspectRatioMode(Qt::AspectRatioMode mode)
-{
- m_aspectRatioMode = mode;
-
- if (m_displayControl) {
- switch (mode) {
- case Qt::IgnoreAspectRatio:
- //comment from MSDN: Do not maintain the aspect ratio of the video. Stretch the video to fit the output rectangle.
- m_displayControl->SetAspectRatioMode(MFVideoARMode_None);
- break;
- case Qt::KeepAspectRatio:
- //comment from MSDN: Preserve the aspect ratio of the video by letterboxing or within the output rectangle.
- m_displayControl->SetAspectRatioMode(MFVideoARMode_PreservePicture);
- break;
- case Qt::KeepAspectRatioByExpanding:
- //for this mode, more adjustment will be done in setDisplayRect
- m_displayControl->SetAspectRatioMode(MFVideoARMode_PreservePicture);
- break;
- default:
- break;
- }
- setDisplayRect(m_displayRect);
- }
-}
-
-int EvrVideoWindowControl::brightness() const
-{
- return m_brightness;
-}
-
-void EvrVideoWindowControl::setBrightness(int brightness)
-{
- if (m_brightness == brightness)
- return;
-
- m_brightness = brightness;
-
- m_dirtyValues |= DXVA2_ProcAmp_Brightness;
-
- applyImageControls();
-
- emit brightnessChanged(brightness);
-}
-
-int EvrVideoWindowControl::contrast() const
-{
- return m_contrast;
-}
-
-void EvrVideoWindowControl::setContrast(int contrast)
-{
- if (m_contrast == contrast)
- return;
-
- m_contrast = contrast;
-
- m_dirtyValues |= DXVA2_ProcAmp_Contrast;
-
- applyImageControls();
-
- emit contrastChanged(contrast);
-}
-
-int EvrVideoWindowControl::hue() const
-{
- return m_hue;
-}
-
-void EvrVideoWindowControl::setHue(int hue)
-{
- if (m_hue == hue)
- return;
-
- m_hue = hue;
-
- m_dirtyValues |= DXVA2_ProcAmp_Hue;
-
- applyImageControls();
-
- emit hueChanged(hue);
-}
-
-int EvrVideoWindowControl::saturation() const
-{
- return m_saturation;
-}
-
-void EvrVideoWindowControl::setSaturation(int saturation)
-{
- if (m_saturation == saturation)
- return;
-
- m_saturation = saturation;
-
- m_dirtyValues |= DXVA2_ProcAmp_Saturation;
-
- applyImageControls();
-
- emit saturationChanged(saturation);
-}
-
-void EvrVideoWindowControl::applyImageControls()
-{
- if (m_processor) {
- DXVA2_ProcAmpValues values;
- if (m_dirtyValues & DXVA2_ProcAmp_Brightness) {
- values.Brightness = scaleProcAmpValue(DXVA2_ProcAmp_Brightness, m_brightness);
- }
- if (m_dirtyValues & DXVA2_ProcAmp_Contrast) {
- values.Contrast = scaleProcAmpValue(DXVA2_ProcAmp_Contrast, m_contrast);
- }
- if (m_dirtyValues & DXVA2_ProcAmp_Hue) {
- values.Hue = scaleProcAmpValue(DXVA2_ProcAmp_Hue, m_hue);
- }
- if (m_dirtyValues & DXVA2_ProcAmp_Saturation) {
- values.Saturation = scaleProcAmpValue(DXVA2_ProcAmp_Saturation, m_saturation);
- }
-
- if (SUCCEEDED(m_processor->SetProcAmpValues(m_dirtyValues, &values))) {
- m_dirtyValues = 0;
- }
- }
-}
-
-DXVA2_Fixed32 EvrVideoWindowControl::scaleProcAmpValue(DWORD prop, int value) const
-{
- float scaledValue = 0.0;
-
- DXVA2_ValueRange range;
- if (SUCCEEDED(m_processor->GetProcAmpRange(prop, &range))) {
- scaledValue = DXVA2FixedToFloat(range.DefaultValue);
- if (value > 0)
- scaledValue += float(value) * (DXVA2FixedToFloat(range.MaxValue) - DXVA2FixedToFloat(range.DefaultValue)) / 100;
- else if (value < 0)
- scaledValue -= float(value) * (DXVA2FixedToFloat(range.MinValue) - DXVA2FixedToFloat(range.DefaultValue)) / 100;
- }
-
- return DXVA2FloatToFixed(scaledValue);
-}
diff --git a/src/plugins/common/evr/evrvideowindowcontrol.h b/src/plugins/common/evr/evrvideowindowcontrol.h
deleted file mode 100644
index ce3b7746f..000000000
--- a/src/plugins/common/evr/evrvideowindowcontrol.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#ifndef EVRVIDEOWINDOWCONTROL_H
-#define EVRVIDEOWINDOWCONTROL_H
-
-#include "qvideowindowcontrol.h"
-
-#include "evrdefs.h"
-
-QT_BEGIN_NAMESPACE
-
-class EvrVideoWindowControl : public QVideoWindowControl
-{
- Q_OBJECT
-public:
- EvrVideoWindowControl(QObject *parent = 0);
- ~EvrVideoWindowControl() override;
-
- bool setEvr(IUnknown *evr);
-
- WId winId() const override;
- void setWinId(WId id) override;
-
- QRect displayRect() const override;
- void setDisplayRect(const QRect &rect) override;
-
- bool isFullScreen() const override;
- void setFullScreen(bool fullScreen) override;
-
- void repaint() override;
-
- QSize nativeSize() const override;
-
- Qt::AspectRatioMode aspectRatioMode() const override;
- void setAspectRatioMode(Qt::AspectRatioMode mode) override;
-
- int brightness() const override;
- void setBrightness(int brightness) override;
-
- int contrast() const override;
- void setContrast(int contrast) override;
-
- int hue() const override;
- void setHue(int hue) override;
-
- int saturation() const override;
- void setSaturation(int saturation) override;
-
- void applyImageControls();
-
-private:
- void clear();
- DXVA2_Fixed32 scaleProcAmpValue(DWORD prop, int value) const;
-
- WId m_windowId;
- COLORREF m_windowColor;
- DWORD m_dirtyValues;
- Qt::AspectRatioMode m_aspectRatioMode;
- QRect m_displayRect;
- int m_brightness;
- int m_contrast;
- int m_hue;
- int m_saturation;
- bool m_fullScreen;
-
- IMFVideoDisplayControl *m_displayControl;
- IMFVideoProcessor *m_processor;
-};
-
-QT_END_NAMESPACE
-
-#endif