summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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)