summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@theqtcompany.com>2015-11-05 13:48:40 +0100
committerYoann Lopes <yoann.lopes@theqtcompany.com>2016-01-12 15:51:24 +0000
commit36549dbe148055d6ecf98952b05b4ff2310fe491 (patch)
treed7aa21a5efc2b9c80125e9ed4598188a0a11dec5 /src/plugins
parent963a534e339c4515f0e1abf85c6e91ec3de145de (diff)
DirectShow: use the EVR in the renderer control.
As for the window control, the existing code from the WMF plugin has been refactored out and is now shared for both plugins. This enables HW-accelerated video decoding in QML, QGraphicsVideoItem and custom QAbstractVideoSurfaces (Angle is required). Task-number: QTBUG-45593 Change-Id: I1d4dbf5695cdd4dbee93f9f4a957fa4d813aa85d Reviewed-by: Christian Stromme <christian.stromme@theqtcompany.com>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/common/evr.pri26
-rw-r--r--src/plugins/common/evr/evrcustompresenter.cpp (renamed from src/plugins/wmf/evrcustompresenter.cpp)233
-rw-r--r--src/plugins/common/evr/evrcustompresenter.h (renamed from src/plugins/wmf/evrcustompresenter.h)85
-rw-r--r--src/plugins/common/evr/evrd3dpresentengine.cpp (renamed from src/plugins/wmf/evrd3dpresentengine.cpp)42
-rw-r--r--src/plugins/common/evr/evrd3dpresentengine.h (renamed from src/plugins/wmf/evrd3dpresentengine.h)4
-rw-r--r--src/plugins/common/evr/evrdefs.cpp42
-rw-r--r--src/plugins/common/evr/evrdefs.h219
-rw-r--r--src/plugins/common/evr/evrhelpers.cpp (renamed from src/plugins/wmf/mfglobal.cpp)27
-rw-r--r--src/plugins/common/evr/evrhelpers.h85
-rw-r--r--src/plugins/common/evr/evrvideowindowcontrol.cpp2
-rw-r--r--src/plugins/directshow/player/directshowevrvideowindowcontrol.cpp4
-rw-r--r--src/plugins/directshow/player/directshowvideorenderercontrol.cpp42
-rw-r--r--src/plugins/directshow/player/directshowvideorenderercontrol.h10
-rw-r--r--src/plugins/directshow/player/player.pri7
-rw-r--r--src/plugins/wmf/mfactivate.h2
-rw-r--r--src/plugins/wmf/mfglobal.h149
-rw-r--r--src/plugins/wmf/player/mfvideorenderercontrol.cpp100
-rw-r--r--src/plugins/wmf/player/mfvideorenderercontrol.h10
-rw-r--r--src/plugins/wmf/wmf.pro17
19 files changed, 705 insertions, 401 deletions
diff --git a/src/plugins/common/evr.pri b/src/plugins/common/evr.pri
index f951f6730..aa272adab 100644
--- a/src/plugins/common/evr.pri
+++ b/src/plugins/common/evr.pri
@@ -2,7 +2,27 @@ INCLUDEPATH += $$PWD/evr
qtHaveModule(widgets): QT += widgets
-HEADERS += $$PWD/evr/evrvideowindowcontrol.h \
- $$PWD/evr/evrdefs.h
+HEADERS += \
+ $$PWD/evr/evrvideowindowcontrol.h \
+ $$PWD/evr/evrdefs.h
-SOURCES += $$PWD/evr/evrvideowindowcontrol.cpp
+SOURCES += \
+ $$PWD/evr/evrvideowindowcontrol.cpp \
+ $$PWD/evr/evrdefs.cpp
+
+contains(QT_CONFIG, angle)|contains(QT_CONFIG, dynamicgl) {
+ LIBS += -lmf -lmfplat -lmfuuid -ld3d9 -ldxva2 -lwinmm -levr
+ QT += gui-private
+
+ DEFINES += CUSTOM_EVR_PRESENTER
+
+ HEADERS += \
+ $$PWD/evr/evrcustompresenter.h \
+ $$PWD/evr/evrd3dpresentengine.h \
+ $$PWD/evr/evrhelpers.h
+
+ SOURCES += \
+ $$PWD/evr/evrcustompresenter.cpp \
+ $$PWD/evr/evrd3dpresentengine.cpp \
+ $$PWD/evr/evrhelpers.cpp
+}
diff --git a/src/plugins/wmf/evrcustompresenter.cpp b/src/plugins/common/evr/evrcustompresenter.cpp
index 967095b20..969dd1415 100644
--- a/src/plugins/wmf/evrcustompresenter.cpp
+++ b/src/plugins/common/evr/evrcustompresenter.cpp
@@ -33,8 +33,8 @@
#include "evrcustompresenter.h"
-#include "mfglobal.h"
#include "evrd3dpresentengine.h"
+#include "evrhelpers.h"
#include <QtCore/qmutex.h>
#include <QtCore/qvarlengtharray.h>
@@ -44,10 +44,8 @@
#include <qcoreapplication.h>
#include <qmath.h>
#include <QtCore/qdebug.h>
-#include <d3d9.h>
-#include <dshow.h>
-
-QT_USE_NAMESPACE
+#include <float.h>
+#include <evcode.h>
const static MFRatio g_DefaultFrameRate = { 30, 1 };
static const DWORD SCHEDULER_TIMEOUT = 5000;
@@ -66,24 +64,39 @@ 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;
+}
Scheduler::Scheduler()
- : m_CB(NULL)
- , m_clock(NULL)
+ : m_clock(NULL)
+ , m_CB(NULL)
, m_threadID(0)
, m_schedulerThread(0)
, m_threadReadyEvent(0)
, m_flushEvent(0)
, m_playbackRate(1.0f)
- , m_lastSampleTime(0)
, m_perFrameInterval(0)
, m_perFrame_1_4th(0)
+ , m_lastSampleTime(0)
{
}
Scheduler::~Scheduler()
{
- qt_wmf_safeRelease(&m_clock);
+ qt_evr_safe_release(&m_clock);
for (int i = 0; i < m_scheduledSamples.size(); ++i)
m_scheduledSamples[i]->Release();
m_scheduledSamples.clear();
@@ -109,8 +122,14 @@ HRESULT Scheduler::startScheduler(IMFClock *clock)
HRESULT hr = S_OK;
DWORD dwID = 0;
+ HANDLE hObjects[2];
+ DWORD dwWait = 0;
- qt_wmf_copyComPointer(m_clock, clock);
+ 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);
@@ -136,10 +155,9 @@ HRESULT Scheduler::startScheduler(IMFClock *clock)
goto done;
}
- HANDLE hObjects[] = { m_threadReadyEvent, m_schedulerThread };
- DWORD dwWait = 0;
-
// 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.
@@ -262,7 +280,7 @@ HRESULT Scheduler::processSamplesInQueue(LONG *nextSleep)
// means the scheduler should sleep for that amount of time.
hr = processSample(sample, &wait);
- qt_wmf_safeRelease(&sample);
+ qt_evr_safe_release(&sample);
if (FAILED(hr) || wait > 0)
break;
@@ -401,7 +419,7 @@ DWORD Scheduler::schedulerThreadProcPrivate()
hr = processSamplesInQueue(&wait);
if (FAILED(hr))
exitThread = true;
- processSamples = (wait != INFINITE);
+ processSamples = (wait != (LONG)INFINITE);
}
break;
}
@@ -551,10 +569,10 @@ EVRCustomPresenter::EVRCustomPresenter()
EVRCustomPresenter::~EVRCustomPresenter()
{
- qt_wmf_safeRelease(&m_clock);
- qt_wmf_safeRelease(&m_mixer);
- qt_wmf_safeRelease(&m_mediaEventSink);
- qt_wmf_safeRelease(&m_mediaType);
+ qt_evr_safe_release(&m_clock);
+ qt_evr_safe_release(&m_mixer);
+ qt_evr_safe_release(&m_mediaEventSink);
+ qt_evr_safe_release(&m_mediaType);
m_D3DPresentEngine->deleteLater();
}
@@ -606,7 +624,7 @@ HRESULT EVRCustomPresenter::GetService(REFGUID guidService, REFIID riid, LPVOID
return E_POINTER;
// The only service GUID that we support is MR_VIDEO_RENDER_SERVICE.
- if (guidService != 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.
@@ -623,7 +641,7 @@ HRESULT EVRCustomPresenter::GetDeviceID(IID* deviceID)
if (!deviceID)
return E_POINTER;
- *deviceID = IID_IDirect3DDevice9;
+ *deviceID = iid_IDirect3DDevice9;
return S_OK;
}
@@ -642,15 +660,15 @@ HRESULT EVRCustomPresenter::InitServicePointers(IMFTopologyServiceLookup *lookup
if (isActive())
return MF_E_INVALIDREQUEST;
- qt_wmf_safeRelease(&m_clock);
- qt_wmf_safeRelease(&m_mixer);
- qt_wmf_safeRelease(&m_mediaEventSink);
+ 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),
+ mr_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&m_clock),
&objectCount
);
@@ -658,7 +676,7 @@ HRESULT EVRCustomPresenter::InitServicePointers(IMFTopologyServiceLookup *lookup
objectCount = 1;
hr = lookup->LookupService(MF_SERVICE_LOOKUP_GLOBAL, 0,
- MR_VIDEO_MIXER_SERVICE, IID_PPV_ARGS(&m_mixer),
+ mr_VIDEO_MIXER_SERVICE, IID_PPV_ARGS(&m_mixer),
&objectCount
);
@@ -674,7 +692,7 @@ HRESULT EVRCustomPresenter::InitServicePointers(IMFTopologyServiceLookup *lookup
objectCount = 1;
hr = lookup->LookupService(MF_SERVICE_LOOKUP_GLOBAL, 0,
- MR_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&m_mediaEventSink),
+ mr_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&m_mediaEventSink),
&objectCount
);
@@ -700,9 +718,9 @@ HRESULT EVRCustomPresenter::ReleaseServicePointers()
setMediaType(NULL);
// Release all services that were acquired from InitServicePointers.
- qt_wmf_safeRelease(&m_clock);
- qt_wmf_safeRelease(&m_mixer);
- qt_wmf_safeRelease(&m_mediaEventSink);
+ qt_evr_safe_release(&m_clock);
+ qt_evr_safe_release(&m_mixer);
+ qt_evr_safe_release(&m_mediaEventSink);
return S_OK;
}
@@ -1019,11 +1037,21 @@ void EVRCustomPresenter::setSurface(QAbstractVideoSurface *surface)
{
m_mutex.lock();
+ if (m_surface) {
+ disconnect(m_surface, &QAbstractVideoSurface::supportedFormatsChanged,
+ this, &EVRCustomPresenter::supportedFormatsChanged);
+ }
+
m_surface = surface;
if (m_D3DPresentEngine)
m_D3DPresentEngine->setSurface(surface);
+ if (m_surface) {
+ connect(m_surface, &QAbstractVideoSurface::supportedFormatsChanged,
+ this, &EVRCustomPresenter::supportedFormatsChanged);
+ }
+
m_mutex.unlock();
supportedFormatsChanged();
@@ -1049,8 +1077,8 @@ HRESULT EVRCustomPresenter::renegotiateMediaType()
// Loop through all of the mixer's proposed output types.
DWORD typeIndex = 0;
while (!foundMediaType && (hr != MF_E_NO_MORE_TYPES)) {
- qt_wmf_safeRelease(&mixerType);
- qt_wmf_safeRelease(&optimalType);
+ 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);
@@ -1089,8 +1117,8 @@ HRESULT EVRCustomPresenter::renegotiateMediaType()
foundMediaType = true;
}
- qt_wmf_safeRelease(&mixerType);
- qt_wmf_safeRelease(&optimalType);
+ qt_evr_safe_release(&mixerType);
+ qt_evr_safe_release(&optimalType);
return hr;
}
@@ -1218,7 +1246,7 @@ HRESULT EVRCustomPresenter::startFrameStep()
if (FAILED(hr))
goto done;
- qt_wmf_safeRelease(&sample);
+ qt_evr_safe_release(&sample);
// We break from this loop when:
// (a) the frame-step queue is empty, or
@@ -1234,12 +1262,12 @@ HRESULT EVRCustomPresenter::startFrameStep()
if (FAILED(hr))
goto done;
- qt_wmf_safeRelease(&sample);
+ qt_evr_safe_release(&sample);
}
}
done:
- qt_wmf_safeRelease(&sample);
+ qt_evr_safe_release(&sample);
return hr;
}
@@ -1251,7 +1279,7 @@ HRESULT EVRCustomPresenter::completeFrameStep(IMFSample *sample)
// Update our state.
m_frameStep.state = FrameStepComplete;
- m_frameStep.sampleNoRef = NULL;
+ m_frameStep.sampleNoRef = 0;
// Notify the EVR that the frame-step is complete.
notifyEvent(EC_STEP_COMPLETE, FALSE, 0); // FALSE = completed (not cancelled)
@@ -1279,7 +1307,7 @@ HRESULT EVRCustomPresenter::cancelFrameStep()
m_frameStep.state = FrameStepNone;
m_frameStep.steps = 0;
- m_frameStep.sampleNoRef = NULL;
+ m_frameStep.sampleNoRef = 0;
// Don't clear the frame-step queue yet, because we might frame step again.
if (oldState > FrameStepNone && oldState < FrameStepComplete) {
@@ -1302,6 +1330,10 @@ HRESULT EVRCustomPresenter::createOptimalVideoType(IMFMediaType *proposedType, I
IMFMediaType *mtOptimal = NULL;
+ UINT64 size;
+ int width;
+ int height;
+
// Clone the proposed type.
hr = MFCreateMediaType(&mtOptimal);
@@ -1315,21 +1347,22 @@ HRESULT EVRCustomPresenter::createOptimalVideoType(IMFMediaType *proposedType, I
// Modify the new type.
// Set the pixel aspect ratio (PAR) to 1:1 (see assumption #1, above)
- hr = MFSetAttributeRatio(mtOptimal, MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
+ // The ratio is packed in a single UINT64. A helper function is normally available for
+ // that (MFSetAttributeRatio) but it's not correctly defined in MinGW 4.9.1.
+ hr = mtOptimal->SetUINT64(MF_MT_PIXEL_ASPECT_RATIO, (((UINT64) 1) << 32) | ((UINT64) 1));
if (FAILED(hr))
goto done;
- UINT64 size;
hr = proposedType->GetUINT64(MF_MT_FRAME_SIZE, &size);
- int width = int(HI32(size));
- int height = int(LO32(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_wmf_makeMFArea(0, 0, rcOutput.right, rcOutput.bottom);
+ displayArea = qt_evr_makeMFArea(0, 0, rcOutput.right, rcOutput.bottom);
hr = mtOptimal->SetUINT32(MF_MT_PAN_SCAN_ENABLED, FALSE);
if (FAILED(hr))
@@ -1355,7 +1388,7 @@ HRESULT EVRCustomPresenter::createOptimalVideoType(IMFMediaType *proposedType, I
(*optimalType)->AddRef();
done:
- qt_wmf_safeRelease(&mtOptimal);
+ qt_evr_safe_release(&mtOptimal);
return hr;
}
@@ -1366,7 +1399,7 @@ HRESULT EVRCustomPresenter::setMediaType(IMFMediaType *mediaType)
// Clearing the media type is allowed in any state (including shutdown).
if (!mediaType) {
- qt_wmf_safeRelease(&m_mediaType);
+ qt_evr_safe_release(&m_mediaType);
releaseResources();
m_D3DPresentEngine->setSurfaceFormat(QVideoSurfaceFormat());
return S_OK;
@@ -1378,6 +1411,9 @@ HRESULT EVRCustomPresenter::setMediaType(IMFMediaType *mediaType)
IMFSample *sample = NULL;
QVideoSurfaceFormat surfaceFormat;
+ UINT64 size;
+ int width;
+ int height;
// Cannot set the media type after shutdown.
HRESULT hr = checkShutdown();
@@ -1386,11 +1422,11 @@ HRESULT EVRCustomPresenter::setMediaType(IMFMediaType *mediaType)
// Check if the new type is actually different.
// Note: This function safely handles NULL input parameters.
- if (qt_wmf_areMediaTypesEqual(m_mediaType, mediaType))
+ 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_wmf_safeRelease(&m_mediaType);
+ qt_evr_safe_release(&m_mediaType);
releaseResources();
// Initialize the presenter engine with the new media type.
@@ -1416,7 +1452,7 @@ HRESULT EVRCustomPresenter::setMediaType(IMFMediaType *mediaType)
goto done;
// Set the frame rate on the scheduler.
- if (SUCCEEDED(qt_wmf_getFrameRate(mediaType, &fps)) && (fps.Numerator != 0) && (fps.Denominator != 0)) {
+ 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
@@ -1430,10 +1466,9 @@ HRESULT EVRCustomPresenter::setMediaType(IMFMediaType *mediaType)
m_mediaType->AddRef();
// Create the surface format
- UINT64 size;
hr = m_mediaType->GetUINT64(MF_MT_FRAME_SIZE, &size);
- int width = int(HI32(size));
- int height = int(LO32(size));
+ width = int(HI32(size));
+ height = int(LO32(size));
surfaceFormat = QVideoSurfaceFormat(QSize(width, height),
pixelFormatFromMediaType(m_mediaType),
QAbstractVideoBuffer::GLTextureHandle);
@@ -1454,7 +1489,7 @@ HRESULT EVRCustomPresenter::isMediaTypeSupported(IMFMediaType *proposed)
UINT32 width = 0, height = 0;
// Validate the format.
- HRESULT hr = qt_wmf_getFourCC(proposed, (DWORD*)&d3dFormat);
+ HRESULT hr = qt_evr_getFourCC(proposed, (DWORD*)&d3dFormat);
if (FAILED(hr))
return hr;
@@ -1493,13 +1528,13 @@ HRESULT EVRCustomPresenter::isMediaTypeSupported(IMFMediaType *proposed)
// we ignore it. We just want to reject invalid apertures.
if (SUCCEEDED(proposed->GetBlob(MF_MT_PAN_SCAN_APERTURE, (UINT8*)&videoCropArea, sizeof(videoCropArea), NULL)))
- hr = qt_wmf_validateVideoArea(videoCropArea, width, height);
+ hr = qt_evr_validateVideoArea(videoCropArea, width, height);
if (SUCCEEDED(proposed->GetBlob(MF_MT_GEOMETRIC_APERTURE, (UINT8*)&videoCropArea, sizeof(videoCropArea), NULL)))
- hr = qt_wmf_validateVideoArea(videoCropArea, width, height);
+ hr = qt_evr_validateVideoArea(videoCropArea, width, height);
if (SUCCEEDED(proposed->GetBlob(MF_MT_MINIMUM_DISPLAY_APERTURE, (UINT8*)&videoCropArea, sizeof(videoCropArea), NULL)))
- hr = qt_wmf_validateVideoArea(videoCropArea, width, height);
+ hr = qt_evr_validateVideoArea(videoCropArea, width, height);
return hr;
}
@@ -1640,10 +1675,10 @@ HRESULT EVRCustomPresenter::processOutput()
}
done:
- qt_wmf_safeRelease(&sample);
+ qt_evr_safe_release(&sample);
// Important: Release any events returned from the ProcessOutput method.
- qt_wmf_safeRelease(&dataBuffer.pEvents);
+ qt_evr_safe_release(&dataBuffer.pEvents);
return hr;
}
@@ -1673,7 +1708,7 @@ HRESULT EVRCustomPresenter::deliverFrameStepSample(IMFSample *sample)
IUnknown *unk = NULL;
// For rate 0, discard any sample that ends earlier than the clock time.
- if (isScrubbing() && m_clock && qt_wmf_isSampleTimePassed(m_clock, sample)) {
+ 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,
@@ -1719,7 +1754,7 @@ HRESULT EVRCustomPresenter::deliverFrameStepSample(IMFSample *sample)
}
}
done:
- qt_wmf_safeRelease(&unk);
+ qt_evr_safe_release(&unk);
return hr;
}
@@ -1732,7 +1767,7 @@ HRESULT EVRCustomPresenter::trackSample(IMFSample *sample)
if (SUCCEEDED(hr))
hr = tracked->SetAllocator(&m_sampleFreeCB, NULL);
- qt_wmf_safeRelease(&tracked);
+ qt_evr_safe_release(&tracked);
return hr;
}
@@ -1761,6 +1796,7 @@ 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);
@@ -1795,7 +1831,7 @@ HRESULT EVRCustomPresenter::onSampleFree(IMFAsyncResult *result)
m_mutex.lock();
- UINT32 token = MFGetAttributeUINT32(sample, MFSamplePresenter_SampleCounter, (UINT32)-1);
+ token = MFGetAttributeUINT32(sample, MFSamplePresenter_SampleCounter, (UINT32)-1);
if (token == m_tokenCounter) {
// Return the sample to the sample pool.
@@ -1811,9 +1847,9 @@ HRESULT EVRCustomPresenter::onSampleFree(IMFAsyncResult *result)
done:
if (FAILED(hr))
notifyEvent(EC_ERRORABORT, hr, 0);
- qt_wmf_safeRelease(&object);
- qt_wmf_safeRelease(&sample);
- qt_wmf_safeRelease(&unk);
+ qt_evr_safe_release(&object);
+ qt_evr_safe_release(&sample);
+ qt_evr_safe_release(&unk);
return hr;
}
@@ -1843,7 +1879,7 @@ float EVRCustomPresenter::getMaxRate(bool thin)
UINT monitorRateHz = 0;
if (!thin && m_mediaType) {
- qt_wmf_getFrameRate(m_mediaType, &fps);
+ qt_evr_getFrameRate(m_mediaType, &fps);
monitorRateHz = m_D3DPresentEngine->refreshRate();
if (fps.Denominator && fps.Numerator && monitorRateHz) {
@@ -1867,7 +1903,7 @@ HRESULT setDesiredSampleTime(IMFSample *sample, const LONGLONG &sampleTime, cons
if (SUCCEEDED(hr))
desired->SetDesiredSampleTimeAndDuration(sampleTime, duration);
- qt_wmf_safeRelease(&desired);
+ qt_evr_safe_release(&desired);
return hr;
}
@@ -1907,8 +1943,8 @@ HRESULT clearDesiredSampleTime(IMFSample *sample)
}
done:
- qt_wmf_safeRelease(&unkSwapChain);
- qt_wmf_safeRelease(&desired);
+ qt_evr_safe_release(&unkSwapChain);
+ qt_evr_safe_release(&desired);
return hr;
}
@@ -1921,7 +1957,7 @@ HRESULT setMixerSourceRect(IMFTransform *mixer, const MFVideoNormalizedRect &sou
HRESULT hr = mixer->GetAttributes(&attributes);
if (SUCCEEDED(hr)) {
- hr = attributes->SetBlob(VIDEO_ZOOM_RECT, (const UINT8*)&sourceRect, sizeof(sourceRect));
+ hr = attributes->SetBlob(video_ZOOM_RECT, (const UINT8*)&sourceRect, sizeof(sourceRect));
attributes->Release();
}
return hr;
@@ -1986,60 +2022,3 @@ static QVideoFrame::PixelFormat pixelFormatFromMediaType(IMFMediaType *type)
return QVideoFrame::Format_Invalid;
}
-
-
-EVRCustomPresenterActivate::EVRCustomPresenterActivate()
- : MFAbstractActivate()
- , m_presenter(0)
- , m_surface(0)
-{ }
-
-HRESULT EVRCustomPresenterActivate::ActivateObject(REFIID riid, void **ppv)
-{
- if (!ppv)
- return E_INVALIDARG;
- QMutexLocker locker(&m_mutex);
- if (!m_presenter) {
- m_presenter = new EVRCustomPresenter;
- if (m_surface)
- m_presenter->setSurface(m_surface);
- }
- return m_presenter->QueryInterface(riid, ppv);
-}
-
-HRESULT EVRCustomPresenterActivate::ShutdownObject()
-{
- // The presenter does not implement IMFShutdown so
- // this function is the same as DetachObject()
- return DetachObject();
-}
-
-HRESULT EVRCustomPresenterActivate::DetachObject()
-{
- QMutexLocker locker(&m_mutex);
- if (m_presenter) {
- m_presenter->Release();
- m_presenter = 0;
- }
- return S_OK;
-}
-
-void EVRCustomPresenterActivate::setSurface(QAbstractVideoSurface *surface)
-{
- QMutexLocker locker(&m_mutex);
- if (m_surface == surface)
- return;
-
- m_surface = surface;
-
- if (m_presenter)
- m_presenter->setSurface(surface);
-}
-
-void EVRCustomPresenterActivate::supportedFormatsChanged()
-{
- QMutexLocker locker(&m_mutex);
-
- if (m_presenter)
- m_presenter->supportedFormatsChanged();
-}
diff --git a/src/plugins/wmf/evrcustompresenter.h b/src/plugins/common/evr/evrcustompresenter.h
index 1d24feaa5..b9067d9ae 100644
--- a/src/plugins/wmf/evrcustompresenter.h
+++ b/src/plugins/common/evr/evrcustompresenter.h
@@ -37,14 +37,67 @@
#include <QObject>
#include <qmutex.h>
#include <qqueue.h>
-#include <evr.h>
-#include "mfactivate.h"
-QT_BEGIN_NAMESPACE
+#include "evrdefs.h"
+
+QT_USE_NAMESPACE
class D3DPresentEngine;
class QAbstractVideoSurface;
+template<class T>
+class AsyncCallback : public IMFAsyncCallback
+{
+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)
+ {
+ 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() {
+ // Delegate to parent class.
+ return m_parent->AddRef();
+ }
+ STDMETHODIMP_(ULONG) Release() {
+ // Delegate to parent class.
+ return m_parent->Release();
+ }
+
+ // IMFAsyncCallback methods
+ STDMETHODIMP GetParameters(DWORD*, DWORD*)
+ {
+ // Implementation of this method is optional.
+ return E_NOTIMPL;
+ }
+
+ STDMETHODIMP Invoke(IMFAsyncResult* asyncResult)
+ {
+ return (m_parent->*m_invokeFn)(asyncResult);
+ }
+
+ T *m_parent;
+ InvokeFn m_invokeFn;
+};
+
class Scheduler
{
public:
@@ -250,7 +303,7 @@ private:
// Callback when a video sample is released.
HRESULT onSampleFree(IMFAsyncResult *result);
- AsyncCallback<EVRCustomPresenter> m_sampleFreeCB;
+ AsyncCallback<EVRCustomPresenter> m_sampleFreeCB;
// Holds information related to frame-stepping.
struct FrameStep
@@ -258,7 +311,7 @@ private:
FrameStep()
: state(FrameStepNone)
, steps(0)
- , sampleNoRef(NULL)
+ , sampleNoRef(0)
{
}
@@ -300,26 +353,6 @@ private:
QList<DWORD> m_supportedGLFormats;
};
-class EVRCustomPresenterActivate : public MFAbstractActivate
-{
-public:
- EVRCustomPresenterActivate();
- ~EVRCustomPresenterActivate()
- { }
-
- STDMETHODIMP ActivateObject(REFIID riid, void **ppv);
- STDMETHODIMP ShutdownObject();
- STDMETHODIMP DetachObject();
-
- void setSurface(QAbstractVideoSurface *surface);
- void supportedFormatsChanged();
-
-private:
- EVRCustomPresenter *m_presenter;
- QAbstractVideoSurface *m_surface;
- QMutex m_mutex;
-};
-
-QT_END_NAMESPACE
+bool qt_evr_setCustomPresenter(IUnknown *evr, EVRCustomPresenter *presenter);
#endif // EVRCUSTOMPRESENTER_H
diff --git a/src/plugins/wmf/evrd3dpresentengine.cpp b/src/plugins/common/evr/evrd3dpresentengine.cpp
index d66918a99..61cee88d7 100644
--- a/src/plugins/wmf/evrd3dpresentengine.cpp
+++ b/src/plugins/common/evr/evrd3dpresentengine.cpp
@@ -33,7 +33,7 @@
#include "evrd3dpresentengine.h"
-#include "mfglobal.h"
+#include "evrhelpers.h"
#include <qtgui/qguiapplication.h>
#include <qpa/qplatformnativeinterface.h>
@@ -53,9 +53,7 @@
#include <WinUser.h>
#include <evr.h>
-QT_USE_NAMESPACE
-
-static const DWORD PRESENTER_BUFFER_COUNT = 3;
+static const int PRESENTER_BUFFER_COUNT = 3;
class TextureVideoBuffer : public QAbstractVideoBuffer
{
@@ -174,10 +172,10 @@ D3DPresentEngine::D3DPresentEngine()
D3DPresentEngine::~D3DPresentEngine()
{
- qt_wmf_safeRelease(&m_texture);
- qt_wmf_safeRelease(&m_device);
- qt_wmf_safeRelease(&m_deviceManager);
- qt_wmf_safeRelease(&m_D3D9);
+ qt_evr_safe_release(&m_texture);
+ qt_evr_safe_release(&m_device);
+ qt_evr_safe_release(&m_deviceManager);
+ qt_evr_safe_release(&m_D3D9);
if (m_eglSurface) {
m_egl->releaseTexImage(m_eglDisplay, m_eglSurface, EGL_BACK_BUFFER);
@@ -309,16 +307,16 @@ HRESULT D3DPresentEngine::createVideoSamples(IMFMediaType *format, QList<IMFSamp
if (FAILED(hr))
goto done;
- qt_wmf_safeRelease(&videoSample);
- qt_wmf_safeRelease(&swapChain);
+ qt_evr_safe_release(&videoSample);
+ qt_evr_safe_release(&swapChain);
}
done:
if (FAILED(hr))
releaseResources();
- qt_wmf_safeRelease(&swapChain);
- qt_wmf_safeRelease(&videoSample);
+ qt_evr_safe_release(&swapChain);
+ qt_evr_safe_release(&videoSample);
return hr;
}
@@ -342,7 +340,7 @@ void D3DPresentEngine::presentSample(void *opaque, qint64)
goto done;
// Get the surface from the buffer.
- hr = MFGetService(buffer, MR_BUFFER_SERVICE, IID_PPV_ARGS(&surface));
+ hr = MFGetService(buffer, mr_BUFFER_SERVICE, IID_PPV_ARGS(&surface));
if (FAILED(hr))
goto done;
}
@@ -367,9 +365,9 @@ void D3DPresentEngine::presentSample(void *opaque, qint64)
}
done:
- qt_wmf_safeRelease(&surface);
- qt_wmf_safeRelease(&buffer);
- qt_wmf_safeRelease(&sample);
+ qt_evr_safe_release(&surface);
+ qt_evr_safe_release(&buffer);
+ qt_evr_safe_release(&sample);
}
void D3DPresentEngine::setSurface(QAbstractVideoSurface *surface)
@@ -492,7 +490,7 @@ bool D3DPresentEngine::updateTexture(IDirect3DSurface9 *src)
m_egl->bindTexImage(m_eglDisplay, m_eglSurface, EGL_BACK_BUFFER);
done:
- qt_wmf_safeRelease(&dest);
+ qt_evr_safe_release(&dest);
if (m_glContext)
m_glContext->doneCurrent();
@@ -577,13 +575,13 @@ HRESULT D3DPresentEngine::createD3DDevice()
if (FAILED(hr))
goto done;
- qt_wmf_safeRelease(&m_device);
+ qt_evr_safe_release(&m_device);
m_device = device;
m_device->AddRef();
done:
- qt_wmf_safeRelease(&device);
+ qt_evr_safe_release(&device);
return hr;
}
@@ -612,8 +610,8 @@ HRESULT D3DPresentEngine::createD3DSample(IDirect3DSwapChain9 *swapChain, IMFSam
(*videoSample)->AddRef();
done:
- qt_wmf_safeRelease(&surface);
- qt_wmf_safeRelease(&sample);
+ qt_evr_safe_release(&surface);
+ qt_evr_safe_release(&sample);
return hr;
}
@@ -631,7 +629,7 @@ HRESULT D3DPresentEngine::getSwapChainPresentParameters(IMFMediaType *type, D3DP
DWORD d3dFormat = 0;
- hr = qt_wmf_getFourCC(type, &d3dFormat);
+ hr = qt_evr_getFourCC(type, &d3dFormat);
if (FAILED(hr))
return hr;
diff --git a/src/plugins/wmf/evrd3dpresentengine.h b/src/plugins/common/evr/evrd3dpresentengine.h
index 7a88ee555..df695a5dd 100644
--- a/src/plugins/wmf/evrd3dpresentengine.h
+++ b/src/plugins/common/evr/evrd3dpresentengine.h
@@ -57,7 +57,7 @@ static const GUID MFSamplePresenter_SampleCounter =
static const GUID MFSamplePresenter_SampleSwapChain =
{ 0xad885bd1, 0x7def, 0x414a, { 0xb5, 0xb0, 0xd3, 0xd2, 0x63, 0xd6, 0xe9, 0x6d } };
-QT_BEGIN_NAMESPACE
+QT_USE_NAMESPACE
class QAbstractVideoSurface;
class QOpenGLContext;
@@ -143,6 +143,4 @@ private:
EGLWrapper *m_egl;
};
-QT_END_NAMESPACE
-
#endif // EVRD3DPRESENTENGINE_H
diff --git a/src/plugins/common/evr/evrdefs.cpp b/src/plugins/common/evr/evrdefs.cpp
new file mode 100644
index 000000000..07d1c11eb
--- /dev/null
+++ b/src/plugins/common/evr/evrdefs.cpp
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $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
index ce6ca6584..3b2c2530a 100644
--- a/src/plugins/common/evr/evrdefs.h
+++ b/src/plugins/common/evr/evrdefs.h
@@ -36,10 +36,47 @@
#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
+
#ifdef __GNUC__
typedef struct MFVideoNormalizedRect {
float left;
@@ -49,6 +86,8 @@ typedef struct MFVideoNormalizedRect {
} 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);
@@ -123,5 +162,185 @@ __CRT_UUID_DECL(IMFVideoProcessor, 0x6AB0000C, 0xFECE, 0x4d1f, 0xA2,0xAC, 0xA9,0
#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/wmf/mfglobal.cpp b/src/plugins/common/evr/evrhelpers.cpp
index 55f2882db..ae289de3a 100644
--- a/src/plugins/wmf/mfglobal.cpp
+++ b/src/plugins/common/evr/evrhelpers.cpp
@@ -31,9 +31,9 @@
**
****************************************************************************/
-#include "mfglobal.h"
+#include "evrhelpers.h"
-HRESULT qt_wmf_getFourCC(IMFMediaType *type, DWORD *fourCC)
+HRESULT qt_evr_getFourCC(IMFMediaType *type, DWORD *fourCC)
{
if (!fourCC)
return E_POINTER;
@@ -50,20 +50,7 @@ HRESULT qt_wmf_getFourCC(IMFMediaType *type, DWORD *fourCC)
return hr;
}
-MFRatio qt_wmf_getPixelAspectRatio(IMFMediaType *type)
-{
- MFRatio ratio = { 0, 0 };
- HRESULT hr = S_OK;
-
- hr = MFGetAttributeRatio(type, MF_MT_PIXEL_ASPECT_RATIO, (UINT32*)&ratio.Numerator, (UINT32*)&ratio.Denominator);
- if (FAILED(hr)) {
- ratio.Numerator = 1;
- ratio.Denominator = 1;
- }
- return ratio;
-}
-
-bool qt_wmf_areMediaTypesEqual(IMFMediaType *type1, IMFMediaType *type2)
+bool qt_evr_areMediaTypesEqual(IMFMediaType *type1, IMFMediaType *type2)
{
if (!type1 && !type2)
return true;
@@ -76,10 +63,10 @@ bool qt_wmf_areMediaTypesEqual(IMFMediaType *type1, IMFMediaType *type2)
return (hr == S_OK);
}
-HRESULT qt_wmf_validateVideoArea(const MFVideoArea& area, UINT32 width, UINT32 height)
+HRESULT qt_evr_validateVideoArea(const MFVideoArea& area, UINT32 width, UINT32 height)
{
- float fOffsetX = qt_wmf_MFOffsetToFloat(area.OffsetX);
- float fOffsetY = qt_wmf_MFOffsetToFloat(area.OffsetY);
+ 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) )
@@ -88,7 +75,7 @@ HRESULT qt_wmf_validateVideoArea(const MFVideoArea& area, UINT32 width, UINT32 h
return S_OK;
}
-bool qt_wmf_isSampleTimePassed(IMFClock *clock, IMFSample *sample)
+bool qt_evr_isSampleTimePassed(IMFClock *clock, IMFSample *sample)
{
if (!sample || !clock)
return false;
diff --git a/src/plugins/common/evr/evrhelpers.h b/src/plugins/common/evr/evrhelpers.h
new file mode 100644
index 000000000..3883379a0
--- /dev/null
+++ b/src/plugins/common/evr/evrhelpers.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef EVRHELPERS_H
+#define EVRHELPERS_H
+
+#include "evrdefs.h"
+
+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, (UINT32*)&pRatio->Numerator, (UINT32*)&pRatio->Denominator);
+}
+
+#endif // EVRHELPERS_H
+
diff --git a/src/plugins/common/evr/evrvideowindowcontrol.cpp b/src/plugins/common/evr/evrvideowindowcontrol.cpp
index faa23d6e5..dae6583ff 100644
--- a/src/plugins/common/evr/evrvideowindowcontrol.cpp
+++ b/src/plugins/common/evr/evrvideowindowcontrol.cpp
@@ -65,8 +65,6 @@ bool EvrVideoWindowControl::setEvr(IUnknown *evr)
if (!evr)
return true;
- static const GUID mr_VIDEO_RENDER_SERVICE = { 0x1092a86c, 0xab1a, 0x459a, {0xa3, 0x36, 0x83, 0x1f, 0xbc, 0x4d, 0x11, 0xff} };
- static const GUID mr_VIDEO_MIXER_SERVICE = { 0x73cd2fc, 0x6cf4, 0x40b7, {0x88, 0x59, 0xe8, 0x95, 0x52, 0xc8, 0x41, 0xf8} };
IMFGetService *service = NULL;
if (SUCCEEDED(evr->QueryInterface(IID_PPV_ARGS(&service)))
diff --git a/src/plugins/directshow/player/directshowevrvideowindowcontrol.cpp b/src/plugins/directshow/player/directshowevrvideowindowcontrol.cpp
index 7bffe47d2..22771bd4c 100644
--- a/src/plugins/directshow/player/directshowevrvideowindowcontrol.cpp
+++ b/src/plugins/directshow/player/directshowevrvideowindowcontrol.cpp
@@ -49,10 +49,8 @@ DirectShowEvrVideoWindowControl::~DirectShowEvrVideoWindowControl()
IBaseFilter *DirectShowEvrVideoWindowControl::filter()
{
- static const GUID clsid_EnhancendVideoRenderer = { 0xfa10746c, 0x9b63, 0x4b6c, {0xbc, 0x49, 0xfc, 0x30, 0xe, 0xa5, 0xf2, 0x56} };
-
if (!m_evrFilter) {
- m_evrFilter = com_new<IBaseFilter>(clsid_EnhancendVideoRenderer);
+ m_evrFilter = com_new<IBaseFilter>(clsid_EnhancedVideoRenderer);
if (!setEvr(m_evrFilter)) {
m_evrFilter->Release();
m_evrFilter = NULL;
diff --git a/src/plugins/directshow/player/directshowvideorenderercontrol.cpp b/src/plugins/directshow/player/directshowvideorenderercontrol.cpp
index 6a1580ea5..6754c1852 100644
--- a/src/plugins/directshow/player/directshowvideorenderercontrol.cpp
+++ b/src/plugins/directshow/player/directshowvideorenderercontrol.cpp
@@ -35,11 +35,21 @@
#include "videosurfacefilter.h"
+#ifdef CUSTOM_EVR_PRESENTER
+#include "evrcustompresenter.h"
+#endif
+
+#include <qabstractvideosurface.h>
+#include <QtMultimedia/private/qmediaopenglhelper_p.h>
+
DirectShowVideoRendererControl::DirectShowVideoRendererControl(DirectShowEventLoop *loop, QObject *parent)
: QVideoRendererControl(parent)
, m_loop(loop)
, m_surface(0)
, m_filter(0)
+#ifdef CUSTOM_EVR_PRESENTER
+ , m_evrPresenter(0)
+#endif
{
}
@@ -47,6 +57,10 @@ DirectShowVideoRendererControl::~DirectShowVideoRendererControl()
{
if (m_filter)
m_filter->Release();
+#ifdef CUSTOM_EVR_PRESENTER
+ if (m_evrPresenter)
+ m_evrPresenter->Release();
+#endif
}
QAbstractVideoSurface *DirectShowVideoRendererControl::surface() const
@@ -59,18 +73,34 @@ void DirectShowVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
if (surface != m_surface) {
m_surface = surface;
- VideoSurfaceFilter *existingFilter = m_filter;
+ IBaseFilter *currentFilter = m_filter;
+ m_filter = 0;
if (surface) {
- m_filter = new VideoSurfaceFilter(surface, m_loop);
- } else {
- m_filter = 0;
+#ifdef CUSTOM_EVR_PRESENTER
+ if (!surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).isEmpty()
+ && QMediaOpenGLHelper::isANGLE()) {
+ m_evrPresenter = new EVRCustomPresenter;
+ m_evrPresenter->setSurface(surface);
+ m_filter = com_new<IBaseFilter>(clsid_EnhancedVideoRenderer);
+ if (!qt_evr_setCustomPresenter(m_filter, m_evrPresenter)) {
+ m_evrPresenter->Release();
+ m_evrPresenter = 0;
+ m_filter->Release();
+ m_filter = 0;
+ }
+ }
+ if (!m_filter)
+#endif
+ {
+ m_filter = new VideoSurfaceFilter(surface, m_loop);
+ }
}
emit filterChanged();
- if (existingFilter)
- existingFilter->Release();
+ if (currentFilter)
+ currentFilter->Release();
}
}
diff --git a/src/plugins/directshow/player/directshowvideorenderercontrol.h b/src/plugins/directshow/player/directshowvideorenderercontrol.h
index b4828d1b0..e6f0bb3af 100644
--- a/src/plugins/directshow/player/directshowvideorenderercontrol.h
+++ b/src/plugins/directshow/player/directshowvideorenderercontrol.h
@@ -41,6 +41,10 @@
class DirectShowEventLoop;
class VideoSurfaceFilter;
+#ifdef CUSTOM_EVR_PRESENTER
+class EVRCustomPresenter;
+#endif
+
QT_USE_NAMESPACE
class DirectShowVideoRendererControl : public QVideoRendererControl
@@ -61,7 +65,11 @@ Q_SIGNALS:
private:
DirectShowEventLoop *m_loop;
QAbstractVideoSurface *m_surface;
- VideoSurfaceFilter *m_filter;
+ IBaseFilter *m_filter;
+
+#ifdef CUSTOM_EVR_PRESENTER
+ EVRCustomPresenter *m_evrPresenter;
+#endif
};
#endif
diff --git a/src/plugins/directshow/player/player.pri b/src/plugins/directshow/player/player.pri
index 8586ea5da..5ecb912b2 100644
--- a/src/plugins/directshow/player/player.pri
+++ b/src/plugins/directshow/player/player.pri
@@ -46,8 +46,11 @@ config_evr {
include($$PWD/../../common/evr.pri)
- HEADERS += $$PWD/directshowevrvideowindowcontrol.h
- SOURCES += $$PWD/directshowevrvideowindowcontrol.cpp
+ HEADERS += \
+ $$PWD/directshowevrvideowindowcontrol.h
+
+ SOURCES += \
+ $$PWD/directshowevrvideowindowcontrol.cpp
}
config_wshellitem {
diff --git a/src/plugins/wmf/mfactivate.h b/src/plugins/wmf/mfactivate.h
index 878e30d4d..8b8e51b56 100644
--- a/src/plugins/wmf/mfactivate.h
+++ b/src/plugins/wmf/mfactivate.h
@@ -34,8 +34,6 @@
#ifndef MFACTIVATE_H
#define MFACTIVATE_H
-#include "mfglobal.h"
-
#include <mfidl.h>
class MFAbstractActivate : public IMFActivate
diff --git a/src/plugins/wmf/mfglobal.h b/src/plugins/wmf/mfglobal.h
deleted file mode 100644
index 073f959f7..000000000
--- a/src/plugins/wmf/mfglobal.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://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 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MFGLOBAL_H
-#define MFGLOBAL_H
-
-#include <mfapi.h>
-#include <mfidl.h>
-#include <Mferror.h>
-
-
-template<class T>
-class AsyncCallback : public IMFAsyncCallback
-{
-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)
- {
- 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() {
- // Delegate to parent class.
- return m_parent->AddRef();
- }
- STDMETHODIMP_(ULONG) Release() {
- // Delegate to parent class.
- return m_parent->Release();
- }
-
-
- // IMFAsyncCallback methods
- STDMETHODIMP GetParameters(DWORD*, DWORD*)
- {
- // Implementation of this method is optional.
- return E_NOTIMPL;
- }
-
- STDMETHODIMP Invoke(IMFAsyncResult* asyncResult)
- {
- return (m_parent->*m_invokeFn)(asyncResult);
- }
-
- T *m_parent;
- InvokeFn m_invokeFn;
-};
-
-template <class T> void qt_wmf_safeRelease(T **ppT)
-{
- if (*ppT) {
- (*ppT)->Release();
- *ppT = NULL;
- }
-}
-
-template <class T>
-void qt_wmf_copyComPointer(T* &dest, T *src)
-{
- if (dest)
- dest->Release();
- dest = src;
- if (dest)
- dest->AddRef();
-}
-
-HRESULT qt_wmf_getFourCC(IMFMediaType *type, DWORD *fourCC);
-MFRatio qt_wmf_getPixelAspectRatio(IMFMediaType *type);
-bool qt_wmf_areMediaTypesEqual(IMFMediaType *type1, IMFMediaType *type2);
-HRESULT qt_wmf_validateVideoArea(const MFVideoArea& area, UINT32 width, UINT32 height);
-bool qt_wmf_isSampleTimePassed(IMFClock *clock, IMFSample *sample);
-
-inline float qt_wmf_MFOffsetToFloat(const MFOffset& offset)
-{
- return offset.value + (float(offset.fract) / 65536);
-}
-
-inline MFOffset qt_wmf_makeMFOffset(float v)
-{
- MFOffset offset;
- offset.value = short(v);
- offset.fract = WORD(65536 * (v-offset.value));
- return offset;
-}
-
-inline MFVideoArea qt_wmf_makeMFArea(float x, float y, DWORD width, DWORD height)
-{
- MFVideoArea area;
- area.OffsetX = qt_wmf_makeMFOffset(x);
- area.OffsetY = qt_wmf_makeMFOffset(y);
- area.Area.cx = width;
- area.Area.cy = height;
- return area;
-}
-
-inline HRESULT qt_wmf_getFrameRate(IMFMediaType *pType, MFRatio *pRatio)
-{
- return MFGetAttributeRatio(pType, MF_MT_FRAME_RATE, (UINT32*)&pRatio->Numerator, (UINT32*)&pRatio->Denominator);
-}
-
-
-#endif // MFGLOBAL_H
diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.cpp b/src/plugins/wmf/player/mfvideorenderercontrol.cpp
index 32806a852..365cf537d 100644
--- a/src/plugins/wmf/player/mfvideorenderercontrol.cpp
+++ b/src/plugins/wmf/player/mfvideorenderercontrol.cpp
@@ -32,13 +32,9 @@
****************************************************************************/
#include "mfvideorenderercontrol.h"
-#include "mfglobal.h"
+#include "mfactivate.h"
-#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
-#define MAYBE_ANGLE
-#endif
-
-#ifdef MAYBE_ANGLE
+#ifdef CUSTOM_EVR_PRESENTER
#include "evrcustompresenter.h"
#endif
@@ -2226,12 +2222,37 @@ namespace
};
}
+#ifdef CUSTOM_EVR_PRESENTER
+
+class EVRCustomPresenterActivate : public MFAbstractActivate
+{
+public:
+ EVRCustomPresenterActivate();
+ ~EVRCustomPresenterActivate()
+ { }
+
+ STDMETHODIMP ActivateObject(REFIID riid, void **ppv);
+ STDMETHODIMP ShutdownObject();
+ STDMETHODIMP DetachObject();
+
+ void setSurface(QAbstractVideoSurface *surface);
+
+private:
+ EVRCustomPresenter *m_presenter;
+ QAbstractVideoSurface *m_surface;
+ QMutex m_mutex;
+};
+
+#endif // CUSTOM_EVR_PRESENTER
+
MFVideoRendererControl::MFVideoRendererControl(QObject *parent)
: QVideoRendererControl(parent)
, m_surface(0)
, m_currentActivate(0)
, m_callback(0)
+#ifdef CUSTOM_EVR_PRESENTER
, m_presenterActivate(0)
+#endif
{
}
@@ -2245,7 +2266,7 @@ void MFVideoRendererControl::clear()
if (m_surface)
m_surface->stop();
-#ifdef MAYBE_ANGLE
+#ifdef CUSTOM_EVR_PRESENTER
if (m_presenterActivate) {
m_presenterActivate->ShutdownObject();
m_presenterActivate->Release();
@@ -2280,7 +2301,7 @@ void MFVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged()));
}
-#ifdef MAYBE_ANGLE
+#ifdef CUSTOM_EVR_PRESENTER
if (m_presenterActivate)
m_presenterActivate->setSurface(m_surface);
else
@@ -2291,8 +2312,10 @@ void MFVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
void MFVideoRendererControl::customEvent(QEvent *event)
{
+#ifdef CUSTOM_EVR_PRESENTER
if (m_presenterActivate)
return;
+#endif
if (!m_currentActivate)
return;
@@ -2323,19 +2346,16 @@ void MFVideoRendererControl::customEvent(QEvent *event)
void MFVideoRendererControl::supportedFormatsChanged()
{
-#ifdef MAYBE_ANGLE
- if (m_presenterActivate)
- m_presenterActivate->supportedFormatsChanged();
- else
-#endif
if (m_currentActivate)
static_cast<VideoRendererActivate*>(m_currentActivate)->supportedFormatsChanged();
}
void MFVideoRendererControl::present()
{
+#ifdef CUSTOM_EVR_PRESENTER
if (m_presenterActivate)
return;
+#endif
if (m_currentActivate)
static_cast<VideoRendererActivate*>(m_currentActivate)->present();
@@ -2347,7 +2367,7 @@ IMFActivate* MFVideoRendererControl::createActivate()
clear();
-#ifdef MAYBE_ANGLE
+#ifdef CUSTOM_EVR_PRESENTER
// We can use the EVR with our custom presenter only if the surface supports OpenGL
// texture handles. We also require ANGLE (due to the D3D interop).
if (!m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).isEmpty()
@@ -2368,5 +2388,57 @@ IMFActivate* MFVideoRendererControl::createActivate()
return m_currentActivate;
}
+#ifdef CUSTOM_EVR_PRESENTER
+
+EVRCustomPresenterActivate::EVRCustomPresenterActivate()
+ : MFAbstractActivate()
+ , m_presenter(0)
+ , m_surface(0)
+{ }
+
+HRESULT EVRCustomPresenterActivate::ActivateObject(REFIID riid, void **ppv)
+{
+ if (!ppv)
+ return E_INVALIDARG;
+ QMutexLocker locker(&m_mutex);
+ if (!m_presenter) {
+ m_presenter = new EVRCustomPresenter;
+ if (m_surface)
+ m_presenter->setSurface(m_surface);
+ }
+ return m_presenter->QueryInterface(riid, ppv);
+}
+
+HRESULT EVRCustomPresenterActivate::ShutdownObject()
+{
+ // The presenter does not implement IMFShutdown so
+ // this function is the same as DetachObject()
+ return DetachObject();
+}
+
+HRESULT EVRCustomPresenterActivate::DetachObject()
+{
+ QMutexLocker locker(&m_mutex);
+ if (m_presenter) {
+ m_presenter->Release();
+ m_presenter = 0;
+ }
+ return S_OK;
+}
+
+void EVRCustomPresenterActivate::setSurface(QAbstractVideoSurface *surface)
+{
+ QMutexLocker locker(&m_mutex);
+ if (m_surface == surface)
+ return;
+
+ m_surface = surface;
+
+ if (m_presenter)
+ m_presenter->setSurface(surface);
+}
+
+#endif // CUSTOM_EVR_PRESENTER
+
#include "moc_mfvideorenderercontrol.cpp"
#include "mfvideorenderercontrol.moc"
diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.h b/src/plugins/wmf/player/mfvideorenderercontrol.h
index ca3b95d10..8ef4feeef 100644
--- a/src/plugins/wmf/player/mfvideorenderercontrol.h
+++ b/src/plugins/wmf/player/mfvideorenderercontrol.h
@@ -38,13 +38,11 @@
#include <mfapi.h>
#include <mfidl.h>
-QT_BEGIN_NAMESPACE
+QT_USE_NAMESPACE
+#ifdef CUSTOM_EVR_PRESENTER
class EVRCustomPresenterActivate;
-
-QT_END_NAMESPACE
-
-QT_USE_NAMESPACE
+#endif
class MFVideoRendererControl : public QVideoRendererControl
{
@@ -73,7 +71,9 @@ private:
IMFActivate *m_currentActivate;
IMFSampleGrabberSinkCallback *m_callback;
+#ifdef CUSTOM_EVR_PRESENTER
EVRCustomPresenterActivate *m_presenterActivate;
+#endif
};
#endif
diff --git a/src/plugins/wmf/wmf.pro b/src/plugins/wmf/wmf.pro
index 68a777f37..1f43bb128 100644
--- a/src/plugins/wmf/wmf.pro
+++ b/src/plugins/wmf/wmf.pro
@@ -17,7 +17,6 @@ HEADERS += \
sourceresolver.h \
samplegrabber.h \
mftvideo.h \
- mfglobal.h \
mfactivate.h
SOURCES += \
@@ -26,21 +25,7 @@ SOURCES += \
sourceresolver.cpp \
samplegrabber.cpp \
mftvideo.cpp \
- mfactivate.cpp \
- mfglobal.cpp
-
-contains(QT_CONFIG, angle)|contains(QT_CONFIG, dynamicgl) {
- LIBS += -ld3d9 -ldxva2 -lwinmm -levr
- QT += gui-private
-
- HEADERS += \
- $$PWD/evrcustompresenter.h \
- $$PWD/evrd3dpresentengine.h
-
- SOURCES += \
- $$PWD/evrcustompresenter.cpp \
- $$PWD/evrd3dpresentengine.cpp
-}
+ mfactivate.cpp
include (player/player.pri)
include (decoder/decoder.pri)