diff options
Diffstat (limited to 'src')
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) |