diff --git a/Samples/BackgroundBlur/BackgroundBlur/BackgroundBlur.vcxproj b/Samples/BackgroundBlur/BackgroundBlur/BackgroundBlur.vcxproj index 0f808189..f9625dde 100644 --- a/Samples/BackgroundBlur/BackgroundBlur/BackgroundBlur.vcxproj +++ b/Samples/BackgroundBlur/BackgroundBlur/BackgroundBlur.vcxproj @@ -121,13 +121,13 @@ true _DEBUG;_WINDOWS;%(PreprocessorDefinitions) true - C:\Users\linneamay\.nuget\packages\microsoft.ai.machinelearning\1.9.1\build\native\include\abi;C:\Windows-Machine-Learning\Samples\BackgroundBlur\BackgroundBlur\common;C:\Windows-Machine-Learning\Samples\BackgroundBlur\DX11VideoRenderer;%(AdditionalIncludeDirectories) + C:\Users\linneamay\.nuget\packages\microsoft.ai.machinelearning\1.9.1\build\native\include\abi;$(SolutionDir)DX11VideoRenderer;common;%(AdditionalIncludeDirectories) stdcpp17 Windows true - C:\Program Files %28x86%29\Windows Kits\10\Lib\10.0.19041.0\um\x64;%(AdditionalLibraryDirectories) + C:\Program Files %28x86%29\Windows Kits\10\Lib\10.0.19041.0\um\$(PlatformShortName);%(AdditionalLibraryDirectories) C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x64\Mfplat.lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x64\Mf.lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x64\Mfcore.lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x64\evr.lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x64\mfuuid.lib;C:\Windows-Machine-Learning\Samples\BackgroundBlur\x64\Debug\DX11VideoRenderer.lib;%(AdditionalDependencies) diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/README.md b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/README.md deleted file mode 100644 index ada01ab5..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/README.md +++ /dev/null @@ -1,56 +0,0 @@ -DirectX video rendering sample -============================== - -This sample shows how to create a media sink that renders video output to a window using DirectX 11. - -Specifically, this sample shows how to: - -- Decode the video using the Media Foundation APIs -- Render the decoded video using the DirectX 11 APIs -- Output the video stream to multi-monitor displays - -For more info about the concepts and APIs demonstrated in this sample, see the following topics: - -- [Direct3D 11 graphics APIs](http://msdn.microsoft.com/en-us/library/windows/desktop/ff476080) -- [Media Foundation media APIs](http://msdn.microsoft.com/en-us/library/windows/desktop/ms694197) -- [DirectX Graphics Interface (DXGI) APIs](http://msdn.microsoft.com/en-us/library/windows/desktop/bb205169) - -**Note** This sample requires Microsoft Visual Studio 2013 or a later version (any SKU) and will not build in Microsoft Visual Studio Express 2013 for Windows . - -**Note** The Windows-classic-samples repo contains a variety of code samples that exercise the various programming models, platforms, features, and components available in Windows and/or Windows Server. This repo provides a Visual Studio solution (SLN) file for each sample, along with the source files, assets, resources, and metadata needed to compile and run the sample. For more info about the programming models, platforms, languages, and APIs demonstrated in these samples, check out the documentation on the [Windows Dev Center](https://dev.windows.com). This sample is provided as-is in order to indicate or demonstrate the functionality of the programming models and feature APIs for Windows and/or Windows Server. This sample was created for Windows 8.1 and/or Windows Server 2012 R2 using Visual Studio 2013, but in many cases it will run unaltered using later versions. This sample was created for Windows 8.1 and/or Windows Server 2012 R2 using Visual Studio 2013, but in many cases it will run unaltered using later versions. Please provide feedback on this sample! - -To get a copy of Windows, go to [Downloads and tools](http://go.microsoft.com/fwlink/p/?linkid=301696). - -To get a copy of Visual Studio, go to [Visual Studio Downloads](http://go.microsoft.com/fwlink/p/?linkid=301697). - -Related technologies --------------------- - -[Media Foundation](http://msdn.microsoft.com/en-us/library/windows/desktop/ms694197) - -Operating system requirements ------------------------------ - -Client - -Windows 8.1 - -Server - -Windows Server 2012 R2 - -Build the sample ----------------- - -To build this sample: - -1. Open the solutions (.sln) file titled DX11VideoRenderer.sln from Visual Studio. You'll find the solutions file in \<*install\_root*\>\\DX11VideoRenderer\\C++. -2. After the sample has loaded, press the F7 (or F6 for Visual Studio 2013) key or select **Build Solution** from the **Build** menu. - -Run the sample --------------- - -1. Register the DLL by running the command `regsvr32 DX11VideoRenderer.dll` from an elevated command prompt. -2. Run [the `topoedit.exe` program from the Windows SDK](https://docs.microsoft.com/en-us/windows/desktop/medfound/topoedit). -3. From the Topology menu, select "Add DX11 Video Renderer." -4. When you are finished using the sample, unregister the DLL by running the command `regsvr32 /u DX11VideoRenderer.dll` from an elevated command prompt. diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Activate.cpp b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Activate.cpp deleted file mode 100644 index ac706327..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Activate.cpp +++ /dev/null @@ -1,213 +0,0 @@ -#include "Activate.h" - -HRESULT DX11VideoRenderer::CActivate::CreateInstance(HWND hwnd, IMFActivate** ppActivate) -{ - if (ppActivate == NULL) - { - return E_POINTER; - } - - CActivate* pActivate = new CActivate(); - if (pActivate == NULL) - { - return E_OUTOFMEMORY; - } - - pActivate->AddRef(); - - HRESULT hr = S_OK; - - do - { - hr = pActivate->Initialize(); - if (FAILED(hr)) - { - break; - } - - hr = pActivate->QueryInterface(IID_PPV_ARGS(ppActivate)); - if (FAILED(hr)) - { - break; - } - - pActivate->m_hwnd = hwnd; - } - while (FALSE); - - SafeRelease(pActivate); - - return hr; -} - -// IUnknown -ULONG DX11VideoRenderer::CActivate::AddRef(void) -{ - return InterlockedIncrement(&m_lRefCount); -} - -// IUnknown -HRESULT DX11VideoRenderer::CActivate::QueryInterface(REFIID iid, __RPC__deref_out _Result_nullonfailure_ void** ppv) -{ - if (!ppv) - { - return E_POINTER; - } - if (iid == IID_IUnknown) - { - *ppv = static_cast(static_cast(this)); - } - else if (iid == __uuidof(IMFActivate)) - { - *ppv = static_cast(this); - } - else if (iid == __uuidof(IPersistStream)) - { - *ppv = static_cast(this); - } - else if (iid == __uuidof(IPersist)) - { - *ppv = static_cast(this); - } - else if (iid == __uuidof(IMFAttributes)) - { - *ppv = static_cast(this); - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -// IUnknown -ULONG DX11VideoRenderer::CActivate::Release(void) -{ - ULONG lRefCount = InterlockedDecrement(&m_lRefCount); - if (lRefCount == 0) - { - delete this; - } - return lRefCount; -} - -// IMFActivate -HRESULT DX11VideoRenderer::CActivate::ActivateObject(__RPC__in REFIID riid, __RPC__deref_out_opt void** ppvObject) -{ - HRESULT hr = S_OK; - IMFGetService* pSinkGetService = NULL; - IMFVideoDisplayControl* pSinkVideoDisplayControl = NULL; - - do - { - if (m_pMediaSink == NULL) - { - hr = CMediaSink::CreateInstance(IID_PPV_ARGS(&m_pMediaSink)); - if (FAILED(hr)) - { - break; - } - - hr = m_pMediaSink->QueryInterface(IID_PPV_ARGS(&pSinkGetService)); - if (FAILED(hr)) - { - break; - } - - hr = pSinkGetService->GetService(MR_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&pSinkVideoDisplayControl)); - if (FAILED(hr)) - { - break; - } - - hr = pSinkVideoDisplayControl->SetVideoWindow(m_hwnd); - if (FAILED(hr)) - { - break; - } - } - - hr = m_pMediaSink->QueryInterface(riid, ppvObject); - if (FAILED(hr)) - { - break; - } - } - while (FALSE); - - SafeRelease(pSinkGetService); - SafeRelease(pSinkVideoDisplayControl); - - return hr; -} - -// IMFActivate -HRESULT DX11VideoRenderer::CActivate::DetachObject(void) -{ - SafeRelease(m_pMediaSink); - - return S_OK; -} - -// IMFActivate -HRESULT DX11VideoRenderer::CActivate::ShutdownObject(void) -{ - if (m_pMediaSink != NULL) - { - m_pMediaSink->Shutdown(); - SafeRelease(m_pMediaSink); - } - - return S_OK; -} - -// IPersistStream -HRESULT DX11VideoRenderer::CActivate::GetSizeMax(__RPC__out ULARGE_INTEGER* pcbSize) -{ - return E_NOTIMPL; -} - -// IPersistStream -HRESULT DX11VideoRenderer::CActivate::IsDirty(void) -{ - return E_NOTIMPL; -} - -// IPersistStream -HRESULT DX11VideoRenderer::CActivate::Load(__RPC__in_opt IStream* pStream) -{ - return E_NOTIMPL; -} - -// IPersistStream -HRESULT DX11VideoRenderer::CActivate::Save(__RPC__in_opt IStream* pStream, BOOL bClearDirty) -{ - return E_NOTIMPL; -} - -// IPersist -HRESULT DX11VideoRenderer::CActivate::GetClassID(__RPC__out CLSID* pClassID) -{ - if (pClassID == NULL) - { - return E_POINTER; - } - *pClassID = CLSID_DX11VideoRendererActivate; - return S_OK; -} - -// ctor -DX11VideoRenderer::CActivate::CActivate(void) : - m_lRefCount(0), - m_pMediaSink(NULL), - m_hwnd(NULL) -{ -} - -// dtor -DX11VideoRenderer::CActivate::~CActivate(void) -{ - SafeRelease(m_pMediaSink); -} diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Activate.h b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Activate.h deleted file mode 100644 index badc1197..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Activate.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include "Common.h" -#include "MFAttributesImpl.h" -#include "MediaSink.h" - -namespace DX11VideoRenderer -{ - class CActivate : public CMFAttributesImpl, public IPersistStream, private CBase - { - public: - - static HRESULT CreateInstance(HWND hwnd, IMFActivate** ppActivate); - - // IUnknown - STDMETHODIMP_(ULONG) AddRef(void); - STDMETHODIMP QueryInterface(REFIID riid, __RPC__deref_out _Result_nullonfailure_ void** ppvObject); - STDMETHODIMP_(ULONG) Release(void); - - // IMFActivate - STDMETHODIMP ActivateObject(__RPC__in REFIID riid, __RPC__deref_out_opt void** ppvObject); - STDMETHODIMP DetachObject(void); - STDMETHODIMP ShutdownObject(void); - - // IPersistStream - STDMETHODIMP GetSizeMax(__RPC__out ULARGE_INTEGER* pcbSize); - STDMETHODIMP IsDirty(void); - STDMETHODIMP Load(__RPC__in_opt IStream* pStream); - STDMETHODIMP Save(__RPC__in_opt IStream* pStream, BOOL bClearDirty); - - // IPersist (from IPersistStream) - STDMETHODIMP GetClassID(__RPC__out CLSID* pClassID); - - private: - - CActivate(void); - ~CActivate(void); - - long m_lRefCount; - IMFMediaSink* m_pMediaSink; - HWND m_hwnd; - }; -} diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/ClassFactory.cpp b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/ClassFactory.cpp deleted file mode 100644 index 64ff278f..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/ClassFactory.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include "ClassFactory.h" - -BOOL DX11VideoRenderer::CClassFactory::IsLocked(void) -{ - return (s_lLockCount == 0) ? FALSE : TRUE; -} - -DX11VideoRenderer::CClassFactory::CClassFactory(void) : - m_lRefCount(0) -{ -} - -DX11VideoRenderer::CClassFactory::~CClassFactory(void) -{ -} - -// IUnknown -ULONG DX11VideoRenderer::CClassFactory::AddRef(void) -{ - return InterlockedIncrement(&m_lRefCount); -} - -// IUnknown -HRESULT DX11VideoRenderer::CClassFactory::QueryInterface(REFIID iid, __RPC__deref_out _Result_nullonfailure_ void** ppv) -{ - if (!ppv) - { - return E_POINTER; - } - if (iid == IID_IUnknown) - { - *ppv = static_cast(static_cast(this)); - } - else if (iid == __uuidof(IClassFactory)) - { - *ppv = static_cast(this); - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -// IUnknown -ULONG DX11VideoRenderer::CClassFactory::Release(void) -{ - ULONG lRefCount = InterlockedDecrement(&m_lRefCount); - if (lRefCount == 0) - { - delete this; - } - return lRefCount; -} - -// IClassFactory -HRESULT DX11VideoRenderer::CClassFactory::CreateInstance(_In_opt_ IUnknown* pUnkOuter, _In_ REFIID riid, _COM_Outptr_ void** ppvObject) -{ - if (ppvObject == NULL) - { - return E_POINTER; - } - - *ppvObject = NULL; - - if (pUnkOuter != NULL) - { - return CLASS_E_NOAGGREGATION; - } - - return CMediaSink::CreateInstance(riid, ppvObject); -} - -// IClassFactory -HRESULT DX11VideoRenderer::CClassFactory::LockServer(BOOL bLock) -{ - if (bLock == FALSE) - { - InterlockedDecrement(&s_lLockCount); - } - else - { - InterlockedIncrement(&s_lLockCount); - } - return S_OK; -} diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/ClassFactory.h b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/ClassFactory.h deleted file mode 100644 index 2b300960..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/ClassFactory.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "Common.h" -#include "MediaSink.h" - -namespace DX11VideoRenderer -{ - class CClassFactory : public IClassFactory, private CBase - { - public: - - static BOOL IsLocked(void); - - CClassFactory(void); - ~CClassFactory(void); - - // IUnknown - STDMETHODIMP_(ULONG) AddRef(void); - STDMETHODIMP QueryInterface(REFIID riid, __RPC__deref_out _Result_nullonfailure_ void** ppvObject); - STDMETHODIMP_(ULONG) Release(void); - - // IClassFactory - STDMETHODIMP CreateInstance(_In_opt_ IUnknown* pUnkOuter, _In_ REFIID riid, _COM_Outptr_ void** ppvObject); - STDMETHODIMP LockServer(BOOL bLock); - - private: - - static volatile long s_lLockCount; - - long m_lRefCount; - }; -} diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Common.h b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Common.h deleted file mode 100644 index 189226b5..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Common.h +++ /dev/null @@ -1,386 +0,0 @@ -#pragma once - -#include -#include // for FLT_MAX -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include // for MEDIASUBTYPE_V216 -#include "DX11VideoRenderer.h" -#include "linklist.h" -#include "staticasynccallback.h" - -#ifndef CLSID_VideoProcessorMFT -//DEFINE_GUID(CLSID_VideoProcessorMFT, 0x88753b26, 0x5b24, 0x49bd, 0xb2, 0xe7, 0xc, 0x44, 0x5c, 0x78, 0xc9, 0x82); -#endif - -// MF_XVP_PLAYBACK_MODE -// Data type: UINT32 (treat as BOOL) -// If this attribute is TRUE, the XVP will run in playback mode where it will: -// 1) Allow caller to allocate D3D output samples -// 2) Not perform FRC -// 3) Allow last frame regeneration (repaint) -// This attribute should be set on the transform's attrbiute store prior to setting the input type. -DEFINE_GUID(MF_XVP_PLAYBACK_MODE, 0x3c5d293f, 0xad67, 0x4e29, 0xaf, 0x12, 0xcf, 0x3e, 0x23, 0x8a, 0xcc, 0xe9); - -namespace DX11VideoRenderer -{ - inline void SafeCloseHandle(HANDLE& h) - { - if (h != NULL) - { - CloseHandle(h); - h = NULL; - } - } - - template inline void SafeDelete(T*& pT) - { - delete pT; - pT = NULL; - } - - template inline void SafeDeleteArray(T*& pT) - { - delete[] pT; - pT = NULL; - } - - template inline void SafeRelease(T*& pT) - { - if (pT != NULL) - { - pT->Release(); - pT = NULL; - } - } - - template inline double TicksToMilliseconds(const T& t) - { - return t / 10000.0; - } - - template inline T MillisecondsToTicks(const T& t) - { - return t * 10000; - } - - // returns the greatest common divisor of A and B - inline int gcd(int A, int B) - { - int Temp; - - if (A < B) - { - Temp = A; - A = B; - B = Temp; - } - - while (B != 0) - { - Temp = A % B; - A = B; - B = Temp; - } - - return A; - } - - // Convert a fixed-point to a float. - inline float MFOffsetToFloat(const MFOffset& offset) - { - return (float)offset.value + ((float)offset.value / 65536.0f); - } - - inline RECT MFVideoAreaToRect(const MFVideoArea area) - { - float left = MFOffsetToFloat(area.OffsetX); - float top = MFOffsetToFloat(area.OffsetY); - - RECT rc = - { - int( left + 0.5f ), - int( top + 0.5f ), - int( left + area.Area.cx + 0.5f ), - int( top + area.Area.cy + 0.5f ) - }; - - return rc; - } - - inline MFOffset MakeOffset(float v) - { - MFOffset offset; - offset.value = short(v); - offset.fract = WORD(65536 * (v-offset.value)); - return offset; - } - - inline MFVideoArea MakeArea(float x, float y, DWORD width, DWORD height) - { - MFVideoArea area; - area.OffsetX = MakeOffset(x); - area.OffsetY = MakeOffset(y); - area.Area.cx = width; - area.Area.cy = height; - return area; - } - - class CBase - { - public: - - static long GetObjectCount(void) - { - return s_lObjectCount; - } - - protected: - - CBase(void) - { - InterlockedIncrement(&s_lObjectCount); - } - - ~CBase(void) - { - InterlockedDecrement(&s_lObjectCount); - } - - private: - - static volatile long s_lObjectCount; - }; - - ////////////////////////////////////////////////////////////////////////// - // CAsyncCallback [template] - // - // Description: - // Helper class that routes IMFAsyncCallback::Invoke calls to a class - // method on the parent class. - // - // Usage: - // Add this class as a member variable. In the parent class constructor, - // initialize the CAsyncCallback class like this: - // m_cb(this, &CYourClass::OnInvoke) - // where - // m_cb = CAsyncCallback object - // CYourClass = parent class - // OnInvoke = Method in the parent class to receive Invoke calls. - // - // The parent's OnInvoke method (you can name it anything you like) must - // have a signature that matches the InvokeFn typedef below. - ////////////////////////////////////////////////////////////////////////// - - // T: Type of the parent object - template - class CAsyncCallback : public IMFAsyncCallback - { - public: - - typedef HRESULT (T::*InvokeFn)(IMFAsyncResult* pAsyncResult); - - CAsyncCallback(T* pParent, InvokeFn fn) : - m_pParent(pParent), - m_pInvokeFn(fn) - { - } - - // IUnknown - STDMETHODIMP_(ULONG) AddRef(void) - { - // Delegate to parent class. - return m_pParent->AddRef(); - } - - STDMETHODIMP_(ULONG) Release(void) - { - // Delegate to parent class. - return m_pParent->Release(); - } - - STDMETHODIMP QueryInterface(REFIID iid, __RPC__deref_out _Result_nullonfailure_ void** ppv) - { - if (!ppv) - { - return E_POINTER; - } - if (iid == __uuidof(IUnknown)) - { - *ppv = static_cast(static_cast(this)); - } - else if (iid == __uuidof(IMFAsyncCallback)) - { - *ppv = static_cast(this); - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; - } - - // IMFAsyncCallback methods - STDMETHODIMP GetParameters(__RPC__out DWORD* pdwFlags, __RPC__out DWORD* pdwQueue) - { - // Implementation of this method is optional. - return E_NOTIMPL; - } - - STDMETHODIMP Invoke(__RPC__in_opt IMFAsyncResult* pAsyncResult) - { - return (m_pParent->*m_pInvokeFn)(pAsyncResult); - } - - private: - - T* m_pParent; - InvokeFn m_pInvokeFn; - }; - - //----------------------------------------------------------------------------- - // ThreadSafeQueue template - // Thread-safe queue of COM interface pointers. - // - // T: COM interface type. - // - // This class is used by the scheduler. - // - // Note: This class uses a critical section to protect the state of the queue. - // With a little work, the scheduler could probably use a lock-free queue. - //----------------------------------------------------------------------------- - - template - class ThreadSafeQueue - { - public: - - ThreadSafeQueue(void) - { - InitializeCriticalSection(&m_lock); - } - - virtual ~ThreadSafeQueue(void) - { - DeleteCriticalSection(&m_lock); - } - - HRESULT Queue(T* p) - { - EnterCriticalSection(&m_lock); - HRESULT hr = m_list.InsertBack(p); - LeaveCriticalSection(&m_lock); - return hr; - } - - HRESULT Dequeue(T** pp) - { - EnterCriticalSection(&m_lock); - HRESULT hr = S_OK; - if (m_list.IsEmpty()) - { - *pp = NULL; - hr = S_FALSE; - } - else - { - hr = m_list.RemoveFront(pp); - } - LeaveCriticalSection(&m_lock); - return hr; - } - - HRESULT PutBack(T* p) - { - EnterCriticalSection(&m_lock); - HRESULT hr = m_list.InsertFront(p); - LeaveCriticalSection(&m_lock); - return hr; - } - - DWORD GetCount(void) - { - EnterCriticalSection(&m_lock); - DWORD nCount = m_list.GetCount(); - LeaveCriticalSection(&m_lock); - return nCount; - } - - void Clear(void) - { - EnterCriticalSection(&m_lock); - m_list.Clear(); - LeaveCriticalSection(&m_lock); - } - - private: - - CRITICAL_SECTION m_lock; - ComPtrListEx m_list; - }; - - class CCritSec - { - public: - - CCritSec(void) : - m_cs() - { - InitializeCriticalSection(&m_cs); - } - - ~CCritSec(void) - { - DeleteCriticalSection(&m_cs); - } - - _Acquires_lock_(this->m_cs) - void Lock(void) - { - EnterCriticalSection(&m_cs); - } - - _Releases_lock_(this->m_cs) - void Unlock(void) - { - LeaveCriticalSection(&m_cs); - } - - private: - - CRITICAL_SECTION m_cs; - }; - - class CAutoLock - { - public: - - _Acquires_lock_(this->m_pLock->m_cs) - CAutoLock(CCritSec* pLock) : - m_pLock(pLock) - { - m_pLock->Lock(); - } - - _Releases_lock_(this->m_pLock->m_cs) - ~CAutoLock(void) - { - m_pLock->Unlock(); - } - - private: - - CCritSec* m_pLock; - }; -} diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/DLLMain.cpp b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/DLLMain.cpp deleted file mode 100644 index 65835969..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/DLLMain.cpp +++ /dev/null @@ -1,261 +0,0 @@ -#include -#include "Common.h" -#include "Activate.h" -#include "ClassFactory.h" -#include "MediaSink.h" - -HMODULE g_hModule = NULL; -volatile long DX11VideoRenderer::CBase::s_lObjectCount = 0; -volatile long DX11VideoRenderer::CClassFactory::s_lLockCount = 0; - -// helper functions - -/////////////////////////////////////////////////////////////////////// -// Name: CreateObjectKeyName -// Desc: Converts a CLSID into a string with the form "CLSID\{clsid}" -/////////////////////////////////////////////////////////////////////// - -HRESULT CreateObjectKeyName(const GUID& guid, _Out_writes_(cchMax) TCHAR* pszName, DWORD cchMax) -{ - pszName[0] = _T('\0'); - - // convert CLSID to string - OLECHAR pszCLSID[CHARS_IN_GUID]; - HRESULT hr = StringFromGUID2(guid, pszCLSID, CHARS_IN_GUID); - if (SUCCEEDED(hr)) - { - // create a string of the form "CLSID\{clsid}" - hr = StringCchPrintf(pszName, cchMax - 1, TEXT("CLSID\\%ls"), pszCLSID); - } - return hr; -} - -/////////////////////////////////////////////////////////////////////// -// Name: SetKeyValue -// Desc: Sets a string value (REG_SZ) for a registry key -// -// hKey: Handle to the registry key. -// sName: Name of the value. Use NULL for the default value. -// sValue: The string value. -/////////////////////////////////////////////////////////////////////// - -HRESULT SetKeyValue(HKEY hKey, const TCHAR* pszName, const TCHAR* pszValue) -{ - size_t cch = 0; - DWORD cbData = 0; - HRESULT hr = StringCchLength(pszValue, MAXLONG, &cch); - if (SUCCEEDED(hr)) - { - cbData = (DWORD) (sizeof(TCHAR) * (cch + 1)); // add 1 for the NULL character - hr = __HRESULT_FROM_WIN32(RegSetValueEx(hKey, pszName, 0, REG_SZ, reinterpret_cast(pszValue), cbData)); - } - return hr; -} - -/////////////////////////////////////////////////////////////////////// -// Name: RegisterObject -// Desc: Creates the registry entries for a COM object. -// -// guid: The object's CLSID -// sDescription: Description of the object -// sThreadingMode: Threading model. e.g., "Both" -/////////////////////////////////////////////////////////////////////// - -HRESULT RegisterObject(GUID guid, const TCHAR* pszDescription, const TCHAR* pszThreadingModel) -{ - HRESULT hr = S_OK; - TCHAR pszTemp[MAX_PATH]; - HKEY hKey = NULL; - HKEY hSubkey = NULL; - DWORD dwRet = 0; - - do - { - hr = CreateObjectKeyName(guid, pszTemp, MAX_PATH); - if (FAILED(hr)) - { - break; - } - - hr = __HRESULT_FROM_WIN32(RegCreateKeyEx(HKEY_CLASSES_ROOT, pszTemp, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL)); - if (FAILED(hr)) - { - break; - } - - hr = SetKeyValue(hKey, NULL, pszDescription); - if (FAILED(hr)) - { - break; - } - - hr = __HRESULT_FROM_WIN32(RegCreateKeyEx(hKey, L"InprocServer32", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hSubkey, NULL)); - if (FAILED(hr)) - { - break; - } - - dwRet = GetModuleFileName(g_hModule, pszTemp, MAX_PATH); - if (dwRet == 0) - { - hr = __HRESULT_FROM_WIN32(GetLastError()); - break; - } - if (dwRet == MAX_PATH) - { - hr = E_FAIL; // buffer too small - break; - } - - hr = SetKeyValue(hSubkey, NULL, pszTemp); - if (FAILED(hr)) - { - break; - } - - hr = SetKeyValue(hSubkey, L"ThreadingModel", pszThreadingModel); - } - while (FALSE); - - if (hSubkey != NULL) - { - RegCloseKey(hSubkey); - } - - if (hKey != NULL) - { - RegCloseKey(hKey); - } - - return hr; -} - -/////////////////////////////////////////////////////////////////////// -// Name: UnregisterObject -// Desc: Deletes the registry entries for a COM object. -// -// guid: The object's CLSID -/////////////////////////////////////////////////////////////////////// - -HRESULT UnregisterObject(GUID guid) -{ - HRESULT hr = S_OK; - TCHAR pszTemp[MAX_PATH]; - - do - { - hr = CreateObjectKeyName(guid, pszTemp, MAX_PATH); - if (FAILED(hr)) - { - break; - } - - hr = __HRESULT_FROM_WIN32(RegDeleteTree(HKEY_CLASSES_ROOT, pszTemp)); - } - while (FALSE); - - return hr; -} - -// DLL Exports - -STDAPI CreateDX11VideoRenderer(REFIID riid, void** ppvObject) -{ - return DX11VideoRenderer::CMediaSink::CreateInstance(riid, ppvObject); -} - -STDAPI CreateDX11VideoRendererActivate(HWND hwnd, IMFActivate** ppActivate) -{ - return DX11VideoRenderer::CActivate::CreateInstance(hwnd, ppActivate); -} - -STDAPI DllCanUnloadNow(void) -{ - return (DX11VideoRenderer::CBase::GetObjectCount() == 0 && DX11VideoRenderer::CClassFactory::IsLocked() == FALSE) ? S_OK : S_FALSE; -} - -STDAPI DllGetClassObject(_In_ REFCLSID clsid, _In_ REFIID riid, _Outptr_ void** ppvObject) -{ - if (clsid != CLSID_DX11VideoRenderer) - { - return CLASS_E_CLASSNOTAVAILABLE; - } - - DX11VideoRenderer::CClassFactory* pFactory = new DX11VideoRenderer::CClassFactory(); - if (pFactory == NULL) - { - return E_OUTOFMEMORY; - } - - pFactory->AddRef(); - - HRESULT hr = pFactory->QueryInterface(riid, ppvObject); - - SafeRelease(pFactory); - - return hr; -} - -BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) -{ - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - { - g_hModule = static_cast(hModule); - break; - } - default: - { - break; - } - } - - return TRUE; -} - -STDAPI DllRegisterServer(void) -{ - HRESULT hr = S_OK; - - do - { - hr = RegisterObject(CLSID_DX11VideoRenderer, L"DX11 Video Renderer", L"Both"); - if (FAILED(hr)) - { - break; - } - - hr = RegisterObject(CLSID_DX11VideoRendererActivate, L"DX11 Video Renderer Activate", L"Both"); - if (FAILED(hr)) - { - break; - } - - hr = MFTRegister( - CLSID_DX11VideoRenderer, // CLSID - MFT_CATEGORY_OTHER, // Category - L"DX11 Video Renderer", // Friendly name - 0, // Reserved, must be zero. - 0, - NULL, - 0, - NULL, - NULL - ); - } - while (FALSE); - - return hr; -} - -STDAPI DllUnregisterServer(void) -{ - HRESULT hr = UnregisterObject(CLSID_DX11VideoRenderer); - HRESULT hrTemp = MFTUnregister(CLSID_DX11VideoRenderer); - if (SUCCEEDED(hr)) - { - hr = hrTemp; - } - return hr; -} diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/DX11VideoRenderer.def b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/DX11VideoRenderer.def deleted file mode 100644 index 2de1efec..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/DX11VideoRenderer.def +++ /dev/null @@ -1,9 +0,0 @@ -LIBRARY "DX11VideoRenderer" -EXPORTS - CreateDX11VideoRenderer - CreateDX11VideoRendererActivate - DllCanUnloadNow PRIVATE - DllGetClassObject PRIVATE - DllMain PRIVATE - DllRegisterServer PRIVATE - DllUnregisterServer PRIVATE \ No newline at end of file diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/DX11VideoRenderer.h b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/DX11VideoRenderer.h deleted file mode 100644 index 892af982..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/DX11VideoRenderer.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -// {83A1FDBC-AB3A-4376-A529-80E18C206534} -DEFINE_GUID(CLSID_DX11VideoRenderer, 0x83a1fdbc, 0xab3a, 0x4376, 0xa5, 0x29, 0x80, 0xe1, 0x8c, 0x20, 0x65, 0x34); - -// {0743FA5C-DA9E-4760-8187-CCAC3DC15D77} -DEFINE_GUID(CLSID_DX11VideoRendererActivate, 0x743fa5c, 0xda9e, 0x4760, 0x81, 0x87, 0xcc, 0xac, 0x3d, 0xc1, 0x5d, 0x77); - -// creation methods exposed by the lib -STDAPI CreateDX11VideoRenderer(REFIID riid, void** ppvObject); -STDAPI CreateDX11VideoRendererActivate(HWND hwnd, IMFActivate** ppActivate); diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/DX11VideoRenderer.sln b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/DX11VideoRenderer.sln deleted file mode 100644 index d905a376..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/DX11VideoRenderer.sln +++ /dev/null @@ -1,31 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31729.503 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DX11VideoRenderer", "DX11VideoRenderer.vcxproj", "{ED9D0263-0454-4C86-967B-BEEB81B8330B}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {ED9D0263-0454-4C86-967B-BEEB81B8330B}.Debug|Win32.ActiveCfg = Release|Win32 - {ED9D0263-0454-4C86-967B-BEEB81B8330B}.Debug|Win32.Build.0 = Release|Win32 - {ED9D0263-0454-4C86-967B-BEEB81B8330B}.Debug|x64.ActiveCfg = Debug|x64 - {ED9D0263-0454-4C86-967B-BEEB81B8330B}.Debug|x64.Build.0 = Debug|x64 - {ED9D0263-0454-4C86-967B-BEEB81B8330B}.Release|Win32.ActiveCfg = Release|Win32 - {ED9D0263-0454-4C86-967B-BEEB81B8330B}.Release|Win32.Build.0 = Release|Win32 - {ED9D0263-0454-4C86-967B-BEEB81B8330B}.Release|x64.ActiveCfg = Debug|x64 - {ED9D0263-0454-4C86-967B-BEEB81B8330B}.Release|x64.Build.0 = Debug|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {6F11A558-643A-4061-815F-1535A55192A9} - EndGlobalSection -EndGlobal diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/DX11VideoRenderer.vcxproj b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/DX11VideoRenderer.vcxproj deleted file mode 100644 index 1c892a04..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/DX11VideoRenderer.vcxproj +++ /dev/null @@ -1,193 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {ED9D0263-0454-4C86-967B-BEEB81B8330B} - Win32Proj - DX11VideoRenderer - native - 10.0.19041.0 - - - - true - Unicode - v142 - - - true - Unicode - v142 - - - DynamicLibrary - false - true - Unicode - v142 - - - DynamicLibrary - false - true - Unicode - v142 - - - - - - - - - - - - - - - - - - - true - - - true - - - false - - - false - - - - - - Level3 - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - - - stdcpp17 - - - Windows - true - DX11VideoRenderer.def - winmm.lib;dcomp.lib;d3d11.lib;mfuuid.lib;mfplat.lib;evr.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - - - stdcpp17 - - - Windows - true - DX11VideoRenderer.def - winmm.lib;dcomp.lib;d3d11.lib;mfuuid.lib;mfplat.lib;evr.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - - - stdcpp17 - - - Windows - true - true - true - DX11VideoRenderer.def - winmm.lib;dcomp.lib;d3d11.lib;mfuuid.lib;mfplat.lib;evr.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - - - stdcpp17 - - - Windows - true - true - true - DX11VideoRenderer.def - winmm.lib;dcomp.lib;d3d11.lib;mfuuid.lib;mfplat.lib;evr.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/MFAttributesImpl.h b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/MFAttributesImpl.h deleted file mode 100644 index 9402a4af..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/MFAttributesImpl.h +++ /dev/null @@ -1,352 +0,0 @@ -#pragma once - -template -class CMFAttributesImpl : public TBase -{ -protected: - - // This version of the constructor does not initialize the - // attribute store. The derived class must call Initialize() in - // its own constructor. - CMFAttributesImpl(void) : - _pAttributes(NULL) - { - } - - // This version of the constructor initializes the attribute - // store, but the derived class must pass an HRESULT parameter - // to the constructor. - - CMFAttributesImpl(HRESULT& hr, UINT32 cInitialSize = 0) : - _pAttributes(NULL) - { - hr = Initialize(cInitialSize); - } - - // The next version of the constructor uses a caller-provided - // implementation of IMFAttributes. - - // (Sometimes you want to delegate IMFAttributes calls to some - // other object that implements IMFAttributes, rather than using - // MFCreateAttributes.) - - CMFAttributesImpl(HRESULT& hr, IUnknown* pUnk) : - _pAttributes(NULL) - { - hr = Initialize(pUnk); - } - - virtual ~CMFAttributesImpl(void) - { - if (_pAttributes) - { - _pAttributes->Release(); - } - } - - // Initializes the object by creating the standard Media Foundation attribute store. - HRESULT Initialize(UINT32 cInitialSize = 0) - { - if (_pAttributes == NULL) - { - return MFCreateAttributes(&_pAttributes, cInitialSize); - } - else - { - return S_OK; - } - } - - // Initializes this object from a caller-provided attribute store. - // pUnk: Pointer to an object that exposes IMFAttributes. - HRESULT Initialize(IUnknown* pUnk) - { - if (_pAttributes) - { - _pAttributes->Release(); - _pAttributes = NULL; - } - - return pUnk->QueryInterface(IID_PPV_ARGS(&_pAttributes)); - } - -public: - - // IMFAttributes methods - - STDMETHODIMP GetItem(__RPC__in REFGUID guidKey, __RPC__inout_opt PROPVARIANT* pValue) - { - assert(_pAttributes); - return _pAttributes->GetItem(guidKey, pValue); - } - - STDMETHODIMP GetItemType(__RPC__in REFGUID guidKey, __RPC__out MF_ATTRIBUTE_TYPE* pType) - { - assert(_pAttributes); - return _pAttributes->GetItemType(guidKey, pType); - } - - STDMETHODIMP CompareItem(__RPC__in REFGUID guidKey, __RPC__in REFPROPVARIANT Value, __RPC__out BOOL* pbResult) - { - assert(_pAttributes); - return _pAttributes->CompareItem(guidKey, Value, pbResult); - } - - STDMETHODIMP Compare(__RPC__in_opt IMFAttributes* pTheirs, MF_ATTRIBUTES_MATCH_TYPE MatchType, __RPC__out BOOL* pbResult) - { - assert(_pAttributes); - return _pAttributes->Compare(pTheirs, MatchType, pbResult); - } - - STDMETHODIMP GetUINT32(__RPC__in REFGUID guidKey, __RPC__out UINT32* punValue) - { - assert(_pAttributes); - return _pAttributes->GetUINT32(guidKey, punValue); - } - - STDMETHODIMP GetUINT64(__RPC__in REFGUID guidKey, __RPC__out UINT64* punValue) - { - assert(_pAttributes); - return _pAttributes->GetUINT64(guidKey, punValue); - } - - STDMETHODIMP GetDouble(__RPC__in REFGUID guidKey, __RPC__out double* pfValue) - { - assert(_pAttributes); - return _pAttributes->GetDouble(guidKey, pfValue); - } - - STDMETHODIMP GetGUID(__RPC__in REFGUID guidKey, __RPC__out GUID* pguidValue) - { - assert(_pAttributes); - return _pAttributes->GetGUID(guidKey, pguidValue); - } - - STDMETHODIMP GetStringLength(__RPC__in REFGUID guidKey, __RPC__out UINT32* pcchLength) - { - assert(_pAttributes); - return _pAttributes->GetStringLength(guidKey, pcchLength); - } - - STDMETHODIMP GetString(__RPC__in REFGUID guidKey, __RPC__out_ecount_full(cchBufSize) LPWSTR pwszValue, UINT32 cchBufSize, __RPC__inout_opt UINT32* pcchLength) - { - assert(_pAttributes); - return _pAttributes->GetString(guidKey, pwszValue, cchBufSize, pcchLength); - } - - STDMETHODIMP GetAllocatedString(__RPC__in REFGUID guidKey, __RPC__deref_out_ecount_full_opt(( *pcchLength + 1 ) ) LPWSTR* ppwszValue, __RPC__out UINT32* pcchLength) - { - assert(_pAttributes); - return _pAttributes->GetAllocatedString(guidKey, ppwszValue, pcchLength); - } - - STDMETHODIMP GetBlobSize(__RPC__in REFGUID guidKey, __RPC__out UINT32* pcbBlobSize) - { - assert(_pAttributes); - return _pAttributes->GetBlobSize(guidKey, pcbBlobSize); - } - - STDMETHODIMP GetBlob(__RPC__in REFGUID guidKey, __RPC__out_ecount_full(cbBufSize) UINT8* pBuf, UINT32 cbBufSize, __RPC__inout_opt UINT32* pcbBlobSize) - { - assert(_pAttributes); - return _pAttributes->GetBlob(guidKey, pBuf, cbBufSize, pcbBlobSize); - } - - STDMETHODIMP GetAllocatedBlob(__RPC__in REFGUID guidKey, __RPC__deref_out_ecount_full_opt(*pcbSize) UINT8** ppBuf, __RPC__out UINT32* pcbSize) - { - assert(_pAttributes); - return _pAttributes->GetAllocatedBlob(guidKey, ppBuf, pcbSize); - } - - STDMETHODIMP GetUnknown(__RPC__in REFGUID guidKey, __RPC__in REFIID riid, __RPC__deref_out_opt LPVOID* ppv) - { - assert(_pAttributes); - return _pAttributes->GetUnknown(guidKey, riid, ppv); - } - - STDMETHODIMP SetItem(__RPC__in REFGUID guidKey, __RPC__in REFPROPVARIANT Value) - { - assert(_pAttributes); - return _pAttributes->SetItem(guidKey, Value); - } - - STDMETHODIMP DeleteItem(__RPC__in REFGUID guidKey) - { - assert(_pAttributes); - return _pAttributes->DeleteItem(guidKey); - } - - STDMETHODIMP DeleteAllItems(void) - { - assert(_pAttributes); - return _pAttributes->DeleteAllItems(); - } - - STDMETHODIMP SetUINT32(__RPC__in REFGUID guidKey, UINT32 unValue) - { - assert(_pAttributes); - return _pAttributes->SetUINT32(guidKey, unValue); - } - - STDMETHODIMP SetUINT64(__RPC__in REFGUID guidKey, UINT64 unValue) - { - assert(_pAttributes); - return _pAttributes->SetUINT64(guidKey, unValue); - } - - STDMETHODIMP SetDouble(__RPC__in REFGUID guidKey, double fValue) - { - assert(_pAttributes); - return _pAttributes->SetDouble(guidKey, fValue); - } - - STDMETHODIMP SetGUID(__RPC__in REFGUID guidKey, __RPC__in REFGUID guidValue) - { - assert(_pAttributes); - return _pAttributes->SetGUID(guidKey, guidValue); - } - - STDMETHODIMP SetString(__RPC__in REFGUID guidKey, __RPC__in_string LPCWSTR wszValue) - { - assert(_pAttributes); - return _pAttributes->SetString(guidKey, wszValue); - } - - STDMETHODIMP SetBlob(__RPC__in REFGUID guidKey, __RPC__in_ecount_full(cbBufSize) const UINT8* pBuf, UINT32 cbBufSize) - { - assert(_pAttributes); - return _pAttributes->SetBlob(guidKey, pBuf, cbBufSize); - } - - STDMETHODIMP SetUnknown(__RPC__in REFGUID guidKey, __RPC__in_opt IUnknown* pUnknown) - { - assert(_pAttributes); - return _pAttributes->SetUnknown(guidKey, pUnknown); - } - - STDMETHODIMP LockStore(void) - { - assert(_pAttributes); - return _pAttributes->LockStore(); - } - - STDMETHODIMP UnlockStore(void) - { - assert(_pAttributes); - return _pAttributes->UnlockStore(); - } - - STDMETHODIMP GetCount(__RPC__out UINT32* pcItems) - { - assert(_pAttributes); - return _pAttributes->GetCount(pcItems); - } - - STDMETHODIMP GetItemByIndex(UINT32 unIndex, __RPC__out GUID* pguidKey, __RPC__inout_opt PROPVARIANT* pValue) - { - assert(_pAttributes); - return _pAttributes->GetItemByIndex(unIndex, pguidKey, pValue); - } - - STDMETHODIMP CopyAllItems(__RPC__in_opt IMFAttributes* pDest) - { - assert(_pAttributes); - return _pAttributes->CopyAllItems(pDest); - } - - // Helper functions - - HRESULT SerializeToStream(DWORD dwOptions, IStream* pStm) - // dwOptions: Flags from MF_ATTRIBUTE_SERIALIZE_OPTIONS - { - assert(_pAttributes); - return MFSerializeAttributesToStream(_pAttributes, dwOptions, pStm); - } - - HRESULT DeserializeFromStream(DWORD dwOptions, IStream* pStm) - { - assert(_pAttributes); - return MFDeserializeAttributesFromStream(_pAttributes, dwOptions, pStm); - } - - // SerializeToBlob: Stores the attributes in a byte array. - // - // ppBuf: Receives a pointer to the byte array. - // pcbSize: Receives the size of the byte array. - // - // The caller must free the array using CoTaskMemFree. - HRESULT SerializeToBlob(UINT8** ppBuffer, UINT* pcbSize) - { - assert(_pAttributes); - - if (ppBuffer == NULL) - { - return E_POINTER; - } - if (pcbSize == NULL) - { - return E_POINTER; - } - - HRESULT hr = S_OK; - UINT32 cbSize = 0; - BYTE* pBuffer = NULL; - - CHECK_HR(hr = MFGetAttributesAsBlobSize(_pAttributes, &cbSize)); - - pBuffer = (BYTE*)CoTaskMemAlloc(cbSize); - if (pBuffer == NULL) - { - CHECK_HR(hr = E_OUTOFMEMORY); - } - - CHECK_HR(hr = MFGetAttributesAsBlob(_pAttributes, pBuffer, cbSize)); - - *ppBuffer = pBuffer; - *pcbSize = cbSize; - - if (FAILED(hr)) - { - *ppBuffer = NULL; - *pcbSize = 0; - CoTaskMemFree(pBuffer); - } - return hr; - } - - HRESULT DeserializeFromBlob(const UINT8* pBuffer, UINT cbSize) - { - assert(_pAttributes); - return MFInitAttributesFromBlob(_pAttributes, pBuffer, cbSize); - } - - HRESULT GetRatio(REFGUID guidKey, UINT32* pnNumerator, UINT32* punDenominator) - { - assert(_pAttributes); - return MFGetAttributeRatio(_pAttributes, guidKey, pnNumerator, punDenominator); - } - - HRESULT SetRatio(REFGUID guidKey, UINT32 unNumerator, UINT32 unDenominator) - { - assert(_pAttributes); - return MFSetAttributeRatio(_pAttributes, guidKey, unNumerator, unDenominator); - } - - // Gets an attribute whose value represents the size of something (eg a video frame). - HRESULT GetSize(REFGUID guidKey, UINT32* punWidth, UINT32* punHeight) - { - assert(_pAttributes); - return MFGetAttributeSize(_pAttributes, guidKey, punWidth, punHeight); - } - - // Sets an attribute whose value represents the size of something (eg a video frame). - HRESULT SetSize(REFGUID guidKey, UINT32 unWidth, UINT32 unHeight) - { - assert(_pAttributes); - return MFSetAttributeSize (_pAttributes, guidKey, unWidth, unHeight); - } - -protected: - - IMFAttributes* _pAttributes; -}; \ No newline at end of file diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Marker.cpp b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Marker.cpp deleted file mode 100644 index 75fe7af3..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Marker.cpp +++ /dev/null @@ -1,142 +0,0 @@ -#include "Marker.h" - -////////////////////// -// CMarker class -// Holds information from IMFStreamSink::PlaceMarker -// - -DX11VideoRenderer::CMarker::CMarker(MFSTREAMSINK_MARKER_TYPE eMarkerType) : - m_nRefCount(1), - m_eMarkerType(eMarkerType) -{ - PropVariantInit(&m_varMarkerValue); - PropVariantInit(&m_varContextValue); -} - -DX11VideoRenderer::CMarker::~CMarker(void) -{ - assert(m_nRefCount == 0); - - PropVariantClear(&m_varMarkerValue); - PropVariantClear(&m_varContextValue); -} - -/* static */ -HRESULT DX11VideoRenderer::CMarker::Create( - MFSTREAMSINK_MARKER_TYPE eMarkerType, - const PROPVARIANT* pvarMarkerValue, // Can be NULL. - const PROPVARIANT* pvarContextValue, // Can be NULL. - IMarker** ppMarker - ) -{ - if (ppMarker == NULL) - { - return E_POINTER; - } - - HRESULT hr = S_OK; - CMarker* pMarker = new CMarker(eMarkerType); - - if (pMarker == NULL) - { - hr = E_OUTOFMEMORY; - } - - // Copy the marker data. - if (SUCCEEDED(hr)) - { - if (pvarMarkerValue) - { - hr = PropVariantCopy(&pMarker->m_varMarkerValue, pvarMarkerValue); - } - } - - if (SUCCEEDED(hr)) - { - if (pvarContextValue) - { - hr = PropVariantCopy(&pMarker->m_varContextValue, pvarContextValue); - } - } - - if (SUCCEEDED(hr)) - { - *ppMarker = pMarker; - (*ppMarker)->AddRef(); - } - - SafeRelease(pMarker); - - return hr; -} - -// IUnknown methods. - -ULONG DX11VideoRenderer::CMarker::AddRef(void) -{ - return InterlockedIncrement(&m_nRefCount); -} - -ULONG DX11VideoRenderer::CMarker::Release(void) -{ - ULONG uCount = InterlockedDecrement(&m_nRefCount); - if (uCount == 0) - { - delete this; - } - // For thread safety, return a temporary variable. - return uCount; -} - -HRESULT DX11VideoRenderer::CMarker::QueryInterface(REFIID iid, __RPC__deref_out _Result_nullonfailure_ void** ppv) -{ - if (!ppv) - { - return E_POINTER; - } - if (iid == IID_IUnknown) - { - *ppv = static_cast(this); - } - else if (iid == __uuidof(IMarker)) - { - *ppv = static_cast(this); - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -// IMarker methods -HRESULT DX11VideoRenderer::CMarker::GetMarkerType(MFSTREAMSINK_MARKER_TYPE* pType) -{ - if (pType == NULL) - { - return E_POINTER; - } - - *pType = m_eMarkerType; - return S_OK; -} - -HRESULT DX11VideoRenderer::CMarker::GetMarkerValue(PROPVARIANT* pvar) -{ - if (pvar == NULL) - { - return E_POINTER; - } - return PropVariantCopy(pvar, &m_varMarkerValue); - -} -HRESULT DX11VideoRenderer::CMarker::GetContext(PROPVARIANT* pvar) -{ - if (pvar == NULL) - { - return E_POINTER; - } - return PropVariantCopy(pvar, &m_varContextValue); -} diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Marker.h b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Marker.h deleted file mode 100644 index 7761f4ff..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Marker.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include "Common.h" -#include "Scheduler.h" -#include "display.h" - -namespace DX11VideoRenderer -{ - // IMarker: - // Custom interface for handling IMFStreamSink::PlaceMarker calls asynchronously. - - // A marker consists of a marker type, marker data, and context data. - // By defining this interface, we can store the marker data inside an IUnknown object - // and keep that object on the same queue that holds the media samples. This is - // useful because samples and markers must be serialized. That is, we cannot respond - // to a marker until we have processed all of the samples that came before it. - - // Note that IMarker is not a standard Media Foundation interface. - MIDL_INTERFACE("3AC82233-933C-43a9-AF3D-ADC94EABF406") - IMarker : public IUnknown - { - virtual STDMETHODIMP GetMarkerType(MFSTREAMSINK_MARKER_TYPE* pType) = 0; - virtual STDMETHODIMP GetMarkerValue(PROPVARIANT* pvar) = 0; - virtual STDMETHODIMP GetContext(PROPVARIANT* pvar) = 0; - }; - - // Holds marker information for IMFStreamSink::PlaceMarker - - class CMarker : public IMarker, private CBase - { - public: - - static HRESULT Create( - MFSTREAMSINK_MARKER_TYPE eMarkerType, - const PROPVARIANT* pvarMarkerValue, - const PROPVARIANT* pvarContextValue, - IMarker** ppMarker - ); - - // IUnknown methods. - STDMETHODIMP_(ULONG) AddRef(void); - STDMETHODIMP_(ULONG) Release(void); - STDMETHODIMP QueryInterface(REFIID iid, __RPC__deref_out _Result_nullonfailure_ void** ppv); - - STDMETHODIMP GetMarkerType(MFSTREAMSINK_MARKER_TYPE* pType); - STDMETHODIMP GetMarkerValue(PROPVARIANT* pvar); - STDMETHODIMP GetContext(PROPVARIANT* pvar); - - protected: - - MFSTREAMSINK_MARKER_TYPE m_eMarkerType; - PROPVARIANT m_varMarkerValue; - PROPVARIANT m_varContextValue; - - private: - - CMarker(MFSTREAMSINK_MARKER_TYPE eMarkerType); - virtual ~CMarker(void); - - long m_nRefCount; - }; -} diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/MediaSink.cpp b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/MediaSink.cpp deleted file mode 100644 index 2c249d40..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/MediaSink.cpp +++ /dev/null @@ -1,791 +0,0 @@ -#include "MediaSink.h" - -///////////////////////////////////////////////////////////////////////////////////////////// -// -// CMediaSink class. - Implements the media sink. -// -// Notes: -// - Most public methods calls CheckShutdown. This method fails if the sink was shut down. -// -///////////////////////////////////////////////////////////////////////////////////////////// - -DX11VideoRenderer::CCritSec DX11VideoRenderer::CMediaSink::s_csStreamSinkAndScheduler; - -//------------------------------------------------------------------- -// Name: CreateInstance -// Description: Creates an instance of the DX11 Video Renderer sink object. -//------------------------------------------------------------------- - -/* static */ HRESULT DX11VideoRenderer::CMediaSink::CreateInstance(_In_ REFIID iid, _COM_Outptr_ void** ppSink) -{ - if (ppSink == NULL) - { - return E_POINTER; - } - - *ppSink = NULL; - - HRESULT hr = S_OK; - CMediaSink* pSink = new CMediaSink(); // Created with ref count = 1. - - if (pSink == NULL) - { - hr = E_OUTOFMEMORY; - } - - if (SUCCEEDED(hr)) - { - hr = pSink->Initialize(); - } - - if (SUCCEEDED(hr)) - { - hr = pSink->QueryInterface(iid, ppSink); - } - - SafeRelease(pSink); - - return hr; -} - -// IUnknown methods - -ULONG DX11VideoRenderer::CMediaSink::AddRef(void) -{ - return InterlockedIncrement(&m_nRefCount); -} - -HRESULT DX11VideoRenderer::CMediaSink::QueryInterface(REFIID iid, __RPC__deref_out _Result_nullonfailure_ void** ppv) -{ - if (!ppv) - { - return E_POINTER; - } - if (iid == IID_IUnknown) - { - *ppv = static_cast(static_cast(this)); - } - else if (iid == __uuidof(IMFMediaSink)) - { - *ppv = static_cast(this); - } - else if (iid == __uuidof(IMFClockStateSink)) - { - *ppv = static_cast(this); - } - else if (iid == __uuidof(IMFGetService)) - { - *ppv = static_cast(this); - } - else if (iid == IID_IMFRateSupport) - { - *ppv = static_cast(this); - } - else if (iid == IID_IMFMediaSinkPreroll) - { - *ppv = static_cast(this); - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -ULONG DX11VideoRenderer::CMediaSink::Release(void) -{ - ULONG uCount = InterlockedDecrement(&m_nRefCount); - if (uCount == 0) - { - delete this; - } - // For thread safety, return a temporary variable. - return uCount; -} - -/// IMFMediaSink methods. - -//------------------------------------------------------------------- -// Name: AddStreamSink -// Description: Adds a new stream to the sink. -// -// Note: This sink has a fixed number of streams, so this method -// always returns MF_E_STREAMSINKS_FIXED. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CMediaSink::AddStreamSink(DWORD dwStreamSinkIdentifier, __RPC__in_opt IMFMediaType* pMediaType, __RPC__deref_out_opt IMFStreamSink** ppStreamSink) -{ - return MF_E_STREAMSINKS_FIXED; -} - -//------------------------------------------------------------------- -// Name: GetCharacteristics -// Description: Returns the characteristics flags. -// -// Note: This sink has a fixed number of streams. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CMediaSink::GetCharacteristics(__RPC__out DWORD* pdwCharacteristics) -{ - CAutoLock lock(&m_csMediaSink); - - if (pdwCharacteristics == NULL) - { - return E_POINTER; - } - - HRESULT hr = CheckShutdown(); - - if (SUCCEEDED(hr)) - { - *pdwCharacteristics = MEDIASINK_FIXED_STREAMS | MEDIASINK_CAN_PREROLL; - } - - return hr; -} - -//------------------------------------------------------------------- -// Name: GetPresentationClock -// Description: Returns a pointer to the presentation clock. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CMediaSink::GetPresentationClock(__RPC__deref_out_opt IMFPresentationClock** ppPresentationClock) -{ - CAutoLock lock(&m_csMediaSink); - - if (ppPresentationClock == NULL) - { - return E_POINTER; - } - - HRESULT hr = CheckShutdown(); - - if (SUCCEEDED(hr)) - { - if (m_pClock == NULL) - { - hr = MF_E_NO_CLOCK; // There is no presentation clock. - } - else - { - // Return the pointer to the caller. - *ppPresentationClock = m_pClock; - (*ppPresentationClock)->AddRef(); - } - } - - return hr; -} - -//------------------------------------------------------------------- -// Name: GetStreamSinkById -// Description: Retrieves a stream by ID. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CMediaSink::GetStreamSinkById(DWORD dwStreamSinkIdentifier, __RPC__deref_out_opt IMFStreamSink** ppStreamSink) -{ - CAutoLock lock(&m_csMediaSink); - - if (ppStreamSink == NULL) - { - return E_POINTER; - } - - // Fixed stream ID. - if (dwStreamSinkIdentifier != STREAM_ID) - { - return MF_E_INVALIDSTREAMNUMBER; - } - - HRESULT hr = CheckShutdown(); - - if (SUCCEEDED(hr)) - { - *ppStreamSink = m_pStream; - (*ppStreamSink)->AddRef(); - } - - return hr; -} - -//------------------------------------------------------------------- -// Name: GetStreamSinkByIndex -// Description: Retrieves a stream by index. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CMediaSink::GetStreamSinkByIndex(DWORD dwIndex, __RPC__deref_out_opt IMFStreamSink** ppStreamSink) -{ - CAutoLock lock(&m_csMediaSink); - - if (ppStreamSink == NULL) - { - return E_POINTER; - } - - // Fixed stream: Index 0. - if (dwIndex > 0) - { - return MF_E_INVALIDINDEX; - } - - HRESULT hr = CheckShutdown(); - if (SUCCEEDED(hr)) - { - *ppStreamSink = m_pStream; - (*ppStreamSink)->AddRef(); - } - - return hr; -} - -//------------------------------------------------------------------- -// Name: GetStreamSinkCount -// Description: Returns the number of streams. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CMediaSink::GetStreamSinkCount(__RPC__out DWORD* pcStreamSinkCount) -{ - CAutoLock lock(&m_csMediaSink); - - if (pcStreamSinkCount == NULL) - { - return E_POINTER; - } - - HRESULT hr = CheckShutdown(); - - if (SUCCEEDED(hr)) - { - *pcStreamSinkCount = 1; // Fixed number of streams. - } - - return hr; - -} - -//------------------------------------------------------------------- -// Name: RemoveStreamSink -// Description: Removes a stream from the sink. -// -// Note: This sink has a fixed number of streams, so this method -// always returns MF_E_STREAMSINKS_FIXED. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CMediaSink::RemoveStreamSink(DWORD dwStreamSinkIdentifier) -{ - return MF_E_STREAMSINKS_FIXED; -} - -//------------------------------------------------------------------- -// Name: SetPresentationClock -// Description: Sets the presentation clock. -// -// pPresentationClock: Pointer to the clock. Can be NULL. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CMediaSink::SetPresentationClock(__RPC__in_opt IMFPresentationClock* pPresentationClock) -{ - CAutoLock lock(&m_csMediaSink); - - HRESULT hr = CheckShutdown(); - - // If we already have a clock, remove ourselves from that clock's - // state notifications. - if (SUCCEEDED(hr)) - { - if (m_pClock) - { - hr = m_pClock->RemoveClockStateSink(this); - } - } - - // Register ourselves to get state notifications from the new clock. - if (SUCCEEDED(hr)) - { - if (pPresentationClock) - { - hr = pPresentationClock->AddClockStateSink(this); - } - } - - if (SUCCEEDED(hr)) - { - // Release the pointer to the old clock. - // Store the pointer to the new clock. - - SafeRelease(m_pClock); - m_pClock = pPresentationClock; - if (m_pClock) - { - m_pClock->AddRef(); - } - } - - return hr; -} - -//------------------------------------------------------------------- -// Name: Shutdown -// Description: Releases resources held by the media sink. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CMediaSink::Shutdown(void) -{ - CAutoLock lock(&m_csMediaSink); - - HRESULT hr = MF_E_SHUTDOWN; - - m_IsShutdown = TRUE; - - if (m_pStream != NULL) - { - m_pStream->Shutdown(); - } - - if (m_pPresenter != NULL) - { - m_pPresenter->Shutdown(); - } - - SafeRelease(m_pClock); - SafeRelease(m_pStream); - SafeRelease(m_pPresenter); - - if (m_pScheduler != NULL) - { - hr = m_pScheduler->StopScheduler(); - } - - SafeRelease(m_pScheduler); - - return hr; -} - -//------------------------------------------------------------------- -// Name: OnClockPause -// Description: Called when the presentation clock paused. -// -// Note: For an archive sink, the paused state is equivalent to the -// running (started) state. We still accept data and archive it. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CMediaSink::OnClockPause( - /* [in] */ MFTIME hnsSystemTime) -{ - CAutoLock lock(&m_csMediaSink); - - HRESULT hr = CheckShutdown(); - - if (SUCCEEDED(hr)) - { - hr = m_pStream->Pause(); - } - - return hr; -} - -//------------------------------------------------------------------- -// Name: OnClockRestart -// Description: Called when the presentation clock restarts. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CMediaSink::OnClockRestart( - /* [in] */ MFTIME hnsSystemTime) -{ - CAutoLock lock(&m_csMediaSink); - - HRESULT hr = CheckShutdown(); - - if (SUCCEEDED(hr)) - { - hr = m_pStream->Restart(); - } - - return hr; -} - -//------------------------------------------------------------------- -// Name: OnClockSetRate -// Description: Called when the presentation clock's rate changes. -// -// Note: For a rateless sink, the clock rate is not important. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CMediaSink::OnClockSetRate( - /* [in] */ MFTIME hnsSystemTime, - /* [in] */ float flRate) -{ - if (m_pScheduler != NULL) - { - // Tell the scheduler about the new rate. - m_pScheduler->SetClockRate(flRate); - } - - return S_OK; -} - -//------------------------------------------------------------------- -// Name: OnClockStart -// Description: Called when the presentation clock starts. -// -// hnsSystemTime: System time when the clock started. -// llClockStartOffset: Starting presentatation time. -// -// Note: For an archive sink, we don't care about the system time. -// But we need to cache the value of llClockStartOffset. This -// gives us the earliest time stamp that we archive. If any -// input samples have an earlier time stamp, we discard them. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CMediaSink::OnClockStart( - /* [in] */ MFTIME hnsSystemTime, - /* [in] */ LONGLONG llClockStartOffset) -{ - CAutoLock lock(&m_csMediaSink); - - HRESULT hr = CheckShutdown(); - if (FAILED(hr)) - { - return hr; - } - - // Check if the clock is already active (not stopped). - // And if the clock position changes while the clock is active, it - // is a seek request. We need to flush all pending samples. - if (m_pStream->IsActive() && llClockStartOffset != PRESENTATION_CURRENT_POSITION) - { - // This call blocks until the scheduler threads discards all scheduled samples. - hr = m_pStream->Flush(); - } - else - { - if (m_pScheduler != NULL) - { - // Start the scheduler thread. - hr = m_pScheduler->StartScheduler(m_pClock); - } - } - - if (SUCCEEDED(hr)) - { - hr = m_pStream->Start(llClockStartOffset); - } - - return hr; -} - -//------------------------------------------------------------------- -// Name: OnClockStop -// Description: Called when the presentation clock stops. -// -// Note: After this method is called, we stop accepting new data. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CMediaSink::OnClockStop( - /* [in] */ MFTIME hnsSystemTime) -{ - CAutoLock lock(&m_csMediaSink); - - HRESULT hr = CheckShutdown(); - - if (SUCCEEDED(hr)) - { - hr = m_pStream->Stop(); - } - - if (SUCCEEDED(hr)) - { - if (m_pScheduler != NULL) - { - // Stop the scheduler thread. - hr = m_pScheduler->StopScheduler(); - } - } - - return hr; -} - -//------------------------------------------------------------------------- -// Name: GetService -// Description: IMFGetService -//------------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CMediaSink::GetService(__RPC__in REFGUID guidService, __RPC__in REFIID riid, __RPC__deref_out_opt LPVOID* ppvObject) -{ - HRESULT hr = S_OK; - - if (guidService == MF_RATE_CONTROL_SERVICE) - { - hr = QueryInterface(riid, ppvObject); - } - else if (guidService == MR_VIDEO_RENDER_SERVICE) - { - hr = m_pPresenter->QueryInterface(riid, ppvObject); - } - else if (guidService == MR_VIDEO_ACCELERATION_SERVICE) - { - hr = m_pPresenter->GetService(guidService, riid, ppvObject); - } - else - { - hr = MF_E_UNSUPPORTED_SERVICE; - } - - return hr; -} - -STDMETHODIMP DX11VideoRenderer::CMediaSink::GetFastestRate( - MFRATE_DIRECTION eDirection, - BOOL fThin, - _Out_ float *pflRate - ) -{ - HRESULT hr = S_OK; - - CAutoLock lock(&m_csMediaSink); - - do - { - hr = CheckShutdown(); - if (FAILED(hr)) - { - break; - } - - if (NULL == pflRate) - { - hr = E_POINTER; - break; - } - - float rate; - - hr = m_pStream->GetMaxRate(fThin, &rate); - if (FAILED(hr)) - { - break; - } - - if (MFRATE_FORWARD == eDirection) - { - *pflRate = rate; - } - else - { - *pflRate = -rate; - } - } - while (FALSE); - - return hr; -} - -//------------------------------------------------------------------------- -// Name: GetSlowestRate -// Description: IMFRateSupport -//------------------------------------------------------------------------- - -STDMETHODIMP DX11VideoRenderer::CMediaSink::GetSlowestRate( - MFRATE_DIRECTION eDirection, - BOOL fThin, - _Out_ float* pflRate - ) -{ - HRESULT hr = S_OK; - - CAutoLock lock(&m_csMediaSink); - - do - { - hr = CheckShutdown(); - if (FAILED(hr)) - { - break; - } - - if (NULL == pflRate) - { - hr = E_POINTER; - break; - } - - if (SUCCEEDED(hr)) - { - // - // We go as slow as you want! - // - *pflRate = 0; - } - } - while (FALSE); - - return hr; -} - -STDMETHODIMP DX11VideoRenderer::CMediaSink::IsRateSupported(BOOL fThin, float flRate, __RPC__inout_opt float* pflNearestSupportedRate) -{ - HRESULT hr = S_OK; - float flNearestSupportedRate = flRate; - - CAutoLock lock(&m_csMediaSink); - - do - { - hr = CheckShutdown(); - if (FAILED(hr)) - { - break; - } - - // - // Only support rates up to the refresh rate of the monitor. - // This check makes sense only if we're going to be receiving - // all frames - // - if ( !fThin ) - { - float rate; - - hr = m_pStream->GetMaxRate(fThin, &rate); - if (FAILED(hr)) - { - break; - } - - if ( (flRate > 0 && flRate > (float)rate) || - (flRate < 0 && flRate < -(float)rate) ) - { - hr = MF_E_UNSUPPORTED_RATE; - flNearestSupportedRate = ( flRate >= 0.0f ) ? rate : -rate; - - break; - } - } - } - while (FALSE); - - if ( NULL != pflNearestSupportedRate ) - { - *pflNearestSupportedRate = flNearestSupportedRate; - } - - return hr; -} - -STDMETHODIMP DX11VideoRenderer::CMediaSink::NotifyPreroll(MFTIME hnsUpcomingStartTime) -{ - HRESULT hr = S_OK; - - CAutoLock lock(&m_csMediaSink); - - hr = CheckShutdown(); - - if (SUCCEEDED(hr)) - { - hr = m_pStream->Preroll(); - } - - return hr; -} - -/// Private methods - -//------------------------------------------------------------------- -// CMediaSink constructor. -//------------------------------------------------------------------- - -DX11VideoRenderer::CMediaSink::CMediaSink(void) : - STREAM_ID(1), - m_nRefCount(1), - m_csMediaSink(), // default ctor - m_IsShutdown(FALSE), - m_pStream(NULL), - m_pClock(NULL), - m_pScheduler(NULL), - m_pPresenter(NULL) -{ -} - -//------------------------------------------------------------------- -// CMediaSink destructor. -//------------------------------------------------------------------- - -DX11VideoRenderer::CMediaSink::~CMediaSink(void) -{ -} - -HRESULT DX11VideoRenderer::CMediaSink::CheckShutdown(void) const -{ - if (m_IsShutdown) - { - return MF_E_SHUTDOWN; - } - else - { - return S_OK; - } -} - -//------------------------------------------------------------------- -// Name: Initialize -// Description: Initializes the media sink. -// -// Note: This method is called once when the media sink is first -// initialized. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CMediaSink::Initialize(void) -{ - HRESULT hr = S_OK; - IMFMediaSink* pSink = NULL; - - do - { - m_pScheduler = new CScheduler(s_csStreamSinkAndScheduler); - if (m_pScheduler == NULL) - { - hr = E_OUTOFMEMORY; - break; - } - - m_pStream = new CStreamSink(STREAM_ID, s_csStreamSinkAndScheduler, m_pScheduler); - if (m_pStream == NULL) - { - hr = E_OUTOFMEMORY; - break; - } - - m_pPresenter = new CPresenter(); // Created with ref count = 1. - if (m_pPresenter == NULL) - { - hr = E_OUTOFMEMORY; - break; - } - - hr = QueryInterface(IID_PPV_ARGS(&pSink)); - if (FAILED(hr)) - { - break; - } - - hr = m_pStream->Initialize(pSink, m_pPresenter); - if (FAILED(hr)) - { - break; - } - - m_pScheduler->SetCallback(static_cast(m_pStream)); - } - while (FALSE); - - if (FAILED(hr)) - { - Shutdown(); - } - - SafeRelease(pSink); - - return hr; -} diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/MediaSink.h b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/MediaSink.h deleted file mode 100644 index a18a0b98..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/MediaSink.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -#include "Common.h" -#include "Presenter.h" -#include "Scheduler.h" -#include "StreamSink.h" - -namespace DX11VideoRenderer -{ - class CMediaSink : - public IMFMediaSink, - public IMFClockStateSink, - public IMFGetService, - public IMFRateSupport, - public IMFMediaSinkPreroll, - private CBase - { - public: - - // Static method to create the object. - static HRESULT CreateInstance(_In_ REFIID iid, _COM_Outptr_ void** ppSink); - - // IUnknown - STDMETHODIMP_(ULONG) AddRef(void); - STDMETHODIMP QueryInterface(REFIID iid, __RPC__deref_out _Result_nullonfailure_ void** ppv); - STDMETHODIMP_(ULONG) Release(void); - - // IMFMediaSink methods - STDMETHODIMP AddStreamSink(DWORD dwStreamSinkIdentifier, __RPC__in_opt IMFMediaType* pMediaType, __RPC__deref_out_opt IMFStreamSink** ppStreamSink); - STDMETHODIMP GetCharacteristics(__RPC__out DWORD* pdwCharacteristics); - STDMETHODIMP GetPresentationClock(__RPC__deref_out_opt IMFPresentationClock** ppPresentationClock); - STDMETHODIMP GetStreamSinkById(DWORD dwIdentifier, __RPC__deref_out_opt IMFStreamSink** ppStreamSink); - STDMETHODIMP GetStreamSinkByIndex(DWORD dwIndex, __RPC__deref_out_opt IMFStreamSink** ppStreamSink); - STDMETHODIMP GetStreamSinkCount(__RPC__out DWORD* pcStreamSinkCount); - STDMETHODIMP RemoveStreamSink(DWORD dwStreamSinkIdentifier); - STDMETHODIMP SetPresentationClock(__RPC__in_opt IMFPresentationClock* pPresentationClock); - STDMETHODIMP Shutdown(void); - - // IMFClockStateSink methods - STDMETHODIMP OnClockPause(MFTIME hnsSystemTime); - STDMETHODIMP OnClockRestart(MFTIME hnsSystemTime); - STDMETHODIMP OnClockSetRate(MFTIME hnsSystemTime, float flRate); - STDMETHODIMP OnClockStart(MFTIME hnsSystemTime, LONGLONG llClockStartOffset); - STDMETHODIMP OnClockStop(MFTIME hnsSystemTime); - - // IMFGetService - STDMETHODIMP GetService(__RPC__in REFGUID guidService, __RPC__in REFIID riid, __RPC__deref_out_opt LPVOID* ppvObject); - - // IMFRateSupport - STDMETHODIMP GetFastestRate(MFRATE_DIRECTION eDirection, BOOL fThin, _Out_ float* pflRate); - STDMETHODIMP GetSlowestRate(MFRATE_DIRECTION eDirection, BOOL fThin, _Out_ float* pflRate); - STDMETHODIMP IsRateSupported(BOOL fThin, float flRate, __RPC__inout_opt float* pflNearestSupportedRate); - - // IMFMediaSinkPreroll - STDMETHODIMP NotifyPreroll(MFTIME hnsUpcomingStartTime); - - private: - - static CCritSec s_csStreamSinkAndScheduler; // critical section for thread safety, used for CStreamSink and CScheduler - - CMediaSink(void); - virtual ~CMediaSink(void); - - HRESULT CheckShutdown(void) const; - HRESULT Initialize(void); - - const DWORD STREAM_ID; // The stream ID of the one stream on the sink. - long m_nRefCount; // reference count - CCritSec m_csMediaSink; // critical section for thread safety, used for CMediaSink - BOOL m_IsShutdown; // Flag to indicate if Shutdown() method was called. - CStreamSink* m_pStream; // Byte stream - IMFPresentationClock* m_pClock; // Presentation clock. - CScheduler* m_pScheduler; // Manages scheduling of samples. - CPresenter* m_pPresenter; - }; -} diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Presenter.cpp b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Presenter.cpp deleted file mode 100644 index 5f228f79..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Presenter.cpp +++ /dev/null @@ -1,2307 +0,0 @@ -#include "Presenter.h" - -///////////////////////////////////////////////////////////////////////////////////////////// -// -// CPresenter class. - Presents samples using DX11. -// -// Notes: -// - Most public methods calls CheckShutdown. This method fails if the presenter was shut down. -// -///////////////////////////////////////////////////////////////////////////////////////////// - -//------------------------------------------------------------------- -// CPresenter constructor. -//------------------------------------------------------------------- - -DX11VideoRenderer::CPresenter::CPresenter(void) : - m_nRefCount(1), - m_critSec(), // default ctor - m_IsShutdown(FALSE), - m_pDXGIFactory2(NULL), - m_pD3D11Device(NULL), - m_pD3DImmediateContext(NULL), - m_pDXGIManager(NULL), - m_pDXGIOutput1(NULL), - m_pSampleAllocatorEx(NULL), - m_pDCompDevice(NULL), - m_pHwndTarget(NULL), - m_pRootVisual(NULL), - m_bSoftwareDXVADeviceInUse(FALSE), - m_hwndVideo(NULL), - m_pMonitors(NULL), - m_lpCurrMon(NULL), - m_DeviceResetToken(0), - m_DXSWSwitch(0), - m_useXVP(1), - m_useDCompVisual(0), - m_useDebugLayer(D3D11_CREATE_DEVICE_VIDEO_SUPPORT), - m_pDX11VideoDevice(NULL), - m_pVideoProcessorEnum(NULL), - m_pVideoProcessor(NULL), - m_pSwapChain1(NULL), - m_bDeviceChanged(FALSE), - m_bResize(TRUE), - m_b3DVideo(FALSE), - m_bStereoEnabled(FALSE), - m_vp3DOutput(MFVideo3DSampleFormat_BaseView), - m_bFullScreenState(FALSE), - m_bCanProcessNextSample(TRUE), - m_displayRect(), // default ctor - m_imageWidthInPixels(0), - m_imageHeightInPixels(0), - m_uiRealDisplayWidth(0), - m_uiRealDisplayHeight(0), - m_rcSrcApp(), // default ctor - m_rcDstApp(), // default ctor - m_pXVP(NULL), - m_pXVPControl(NULL) -{ - ZeroMemory(&m_rcSrcApp, sizeof(m_rcSrcApp)); - ZeroMemory(&m_rcDstApp, sizeof(m_rcDstApp)); -} - -//------------------------------------------------------------------- -// CPresenter destructor. -//------------------------------------------------------------------- - -DX11VideoRenderer::CPresenter::~CPresenter(void) -{ - SafeDelete(m_pMonitors); -} - -// IUnknown -ULONG DX11VideoRenderer::CPresenter::AddRef(void) -{ - return InterlockedIncrement(&m_nRefCount); -} - -// IUnknown -HRESULT DX11VideoRenderer::CPresenter::QueryInterface(REFIID iid, __RPC__deref_out _Result_nullonfailure_ void** ppv) -{ - if (!ppv) - { - return E_POINTER; - } - if (iid == IID_IUnknown) - { - *ppv = static_cast(static_cast(this)); - } - else if (iid == __uuidof(IMFVideoDisplayControl)) - { - *ppv = static_cast(this); - } - else if (iid == __uuidof(IMFGetService)) - { - *ppv = static_cast(this); - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -// IUnknown -ULONG DX11VideoRenderer::CPresenter::Release(void) -{ - ULONG uCount = InterlockedDecrement(&m_nRefCount); - if (uCount == 0) - { - delete this; - } - // For thread safety, return a temporary variable. - return uCount; -} - -// IMFVideoDisplayControl -HRESULT DX11VideoRenderer::CPresenter::GetFullscreen(__RPC__out BOOL* pfFullscreen) -{ - CAutoLock lock(&m_critSec); - - HRESULT hr = CheckShutdown(); - if (FAILED(hr)) - { - return hr; - } - - if (pfFullscreen == NULL) - { - return E_POINTER; - } - - *pfFullscreen = m_bFullScreenState; - - return S_OK; -} - -// IMFVideoDisplayControl -HRESULT DX11VideoRenderer::CPresenter::SetFullscreen(BOOL fFullscreen) -{ - CAutoLock lock(&m_critSec); - - HRESULT hr = CheckShutdown(); - - if (SUCCEEDED(hr)) - { - m_bFullScreenState = fFullscreen; - - SafeRelease(m_pDX11VideoDevice); - SafeRelease(m_pVideoProcessorEnum); - SafeRelease(m_pVideoProcessor); - } - - return hr; -} - -// IMFVideoDisplayControl -HRESULT DX11VideoRenderer::CPresenter::SetVideoWindow(__RPC__in HWND hwndVideo) -{ - HRESULT hr = S_OK; - - CAutoLock lock(&m_critSec); - - do - { - hr = CheckShutdown(); - if (FAILED(hr)) - { - break; - } - - if (!IsWindow(hwndVideo)) - { - hr = E_INVALIDARG; - break; - } - - m_pMonitors = new CMonitorArray(); - if (!m_pMonitors) - { - hr = E_OUTOFMEMORY; - break; - } - - hr = SetVideoMonitor(hwndVideo); - if (FAILED(hr)) - { - break; - } - - CheckDecodeSwitchRegKey(); - - m_hwndVideo = hwndVideo; - - hr = CreateDXGIManagerAndDevice(); - if (FAILED(hr)) - { - break; - } - - if (m_useXVP) - { - hr = CreateXVP(); - if (FAILED(hr)) - { - break; - } - } - } - while(FALSE); - - return hr; -} - -//------------------------------------------------------------------------- -// Name: GetService -// Description: IMFGetService -//------------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CPresenter::GetService(__RPC__in REFGUID guidService, __RPC__in REFIID riid, __RPC__deref_out_opt LPVOID* ppvObject) -{ - HRESULT hr = S_OK; - - if (guidService == MR_VIDEO_ACCELERATION_SERVICE) - { - if (riid == __uuidof(IMFDXGIDeviceManager)) - { - if (NULL != m_pDXGIManager) - { - *ppvObject = (void*) static_cast(m_pDXGIManager); - ((IUnknown*) *ppvObject)->AddRef(); - } - else - { - hr = E_NOINTERFACE; - } - } - else if (riid == __uuidof(IMFVideoSampleAllocatorEx)) - { - if (NULL == m_pSampleAllocatorEx) - { - hr = MFCreateVideoSampleAllocatorEx(IID_IMFVideoSampleAllocatorEx, (LPVOID*)&m_pSampleAllocatorEx); - if (SUCCEEDED(hr) && NULL != m_pDXGIManager) - { - hr = m_pSampleAllocatorEx->SetDirectXManager(m_pDXGIManager); - } - } - if (SUCCEEDED(hr)) - { - hr = m_pSampleAllocatorEx->QueryInterface(riid, ppvObject); - } - } - else - { - hr = E_NOINTERFACE; - } - } - else if (guidService == MR_VIDEO_RENDER_SERVICE) - { - hr = QueryInterface(riid, ppvObject); - } - else - { - hr = MF_E_UNSUPPORTED_SERVICE; - } - - return hr; -} - -BOOL DX11VideoRenderer::CPresenter::CanProcessNextSample(void) -{ - return m_bCanProcessNextSample; -} - -HRESULT DX11VideoRenderer::CPresenter::Flush(void) -{ - CAutoLock lock(&m_critSec); - - HRESULT hr = CheckShutdown(); - - if (SUCCEEDED(hr) && m_useXVP) - { - hr = m_pXVP->ProcessMessage(MFT_MESSAGE_COMMAND_FLUSH, 0); - } - - m_bCanProcessNextSample = TRUE; - - return hr; -} - -HRESULT DX11VideoRenderer::CPresenter::GetMonitorRefreshRate(DWORD* pdwRefreshRate) -{ - if (pdwRefreshRate == NULL) - { - return E_POINTER; - } - - if (m_lpCurrMon == NULL) - { - return MF_E_INVALIDREQUEST; - } - - *pdwRefreshRate = m_lpCurrMon->dwRefreshRate; - - return S_OK; -} - -HRESULT DX11VideoRenderer::CPresenter::IsMediaTypeSupported(IMFMediaType* pMediaType, DXGI_FORMAT dxgiFormat) -{ - HRESULT hr = S_OK; - UINT32 uiNumerator = 30000, uiDenominator = 1001; - UINT32 uimageWidthInPixels, uimageHeightInPixels = 0; - - do - { - hr = CheckShutdown(); - if (FAILED(hr)) - { - break; - } - - if (pMediaType == NULL) - { - hr = E_POINTER; - break; - } - - if (!m_pDX11VideoDevice) - { - hr = m_pD3D11Device->QueryInterface(__uuidof(ID3D11VideoDevice), (void**)&m_pDX11VideoDevice); - if (FAILED(hr)) - { - break; - } - } - - hr = MFGetAttributeSize(pMediaType, MF_MT_FRAME_SIZE, &uimageWidthInPixels, &uimageHeightInPixels); - - if (FAILED(hr)) - { - break; - } - - MFGetAttributeRatio(pMediaType, MF_MT_FRAME_RATE, &uiNumerator, &uiDenominator); - - //Check if the format is supported - - D3D11_VIDEO_PROCESSOR_CONTENT_DESC ContentDesc; - ZeroMemory( &ContentDesc, sizeof( ContentDesc ) ); - ContentDesc.InputFrameFormat = D3D11_VIDEO_FRAME_FORMAT_INTERLACED_TOP_FIELD_FIRST; - ContentDesc.InputWidth = (DWORD)uimageWidthInPixels; - ContentDesc.InputHeight = (DWORD)uimageHeightInPixels; - ContentDesc.OutputWidth = (DWORD)uimageWidthInPixels; - ContentDesc.OutputHeight = (DWORD)uimageHeightInPixels; - ContentDesc.InputFrameRate.Numerator = uiNumerator; - ContentDesc.InputFrameRate.Denominator = uiDenominator; - ContentDesc.OutputFrameRate.Numerator = uiNumerator; - ContentDesc.OutputFrameRate.Denominator = uiDenominator; - ContentDesc.Usage = D3D11_VIDEO_USAGE_PLAYBACK_NORMAL; - - SafeRelease(m_pVideoProcessorEnum); - hr = m_pDX11VideoDevice->CreateVideoProcessorEnumerator(&ContentDesc, &m_pVideoProcessorEnum); - if (FAILED(hr)) - { - break; - } - - UINT uiFlags; - hr = m_pVideoProcessorEnum->CheckVideoProcessorFormat(dxgiFormat, &uiFlags); - if (FAILED(hr) || 0 == (uiFlags & D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_INPUT)) - { - hr = MF_E_UNSUPPORTED_D3D_TYPE; - break; - } - - if (m_useXVP) - { - hr = m_pXVP->SetInputType(0, pMediaType, MFT_SET_TYPE_TEST_ONLY); - if (FAILED(hr)) - { - break; - } - } - } - while (FALSE); - - return hr; -} - -//+------------------------------------------------------------------------- -// -// Member: PresentFrame -// -// Synopsis: Present the current outstanding frame in the DX queue -// -//-------------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CPresenter::PresentFrame(void) -{ - HRESULT hr = S_OK; - - CAutoLock lock(&m_critSec); - - do - { - hr = CheckShutdown(); - if (FAILED(hr)) - { - break; - } - - if (NULL == m_pSwapChain1) - { - break; - } - - RECT rcDest; - ZeroMemory(&rcDest, sizeof(rcDest)); - if (CheckEmptyRect(&rcDest)) - { - hr = S_OK; - break; - } - - hr = m_pSwapChain1->Present( 0, 0 ); - if (FAILED(hr)) - { - break; - } - - m_bCanProcessNextSample = TRUE; - } - while (FALSE); - - return hr; -} - -//------------------------------------------------------------------- -// Name: ProcessFrame -// Description: Present one media sample. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CPresenter::ProcessFrame(IMFMediaType* pCurrentType, IMFSample* pSample, UINT32* punInterlaceMode, BOOL* pbDeviceChanged, BOOL* pbProcessAgain, IMFSample** ppOutputSample) -{ - HRESULT hr = S_OK; - BYTE* pData = NULL; - DWORD dwSampleSize = 0; - IMFMediaBuffer* pBuffer = NULL; - IMFMediaBuffer* pEVBuffer = NULL; - DWORD cBuffers = 0; - ID3D11Texture2D* pTexture2D = NULL; - IMFDXGIBuffer* pDXGIBuffer = NULL; - ID3D11Texture2D* pEVTexture2D = NULL; - IMFDXGIBuffer* pEVDXGIBuffer = NULL; - ID3D11Device* pDeviceInput = NULL; - UINT dwViewIndex = 0; - UINT dwEVViewIndex = 0; - - CAutoLock lock(&m_critSec); - - do - { - hr = CheckShutdown(); - if (FAILED(hr)) - { - break; - } - - if (punInterlaceMode == NULL || pCurrentType == NULL || pSample == NULL || pbDeviceChanged == NULL || pbProcessAgain == NULL) - { - hr = E_POINTER; - break; - } - - *pbProcessAgain = FALSE; - *pbDeviceChanged = FALSE; - - hr = pSample->GetBufferCount( &cBuffers ); - if (FAILED(hr)) - { - break; - } - - if (1 == cBuffers) - { - hr = pSample->GetBufferByIndex(0, &pBuffer); - } - else if (2 == cBuffers && m_b3DVideo && 0 != m_vp3DOutput) - { - hr = pSample->GetBufferByIndex(0, &pBuffer); - if (FAILED(hr)) - { - break; - } - - hr = pSample->GetBufferByIndex(1, &pEVBuffer); - } - else - { - hr = pSample->ConvertToContiguousBuffer(&pBuffer); - } - - if (FAILED(hr)) - { - break; - } - - hr = CheckDeviceState(pbDeviceChanged); - if (FAILED(hr)) - { - break; - } - - RECT rcDest; - ZeroMemory(&rcDest, sizeof(rcDest)); - if (CheckEmptyRect(&rcDest)) - { - hr = S_OK; - break; - } - - MFVideoInterlaceMode unInterlaceMode = (MFVideoInterlaceMode) MFGetAttributeUINT32( pCurrentType, MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive ); - - // - // Check the per-sample attributes - // - if (MFVideoInterlace_MixedInterlaceOrProgressive == unInterlaceMode) - { - BOOL fInterlaced = MFGetAttributeUINT32( pSample, MFSampleExtension_Interlaced, FALSE ); - if ( !fInterlaced ) - { - // Progressive sample - *punInterlaceMode = MFVideoInterlace_Progressive; - } - else - { - BOOL fBottomFirst = MFGetAttributeUINT32( pSample, MFSampleExtension_BottomFieldFirst, FALSE ); - if ( fBottomFirst ) - { - *punInterlaceMode = MFVideoInterlace_FieldInterleavedLowerFirst; - } - else - { - *punInterlaceMode = MFVideoInterlace_FieldInterleavedUpperFirst; - } - } - } - - hr = pBuffer->QueryInterface(__uuidof(IMFDXGIBuffer), (LPVOID*)&pDXGIBuffer); - if (FAILED(hr)) - { - break; - } - - hr = pDXGIBuffer->GetResource(__uuidof(ID3D11Texture2D), (LPVOID*)&pTexture2D); - if (FAILED(hr)) - { - break; - } - - hr = pDXGIBuffer->GetSubresourceIndex(&dwViewIndex); - if (FAILED(hr)) - { - break; - } - - if (m_b3DVideo && 0 != m_vp3DOutput) - { - if (pEVBuffer && MFVideo3DSampleFormat_MultiView == m_vp3DOutput) - { - hr = pEVBuffer->QueryInterface(__uuidof(IMFDXGIBuffer), (LPVOID*)&pEVDXGIBuffer); - if (FAILED(hr)) - { - break; - } - - hr = pEVDXGIBuffer->GetResource(__uuidof(ID3D11Texture2D), (LPVOID*)&pEVTexture2D); - if (FAILED(hr)) - { - break; - } - - hr = pEVDXGIBuffer->GetSubresourceIndex(&dwEVViewIndex); - if (FAILED(hr)) - { - break; - } - } - } - - pTexture2D->GetDevice(&pDeviceInput); - if ((NULL == pDeviceInput) || (pDeviceInput != m_pD3D11Device)) - { - break; - } - - if (m_useXVP) - { - BOOL bInputFrameUsed = FALSE; - - hr = ProcessFrameUsingXVP( pCurrentType, pSample, pTexture2D, rcDest, ppOutputSample, &bInputFrameUsed ); - - if (SUCCEEDED(hr) && !bInputFrameUsed) - { - *pbProcessAgain = TRUE; - } - } - else - { - hr = ProcessFrameUsingD3D11( pTexture2D, pEVTexture2D, dwViewIndex, dwEVViewIndex, rcDest, *punInterlaceMode, ppOutputSample ); - - LONGLONG hnsDuration = 0; - LONGLONG hnsTime = 0; - DWORD dwSampleFlags = 0; - - if (ppOutputSample != NULL && *ppOutputSample != NULL) - { - if (SUCCEEDED(pSample->GetSampleDuration(&hnsDuration))) - { - (*ppOutputSample)->SetSampleDuration(hnsDuration); - } - - if (SUCCEEDED(pSample->GetSampleTime(&hnsTime))) - { - (*ppOutputSample)->SetSampleTime(hnsTime); - } - - if (SUCCEEDED(pSample->GetSampleFlags(&dwSampleFlags))) - { - (*ppOutputSample)->SetSampleFlags(dwSampleFlags); - } - } - } - } - while (FALSE); - - SafeRelease(pTexture2D); - SafeRelease(pDXGIBuffer); - SafeRelease(pEVTexture2D); - SafeRelease(pEVDXGIBuffer); - SafeRelease(pDeviceInput); - SafeRelease(pBuffer); - SafeRelease(pEVBuffer); - - return hr; -} - -HRESULT DX11VideoRenderer::CPresenter::SetCurrentMediaType(IMFMediaType* pMediaType) -{ - HRESULT hr = S_OK; - IMFAttributes* pAttributes = NULL; - - CAutoLock lock(&m_critSec); - - do - { - hr = CheckShutdown(); - if (FAILED(hr)) - { - break; - } - - hr = pMediaType->QueryInterface(IID_IMFAttributes, reinterpret_cast(&pAttributes)); - if (FAILED(hr)) - { - break; - } - - HRESULT hr1 = pAttributes->GetUINT32(MF_MT_VIDEO_3D, (UINT32*)&m_b3DVideo); - if (SUCCEEDED(hr1)) - { - hr = pAttributes->GetUINT32(MF_MT_VIDEO_3D_FORMAT, (UINT32*)&m_vp3DOutput); - if (FAILED(hr)) - { - break; - } - } - - //Now Determine Correct Display Resolution - if (SUCCEEDED(hr)) - { - UINT32 parX = 0, parY = 0; - int PARWidth = 0, PARHeight = 0; - MFVideoArea videoArea = {0}; - ZeroMemory(&m_displayRect, sizeof(RECT)); - - if (FAILED(MFGetAttributeSize(pMediaType, MF_MT_PIXEL_ASPECT_RATIO, &parX, &parY))) - { - parX = 1; - parY = 1; - } - - hr = GetVideoDisplayArea(pMediaType, &videoArea); - if (FAILED(hr)) - { - break; - } - - m_displayRect = MFVideoAreaToRect(videoArea); - - PixelAspectToPictureAspect( - videoArea.Area.cx, - videoArea.Area.cy, - parX, - parY, - &PARWidth, - &PARHeight); - - SIZE szVideo = videoArea.Area; - SIZE szPARVideo = {PARWidth, PARHeight}; - AspectRatioCorrectSize(&szVideo, szPARVideo, videoArea.Area, FALSE); - m_uiRealDisplayWidth = szVideo.cx; - m_uiRealDisplayHeight = szVideo.cy; - } - - if (SUCCEEDED(hr) && m_useXVP) - { - // set the input type on the XVP - hr = m_pXVP->SetInputType(0, pMediaType, 0); - if (FAILED(hr)) - { - break; - } - } - } - while (FALSE); - - SafeRelease(pAttributes); - - return hr; -} - -//------------------------------------------------------------------- -// Name: Shutdown -// Description: Releases resources held by the presenter. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CPresenter::Shutdown(void) -{ - CAutoLock lock(&m_critSec); - - HRESULT hr = MF_E_SHUTDOWN; - - m_IsShutdown = TRUE; - - SafeRelease(m_pDXGIManager); - SafeRelease(m_pDXGIFactory2); - SafeRelease(m_pD3D11Device); - SafeRelease(m_pD3DImmediateContext); - SafeRelease(m_pDXGIOutput1); - SafeRelease(m_pSampleAllocatorEx); - SafeRelease(m_pDCompDevice); - SafeRelease(m_pHwndTarget); - SafeRelease(m_pRootVisual); - SafeRelease(m_pXVPControl); - SafeRelease(m_pXVP); - SafeRelease(m_pDX11VideoDevice); - SafeRelease(m_pVideoProcessor); - SafeRelease(m_pVideoProcessorEnum); - SafeRelease(m_pSwapChain1); - - return hr; -} - -/// Private methods - -//+------------------------------------------------------------------------- -// -// Function: AspectRatioCorrectSize -// -// Synopsis: Corrects the supplied size structure so that it becomes the same shape -// as the specified aspect ratio, the correction is always applied in the -// horizontal axis -// -//-------------------------------------------------------------------------- - -void DX11VideoRenderer::CPresenter::AspectRatioCorrectSize( - LPSIZE lpSizeImage, // size to be aspect ratio corrected - const SIZE& sizeAr, // aspect ratio of image - const SIZE& sizeOrig, // original image size - BOOL ScaleXorY // axis to correct in - ) -{ - int cxAR = sizeAr.cx; - int cyAR = sizeAr.cy; - int cxOr = sizeOrig.cx; - int cyOr = sizeOrig.cy; - int sx = lpSizeImage->cx; - int sy = lpSizeImage->cy; - - // MulDiv rounds correctly. - lpSizeImage->cx = MulDiv((sx * cyOr), cxAR, (cyAR * cxOr)); - - if (ScaleXorY && lpSizeImage->cx < cxOr) - { - lpSizeImage->cx = cxOr; - lpSizeImage->cy = MulDiv((sy * cxOr), cyAR, (cxAR * cyOr)); - } -} - -void DX11VideoRenderer::CPresenter::CheckDecodeSwitchRegKey(void) -{ - const TCHAR* lpcszDXSW = TEXT("DXSWSwitch"); - const TCHAR* lpcszInVP = TEXT("XVP"); - const TCHAR* lpcszDComp = TEXT("DComp"); - const TCHAR* lpcszDebugLayer = TEXT("Dbglayer"); - const TCHAR* lpcszREGKEY = TEXT("SOFTWARE\\Microsoft\\Scrunch\\CodecPack\\MSDVD"); - HKEY hk = NULL; - DWORD dwData; - DWORD cbData = sizeof(DWORD); - DWORD cbType; - - if(0 == RegOpenKeyEx(HKEY_CURRENT_USER, lpcszREGKEY, 0, KEY_READ, &hk)) - { - if (0 == RegQueryValueEx(hk, lpcszDXSW, 0, &cbType, (LPBYTE)&dwData, &cbData)) - { - m_DXSWSwitch = dwData; - } - - dwData = 0; - cbData = sizeof(DWORD); - if (0 == RegQueryValueEx(hk, lpcszInVP, 0, &cbType, (LPBYTE)&dwData, &cbData)) - { - m_useXVP = dwData; - } - - dwData = 0; - cbData = sizeof(DWORD); - if (0 == RegQueryValueEx(hk, lpcszDComp, 0, &cbType, (LPBYTE)&dwData, &cbData)) - { - m_useDCompVisual = dwData; - } - - dwData = 0; - cbData = sizeof(DWORD); - if (0 == RegQueryValueEx(hk, lpcszDebugLayer, 0, &cbType, (LPBYTE)&dwData, &cbData)) - { - m_useDebugLayer = dwData; - } - } - - if(NULL != hk) - { - RegCloseKey(hk); - } - - return; -} - -HRESULT DX11VideoRenderer::CPresenter::CheckDeviceState(BOOL* pbDeviceChanged) -{ - if (pbDeviceChanged == NULL) - { - return E_POINTER; - } - - static int deviceStateChecks = 0; - static D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_HARDWARE; - - HRESULT hr = SetVideoMonitor(m_hwndVideo); - if (FAILED(hr)) - { - return hr; - } - - if (m_pD3D11Device != NULL) - { - // Lost/hung device. Destroy the device and create a new one. - if (S_FALSE == hr || (m_DXSWSwitch > 0 && deviceStateChecks == m_DXSWSwitch)) - { - if (m_DXSWSwitch > 0 && deviceStateChecks == m_DXSWSwitch) - { - (driverType == D3D_DRIVER_TYPE_HARDWARE) ? driverType = D3D_DRIVER_TYPE_WARP : driverType = D3D_DRIVER_TYPE_HARDWARE; - } - - hr = CreateDXGIManagerAndDevice(driverType); - if (FAILED(hr)) - { - return hr; - } - - *pbDeviceChanged = TRUE; - - SafeRelease(m_pDX11VideoDevice); - SafeRelease(m_pVideoProcessorEnum); - SafeRelease(m_pVideoProcessor); - SafeRelease(m_pSwapChain1); - - deviceStateChecks = 0; - } - deviceStateChecks++; - } - - return hr; -} - -BOOL DX11VideoRenderer::CPresenter::CheckEmptyRect(RECT* pDst) -{ - GetClientRect(m_hwndVideo, pDst); - - return IsRectEmpty(pDst); -} - -HRESULT DX11VideoRenderer::CPresenter::CheckShutdown(void) const -{ - if (m_IsShutdown) - { - return MF_E_SHUTDOWN; - } - else - { - return S_OK; - } -} - -HRESULT DX11VideoRenderer::CPresenter::CreateDCompDeviceAndVisual(void) -{ - HRESULT hr = S_OK; - IDXGIDevice* pDXGIDevice = NULL; - - do - { - hr = m_pD3D11Device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast(&pDXGIDevice)); - if (FAILED(hr)) - { - break; - } - - hr = DCompositionCreateDevice(pDXGIDevice, __uuidof(IDCompositionDevice), reinterpret_cast(&m_pDCompDevice)); - if (FAILED(hr)) - { - break; - } - - hr = m_pDCompDevice->CreateTargetForHwnd(m_hwndVideo, TRUE, &m_pHwndTarget); - if (FAILED(hr)) - { - break; - } - - hr = m_pDCompDevice->CreateVisual(reinterpret_cast(&m_pRootVisual)); - if (FAILED(hr)) - { - break; - } - - hr = m_pHwndTarget->SetRoot(m_pRootVisual); - if (FAILED(hr)) - { - break; - } - } - while(FALSE); - - SafeRelease(pDXGIDevice); - - return hr; -} - -//------------------------------------------------------------------- -// Name: CreateDXGIManagerAndDevice -// Description: Creates D3D11 device and manager. -// -// Note: This method is called once when SetVideoWindow is called using -// IDX11VideoRenderer. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CPresenter::CreateDXGIManagerAndDevice(D3D_DRIVER_TYPE DriverType) -{ - HRESULT hr = S_OK; - - IDXGIAdapter* pTempAdapter = NULL; - ID3D10Multithread* pMultiThread = NULL; - IDXGIDevice1* pDXGIDev = NULL; - IDXGIAdapter1* pAdapter = NULL; - IDXGIOutput* pDXGIOutput = NULL; - - D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 }; - D3D_FEATURE_LEVEL featureLevel; - UINT resetToken; - - do - { - SafeRelease(m_pD3D11Device); - if (D3D_DRIVER_TYPE_WARP == DriverType) - { - ID3D11Device* pD3D11Device = NULL; - - hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, m_useDebugLayer, featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &pD3D11Device, &featureLevel, NULL); - - if (SUCCEEDED(hr)) - { - m_pD3D11Device = new CPrivate_ID3D11Device(pD3D11Device); - if (NULL == m_pD3D11Device) - { - E_OUTOFMEMORY; - } - } - // SafeRelease(pD3D11Device); - } - else - { - for (DWORD dwCount = 0; dwCount < ARRAYSIZE(featureLevels); dwCount++) - { - hr = D3D11CreateDevice(NULL, DriverType, NULL, m_useDebugLayer, &featureLevels[dwCount], 1, D3D11_SDK_VERSION, &m_pD3D11Device, &featureLevel, NULL); - if (SUCCEEDED(hr)) - { - ID3D11VideoDevice* pDX11VideoDevice = NULL; - hr = m_pD3D11Device->QueryInterface(__uuidof(ID3D11VideoDevice), (void**)&pDX11VideoDevice); - SafeRelease(pDX11VideoDevice); - - if (SUCCEEDED(hr)) - { - break; - } - SafeRelease(m_pD3D11Device); - } - } - } - - if (FAILED(hr)) - { - break; - } - - if (NULL == m_pDXGIManager) - { - hr = MFCreateDXGIDeviceManager(&resetToken, &m_pDXGIManager); - if (FAILED(hr)) - { - break; - } - m_DeviceResetToken = resetToken; - } - - hr = m_pDXGIManager->ResetDevice(m_pD3D11Device, m_DeviceResetToken); - if (FAILED(hr)) - { - break; - } - - SafeRelease(m_pD3DImmediateContext); - m_pD3D11Device->GetImmediateContext(&m_pD3DImmediateContext); - - // Need to explitly set the multithreaded mode for this device - hr = m_pD3DImmediateContext->QueryInterface(__uuidof(ID3D10Multithread), (void**)&pMultiThread); - if (FAILED(hr)) - { - break; - } - - pMultiThread->SetMultithreadProtected(TRUE); - - hr = m_pD3D11Device->QueryInterface( __uuidof( IDXGIDevice1 ), ( LPVOID* )&pDXGIDev ); - if (FAILED(hr)) - { - break; - } - - hr = pDXGIDev->GetAdapter(&pTempAdapter); - if (FAILED(hr)) - { - break; - } - - hr = pTempAdapter->QueryInterface( __uuidof( IDXGIAdapter1 ), (LPVOID*) &pAdapter ) ; - if (FAILED(hr)) - { - break; - } - - SafeRelease(m_pDXGIFactory2); - hr = pAdapter->GetParent( __uuidof( IDXGIFactory2 ), (LPVOID*) &m_pDXGIFactory2 ); - if (FAILED(hr)) - { - break; - } - - hr = pAdapter->EnumOutputs(0, &pDXGIOutput); - if (FAILED(hr)) - { - break; - } - - SafeRelease(m_pDXGIOutput1); - hr = pDXGIOutput->QueryInterface( __uuidof(IDXGIOutput1), (LPVOID*) &m_pDXGIOutput1 ); - if (FAILED(hr)) - { - break; - } - - if (m_useDCompVisual) - { - hr = CreateDCompDeviceAndVisual(); - if (FAILED(hr)) - { - break; - } - } - } - while(FALSE); - - SafeRelease(pTempAdapter); - SafeRelease(pMultiThread); - SafeRelease(pDXGIDev); - SafeRelease(pAdapter); - SafeRelease(pDXGIOutput); - - return hr; -} - -//------------------------------------------------------------------- -// Name: CreateXVP -// Description: Creates a new instance of the XVP MFT. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CPresenter::CreateXVP(void) -{ - HRESULT hr = S_OK; - IMFAttributes* pAttributes = NULL; - - do - { - hr = CoCreateInstance(CLSID_VideoProcessorMFT, nullptr, CLSCTX_INPROC_SERVER, IID_IMFTransform, (void**)&m_pXVP); - if (FAILED(hr)) - { - break; - } - - hr = m_pXVP->ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER, ULONG_PTR(m_pDXGIManager)); - if (FAILED(hr)) - { - break; - } - - // Tell the XVP that we are the swapchain allocator - hr = m_pXVP->GetAttributes(&pAttributes); - if (FAILED(hr)) - { - break; - } - - hr = pAttributes->SetUINT32(MF_XVP_PLAYBACK_MODE, TRUE); - if (FAILED(hr)) - { - break; - } - - hr = m_pXVP->QueryInterface(IID_PPV_ARGS(&m_pXVPControl)); - if (FAILED(hr)) - { - break; - } - } - while (FALSE); - - SafeRelease(pAttributes); - - return hr; -} - -//+------------------------------------------------------------------------- -// -// Member: FindBOBProcessorIndex -// -// Synopsis: Find the BOB video processor. BOB does not require any -// reference frames and can be used with both Progressive -// and interlaced video -// -//-------------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CPresenter::FindBOBProcessorIndex(DWORD* pIndex) -{ - HRESULT hr = S_OK; - D3D11_VIDEO_PROCESSOR_CAPS caps = {}; - D3D11_VIDEO_PROCESSOR_RATE_CONVERSION_CAPS convCaps = {}; - - *pIndex = 0; - hr = m_pVideoProcessorEnum->GetVideoProcessorCaps(&caps); - if (FAILED(hr)) - { - return hr; - } - for (DWORD i = 0; i < caps.RateConversionCapsCount; i++) - { - hr = m_pVideoProcessorEnum->GetVideoProcessorRateConversionCaps(i, &convCaps); - if (FAILED(hr)) - { - return hr; - } - - // Check the caps to see which deinterlacer is supported - if ((convCaps.ProcessorCaps & D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_BOB) != 0) - { - *pIndex = i; - return hr; - } - } - - return E_FAIL; -} - -//------------------------------------------------------------------- -// Name: GetVideoDisplayArea -// Description: get the display area from the media type. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CPresenter::GetVideoDisplayArea(IMFMediaType* pType, MFVideoArea* pArea) -{ - HRESULT hr = S_OK; - BOOL bPanScan = FALSE; - UINT32 uimageWidthInPixels = 0, uimageHeightInPixels = 0; - - hr = MFGetAttributeSize(pType, MF_MT_FRAME_SIZE, &uimageWidthInPixels, &uimageHeightInPixels); - if (FAILED(hr)) - { - return hr; - } - - if (uimageWidthInPixels != m_imageWidthInPixels || uimageHeightInPixels != m_imageHeightInPixels) - { - SafeRelease(m_pVideoProcessorEnum); - SafeRelease(m_pVideoProcessor); - SafeRelease(m_pSwapChain1); - } - - m_imageWidthInPixels = uimageWidthInPixels; - m_imageHeightInPixels = uimageHeightInPixels; - - bPanScan = MFGetAttributeUINT32(pType, MF_MT_PAN_SCAN_ENABLED, FALSE); - - // In pan/scan mode, try to get the pan/scan region. - if (bPanScan) - { - hr = pType->GetBlob( - MF_MT_PAN_SCAN_APERTURE, - (UINT8*)pArea, - sizeof(MFVideoArea), - NULL - ); - } - - // If not in pan/scan mode, or the pan/scan region is not set, - // get the minimimum display aperture. - - if (!bPanScan || hr == MF_E_ATTRIBUTENOTFOUND) - { - hr = pType->GetBlob( - MF_MT_MINIMUM_DISPLAY_APERTURE, - (UINT8*)pArea, - sizeof(MFVideoArea), - NULL - ); - - if (hr == MF_E_ATTRIBUTENOTFOUND) - { - // Minimum display aperture is not set. - - // For backward compatibility with some components, - // check for a geometric aperture. - - hr = pType->GetBlob( - MF_MT_GEOMETRIC_APERTURE, - (UINT8*)pArea, - sizeof(MFVideoArea), - NULL - ); - } - - // Default: Use the entire video area. - - if (hr == MF_E_ATTRIBUTENOTFOUND) - { - *pArea = MakeArea(0.0, 0.0, m_imageWidthInPixels, m_imageHeightInPixels); - hr = S_OK; - } - } - - return hr; -} - -//+------------------------------------------------------------------------- -// -// Function: LetterBoxDstRectPixelAspectToPictureAspect -// -// Synopsis: -// -// Takes a src rectangle and constructs the largest possible destination -// rectangle within the specifed destination rectangle such that -// the video maintains its current shape. -// -// This function assumes that pels are the same shape within both the src -// and dst rectangles. -// -//-------------------------------------------------------------------------- - -void DX11VideoRenderer::CPresenter::LetterBoxDstRect( - LPRECT lprcLBDst, // output letterboxed rectangle - const RECT& rcSrc, // input source rectangle - const RECT& rcDst // input destination rectangle - ) -{ - // figure out src/dest scale ratios - int iSrcWidth = rcSrc.right - rcSrc.left; - int iSrcHeight = rcSrc.bottom - rcSrc.top; - - int iDstWidth = rcDst.right - rcDst.left; - int iDstHeight = rcDst.bottom - rcDst.top; - - int iDstLBWidth = 0; - int iDstLBHeight = 0; - - // - // work out if we are Column or Row letter boxing - // - - if (MulDiv(iSrcWidth, iDstHeight, iSrcHeight) <= iDstWidth) - { - // - // column letter boxing - we add border color bars to the - // left and right of the video image to fill the destination - // rectangle. - // - iDstLBWidth = MulDiv(iDstHeight, iSrcWidth, iSrcHeight); - iDstLBHeight = iDstHeight; - } - else - { - // - // row letter boxing - we add border color bars to the top - // and bottom of the video image to fill the destination - // rectangle - // - iDstLBWidth = iDstWidth; - iDstLBHeight = MulDiv(iDstWidth, iSrcHeight, iSrcWidth); - } - - // - // now create a centered LB rectangle within the current destination rect - // - lprcLBDst->left = rcDst.left + ((iDstWidth - iDstLBWidth) / 2); - lprcLBDst->right = lprcLBDst->left + iDstLBWidth; - - lprcLBDst->top = rcDst.top + ((iDstHeight - iDstLBHeight) / 2); - lprcLBDst->bottom = lprcLBDst->top + iDstLBHeight; -} - -//+------------------------------------------------------------------------- -// -// Function: PixelAspectToPictureAspect -// -// Synopsis: Converts a pixel aspect ratio to a picture aspect ratio -// -//-------------------------------------------------------------------------- - -void DX11VideoRenderer::CPresenter::PixelAspectToPictureAspect( - int Width, - int Height, - int PixelAspectX, - int PixelAspectY, - int* pPictureAspectX, - int* pPictureAspectY - ) -{ - // - // sanity check - if any inputs are 0, return 0 - // - if (PixelAspectX == 0 || PixelAspectY == 0 || Width == 0 || Height == 0) - { - *pPictureAspectX = 0; - *pPictureAspectY = 0; - return; - } - - // - // start by reducing both ratios to lowest terms - // - ReduceToLowestTerms(Width, Height, &Width, &Height); - ReduceToLowestTerms(PixelAspectX, PixelAspectY, &PixelAspectX, &PixelAspectY); - - // - // Make sure that none of the values are larger than 2^16, so we don't - // overflow on the last operation. This reduces the accuracy somewhat, - // but it's a "hail mary" for incredibly strange aspect ratios that don't - // exist in practical usage. - // - while (Width > 0xFFFF || Height > 0xFFFF) - { - Width >>= 1; - Height >>= 1; - } - - while (PixelAspectX > 0xFFFF || PixelAspectY > 0xFFFF) - { - PixelAspectX >>= 1; - PixelAspectY >>= 1; - } - - ReduceToLowestTerms( - PixelAspectX * Width, - PixelAspectY * Height, - pPictureAspectX, - pPictureAspectY - ); -} - -HRESULT DX11VideoRenderer::CPresenter::ProcessFrameUsingD3D11( ID3D11Texture2D* pLeftTexture2D, ID3D11Texture2D* pRightTexture2D, UINT dwLeftViewIndex, UINT dwRightViewIndex, RECT rcDest, UINT32 unInterlaceMode, IMFSample** ppVideoOutFrame ) -{ - HRESULT hr = S_OK; - ID3D11VideoContext* pVideoContext = NULL; - ID3D11VideoProcessorInputView* pLeftInputView = NULL; - ID3D11VideoProcessorInputView* pRightInputView = NULL; - ID3D11VideoProcessorOutputView* pOutputView = NULL; - ID3D11Texture2D* pDXGIBackBuffer = NULL; - ID3D11RenderTargetView* pRTView = NULL; - IMFSample* pRTSample = NULL; - IMFMediaBuffer* pBuffer = NULL; - D3D11_VIDEO_PROCESSOR_CAPS vpCaps = {0}; - LARGE_INTEGER lpcStart,lpcEnd; - - do - { - if (!m_pDX11VideoDevice) - { - hr = m_pD3D11Device->QueryInterface(__uuidof(ID3D11VideoDevice), (void**)&m_pDX11VideoDevice); - if (FAILED(hr)) - { - break; - } - } - - hr = m_pD3DImmediateContext->QueryInterface(__uuidof( ID3D11VideoContext ), (void**)&pVideoContext); - if (FAILED(hr)) - { - break; - } - - // remember the original rectangles - RECT TRectOld = m_rcDstApp; - RECT SRectOld = m_rcSrcApp; - UpdateRectangles(&TRectOld, &SRectOld); - - //Update destination rect with current client rect - m_rcDstApp = rcDest; - - D3D11_TEXTURE2D_DESC surfaceDesc; - pLeftTexture2D->GetDesc(&surfaceDesc); - - if (!m_pVideoProcessorEnum || !m_pVideoProcessor || m_imageWidthInPixels != surfaceDesc.Width || m_imageHeightInPixels != surfaceDesc.Height) - { - SafeRelease(m_pVideoProcessorEnum); - SafeRelease(m_pVideoProcessor); - - m_imageWidthInPixels = surfaceDesc.Width; - m_imageHeightInPixels = surfaceDesc.Height; - - D3D11_VIDEO_PROCESSOR_CONTENT_DESC ContentDesc; - ZeroMemory( &ContentDesc, sizeof( ContentDesc ) ); - ContentDesc.InputFrameFormat = D3D11_VIDEO_FRAME_FORMAT_INTERLACED_TOP_FIELD_FIRST; - ContentDesc.InputWidth = surfaceDesc.Width; - ContentDesc.InputHeight = surfaceDesc.Height; - ContentDesc.OutputWidth = surfaceDesc.Width; - ContentDesc.OutputHeight = surfaceDesc.Height; - ContentDesc.Usage = D3D11_VIDEO_USAGE_PLAYBACK_NORMAL; - - hr = m_pDX11VideoDevice->CreateVideoProcessorEnumerator(&ContentDesc, &m_pVideoProcessorEnum); - if (FAILED(hr)) - { - break; - } - - UINT uiFlags; - DXGI_FORMAT VP_Output_Format = DXGI_FORMAT_B8G8R8A8_UNORM; - - hr = m_pVideoProcessorEnum->CheckVideoProcessorFormat(VP_Output_Format, &uiFlags); - if (FAILED(hr) || 0 == (uiFlags & D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_OUTPUT)) - { - hr = MF_E_UNSUPPORTED_D3D_TYPE; - break; - } - - m_rcSrcApp.left = 0; - m_rcSrcApp.top = 0; - m_rcSrcApp.right = m_uiRealDisplayWidth; - m_rcSrcApp.bottom = m_uiRealDisplayHeight; - - DWORD index; - hr = FindBOBProcessorIndex(&index); - if (FAILED(hr)) - { - break; - } - - hr = m_pDX11VideoDevice->CreateVideoProcessor(m_pVideoProcessorEnum, index, &m_pVideoProcessor); - if (FAILED(hr)) - { - break; - } - - if (m_b3DVideo) - { - hr = m_pVideoProcessorEnum->GetVideoProcessorCaps(&vpCaps); - if (FAILED(hr)) - { - break; - } - - if (vpCaps.FeatureCaps & D3D11_VIDEO_PROCESSOR_FEATURE_CAPS_STEREO) - { - m_bStereoEnabled = TRUE; - } - - DXGI_MODE_DESC1 modeFilter = { 0 }; - modeFilter.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - modeFilter.Width = surfaceDesc.Width; - modeFilter.Height = surfaceDesc.Height; - modeFilter.Stereo = m_bStereoEnabled; - - DXGI_MODE_DESC1 matchedMode; - if (m_bFullScreenState) - { - hr = m_pDXGIOutput1->FindClosestMatchingMode1(&modeFilter, &matchedMode, m_pD3D11Device); - if (FAILED(hr)) - { - break; - } - } - } - } - - // now create the input and output media types - these need to reflect - // the src and destination rectangles that we have been given. - RECT TRect = m_rcDstApp; - RECT SRect = m_rcSrcApp; - UpdateRectangles(&TRect, &SRect); - - const BOOL fDestRectChanged = !EqualRect(&TRect, &TRectOld); - - if (!m_pSwapChain1 || fDestRectChanged) - { - hr = UpdateDXGISwapChain(); - if (FAILED(hr)) - { - break; - } - } - - m_bCanProcessNextSample = FALSE; - - // Get Backbuffer - hr = m_pSwapChain1->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&pDXGIBackBuffer); - if (FAILED(hr)) - { - break; - } - - // create the output media sample - hr = MFCreateSample(&pRTSample); - if (FAILED(hr)) - { - break; - } - - hr = MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), pDXGIBackBuffer, 0, FALSE, &pBuffer); - if (FAILED(hr)) - { - break; - } - - hr = pRTSample->AddBuffer(pBuffer); - if (FAILED(hr)) - { - break; - } - - if (m_b3DVideo && 0 != m_vp3DOutput) - { - SafeRelease(pBuffer); - - hr = MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), pDXGIBackBuffer, 1, FALSE, &pBuffer); - if (FAILED(hr)) - { - break; - } - - hr = pRTSample->AddBuffer(pBuffer); - if (FAILED(hr)) - { - break; - } - } - - QueryPerformanceCounter(&lpcStart); - - QueryPerformanceCounter(&lpcEnd); - - // - // Create Output View of Output Surfaces. - // - D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC OutputViewDesc; - ZeroMemory( &OutputViewDesc, sizeof( OutputViewDesc ) ); - if (m_b3DVideo && m_bStereoEnabled) - { - OutputViewDesc.ViewDimension = D3D11_VPOV_DIMENSION_TEXTURE2DARRAY; - } - else - { - OutputViewDesc.ViewDimension = D3D11_VPOV_DIMENSION_TEXTURE2D; - } - OutputViewDesc.Texture2D.MipSlice = 0; - OutputViewDesc.Texture2DArray.MipSlice = 0; - OutputViewDesc.Texture2DArray.FirstArraySlice = 0; - if (m_b3DVideo && 0 != m_vp3DOutput) - { - OutputViewDesc.Texture2DArray.ArraySize = 2; // STEREO - } - - QueryPerformanceCounter(&lpcStart); - - hr = m_pDX11VideoDevice->CreateVideoProcessorOutputView(pDXGIBackBuffer, m_pVideoProcessorEnum, &OutputViewDesc, &pOutputView); - if (FAILED(hr)) - { - break; - } - - D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC InputLeftViewDesc; - ZeroMemory( &InputLeftViewDesc, sizeof( InputLeftViewDesc ) ); - InputLeftViewDesc.FourCC = 0; - InputLeftViewDesc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D; - InputLeftViewDesc.Texture2D.MipSlice = 0; - InputLeftViewDesc.Texture2D.ArraySlice = dwLeftViewIndex; - - hr = m_pDX11VideoDevice->CreateVideoProcessorInputView(pLeftTexture2D, m_pVideoProcessorEnum, &InputLeftViewDesc, &pLeftInputView); - if (FAILED(hr)) - { - break; - } - - if (m_b3DVideo && MFVideo3DSampleFormat_MultiView == m_vp3DOutput && pRightTexture2D) - { - D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC InputRightViewDesc; - ZeroMemory( &InputRightViewDesc, sizeof( InputRightViewDesc ) ); - InputRightViewDesc.FourCC = 0; - InputRightViewDesc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D; - InputRightViewDesc.Texture2D.MipSlice = 0; - InputRightViewDesc.Texture2D.ArraySlice = dwRightViewIndex; - - hr = m_pDX11VideoDevice->CreateVideoProcessorInputView(pRightTexture2D, m_pVideoProcessorEnum, &InputRightViewDesc, &pRightInputView); - if (FAILED(hr)) - { - break; - } - } - QueryPerformanceCounter(&lpcEnd); - - QueryPerformanceCounter(&lpcStart); - - SetVideoContextParameters(pVideoContext, &SRect, &TRect, unInterlaceMode); - - // Enable/Disable Stereo - if (m_b3DVideo) - { - pVideoContext->VideoProcessorSetOutputStereoMode(m_pVideoProcessor, m_bStereoEnabled); - - D3D11_VIDEO_PROCESSOR_STEREO_FORMAT vpStereoFormat = D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_SEPARATE; - if (MFVideo3DSampleFormat_Packed_LeftRight == m_vp3DOutput) - { - vpStereoFormat = D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_HORIZONTAL; - } - else if (MFVideo3DSampleFormat_Packed_TopBottom == m_vp3DOutput) - { - vpStereoFormat = D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_VERTICAL; - } - - pVideoContext->VideoProcessorSetStreamStereoFormat(m_pVideoProcessor, - 0, m_bStereoEnabled, vpStereoFormat, TRUE, TRUE, D3D11_VIDEO_PROCESSOR_STEREO_FLIP_NONE, 0); - } - - QueryPerformanceCounter(&lpcEnd); - - QueryPerformanceCounter(&lpcStart); - - D3D11_VIDEO_PROCESSOR_STREAM StreamData; - ZeroMemory( &StreamData, sizeof( StreamData ) ); - StreamData.Enable = TRUE; - StreamData.OutputIndex = 0; - StreamData.InputFrameOrField = 0; - StreamData.PastFrames = 0; - StreamData.FutureFrames = 0; - StreamData.ppPastSurfaces = NULL; - StreamData.ppFutureSurfaces = NULL; - StreamData.pInputSurface = pLeftInputView; - StreamData.ppPastSurfacesRight = NULL; - StreamData.ppFutureSurfacesRight = NULL; - - if (m_b3DVideo && MFVideo3DSampleFormat_MultiView == m_vp3DOutput && pRightTexture2D) - { - StreamData.pInputSurfaceRight = pRightInputView; - } - - hr = pVideoContext->VideoProcessorBlt(m_pVideoProcessor, pOutputView, 0, 1, &StreamData ); - if (FAILED(hr)) - { - break; - } - QueryPerformanceCounter(&lpcEnd); - - if (ppVideoOutFrame != NULL) - { - *ppVideoOutFrame = pRTSample; - (*ppVideoOutFrame)->AddRef(); - } - } - while (FALSE); - - SafeRelease(pBuffer); - SafeRelease(pRTSample); - SafeRelease(pDXGIBackBuffer); - SafeRelease(pOutputView); - SafeRelease(pLeftInputView); - SafeRelease(pRightInputView); - SafeRelease(pVideoContext); - - return hr; -} - -HRESULT DX11VideoRenderer::CPresenter::ProcessFrameUsingXVP( IMFMediaType* pCurrentType, IMFSample* pVideoFrame, ID3D11Texture2D* pTexture2D, RECT rcDest, IMFSample** ppVideoOutFrame, BOOL* pbInputFrameUsed ) -{ - HRESULT hr = S_OK; - ID3D11VideoContext* pVideoContext = NULL; - ID3D11Texture2D* pDXGIBackBuffer = NULL; - IMFSample* pRTSample = NULL; - IMFMediaBuffer* pBuffer = NULL; - IMFAttributes* pAttributes = NULL; - D3D11_VIDEO_PROCESSOR_CAPS vpCaps = {0}; - - do - { - if (!m_pDX11VideoDevice) - { - hr = m_pD3D11Device->QueryInterface(__uuidof(ID3D11VideoDevice), (void**)&m_pDX11VideoDevice); - if (FAILED(hr)) - { - break; - } - } - - hr = m_pD3DImmediateContext->QueryInterface(__uuidof( ID3D11VideoContext ), (void**)&pVideoContext); - if (FAILED(hr)) - { - break; - } - - // remember the original rectangles - RECT TRectOld = m_rcDstApp; - RECT SRectOld = m_rcSrcApp; - UpdateRectangles(&TRectOld, &SRectOld); - - //Update destination rect with current client rect - m_rcDstApp = rcDest; - - D3D11_TEXTURE2D_DESC surfaceDesc; - pTexture2D->GetDesc(&surfaceDesc); - - BOOL fTypeChanged = FALSE; - if (!m_pVideoProcessorEnum || !m_pSwapChain1 || m_imageWidthInPixels != surfaceDesc.Width || m_imageHeightInPixels != surfaceDesc.Height) - { - SafeRelease(m_pVideoProcessorEnum); - SafeRelease(m_pSwapChain1); - - m_imageWidthInPixels = surfaceDesc.Width; - m_imageHeightInPixels = surfaceDesc.Height; - fTypeChanged = TRUE; - - D3D11_VIDEO_PROCESSOR_CONTENT_DESC ContentDesc; - ZeroMemory( &ContentDesc, sizeof( ContentDesc ) ); - ContentDesc.InputFrameFormat = D3D11_VIDEO_FRAME_FORMAT_INTERLACED_TOP_FIELD_FIRST; - ContentDesc.InputWidth = surfaceDesc.Width; - ContentDesc.InputHeight = surfaceDesc.Height; - ContentDesc.OutputWidth = surfaceDesc.Width; - ContentDesc.OutputHeight = surfaceDesc.Height; - ContentDesc.Usage = D3D11_VIDEO_USAGE_PLAYBACK_NORMAL; - - hr = m_pDX11VideoDevice->CreateVideoProcessorEnumerator(&ContentDesc, &m_pVideoProcessorEnum); - if (FAILED(hr)) - { - break; - } - - m_rcSrcApp.left = 0; - m_rcSrcApp.top = 0; - m_rcSrcApp.right = m_uiRealDisplayWidth; - m_rcSrcApp.bottom = m_uiRealDisplayHeight; - - if (m_b3DVideo) - { - hr = m_pVideoProcessorEnum->GetVideoProcessorCaps(&vpCaps); - if (FAILED(hr)) - { - break; - } - - if (vpCaps.FeatureCaps & D3D11_VIDEO_PROCESSOR_FEATURE_CAPS_STEREO) - { - m_bStereoEnabled = TRUE; - } - - DXGI_MODE_DESC1 modeFilter = { 0 }; - modeFilter.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - modeFilter.Width = surfaceDesc.Width; - modeFilter.Height = surfaceDesc.Height; - modeFilter.Stereo = m_bStereoEnabled; - - DXGI_MODE_DESC1 matchedMode; - if (m_bFullScreenState) - { - hr = m_pDXGIOutput1->FindClosestMatchingMode1(&modeFilter, &matchedMode, m_pD3D11Device); - if (FAILED(hr)) - { - break; - } - } - - hr = m_pXVP->GetAttributes(&pAttributes); - if (FAILED(hr)) - { - break; - } - - hr = pAttributes->SetUINT32(MF_ENABLE_3DVIDEO_OUTPUT, (0 != m_vp3DOutput) ? MF3DVideoOutputType_Stereo : MF3DVideoOutputType_BaseView); - if (FAILED(hr)) - { - break; - } - } - } - - // now create the input and output media types - these need to reflect - // the src and destination rectangles that we have been given. - RECT TRect = m_rcDstApp; - RECT SRect = m_rcSrcApp; - UpdateRectangles(&TRect, &SRect); - - const BOOL fDestRectChanged = !EqualRect(&TRect, &TRectOld); - const BOOL fSrcRectChanged = !EqualRect(&SRect, &SRectOld); - - if (!m_pSwapChain1 || fDestRectChanged) - { - hr = UpdateDXGISwapChain(); - if (FAILED(hr)) - { - break; - } - } - - if (fTypeChanged || fSrcRectChanged || fDestRectChanged) - { - // stop streaming to avoid multiple start\stop calls internally in XVP - hr = m_pXVP->ProcessMessage(MFT_MESSAGE_NOTIFY_END_STREAMING, 0); - if (FAILED(hr)) - { - break; - } - - if (fTypeChanged) - { - hr = SetXVPOutputMediaType(pCurrentType, DXGI_FORMAT_B8G8R8A8_UNORM); - if (FAILED(hr)) - { - break; - } - } - - if (fDestRectChanged) - { - hr = m_pXVPControl->SetDestinationRectangle(&m_rcDstApp); - if (FAILED(hr)) - { - break; - } - } - - if (fSrcRectChanged) - { - hr = m_pXVPControl->SetSourceRectangle(&SRect); - if (FAILED(hr)) - { - break; - } - } - - hr = m_pXVP->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0); - if (FAILED(hr)) - { - break; - } - } - - m_bCanProcessNextSample = FALSE; - - // Get Backbuffer - hr = m_pSwapChain1->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&pDXGIBackBuffer); - if (FAILED(hr)) - { - break; - } - - // create the output media sample - hr = MFCreateSample(&pRTSample); - if (FAILED(hr)) - { - break; - } - - hr = MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), pDXGIBackBuffer, 0, FALSE, &pBuffer); - if (FAILED(hr)) - { - break; - } - - hr = pRTSample->AddBuffer(pBuffer); - if (FAILED(hr)) - { - break; - } - - if (m_b3DVideo && 0 != m_vp3DOutput) - { - SafeRelease(pBuffer); - - hr = MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), pDXGIBackBuffer, 1, FALSE, &pBuffer); - if (FAILED(hr)) - { - break; - } - - hr = pRTSample->AddBuffer(pBuffer); - if (FAILED(hr)) - { - break; - } - } - - DWORD dwStatus = 0; - MFT_OUTPUT_DATA_BUFFER outputDataBuffer = {}; - outputDataBuffer.pSample = pRTSample; - hr = m_pXVP->ProcessOutput(0, 1, &outputDataBuffer, &dwStatus); - if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) - { - //call process input on the MFT to deliver the YUV video sample - // and the call process output to extract of newly processed frame - hr = m_pXVP->ProcessInput(0, pVideoFrame, 0); - if (FAILED(hr)) - { - break; - } - - *pbInputFrameUsed = TRUE; - - hr = m_pXVP->ProcessOutput(0, 1, &outputDataBuffer, &dwStatus); - if (FAILED(hr)) - { - break; - } - } - else - { - *pbInputFrameUsed = FALSE; - } - - if (ppVideoOutFrame != NULL) - { - *ppVideoOutFrame = pRTSample; - (*ppVideoOutFrame)->AddRef(); - } - } - while (FALSE); - - SafeRelease(pAttributes); - SafeRelease(pBuffer); - SafeRelease(pRTSample); - SafeRelease(pDXGIBackBuffer); - SafeRelease(pVideoContext); - - return hr; -} - -//+------------------------------------------------------------------------- -// -// Function: ReduceToLowestTerms -// -// Synopsis: reduces a numerator and denominator pair to their lowest terms -// -//-------------------------------------------------------------------------- - -void DX11VideoRenderer::CPresenter::ReduceToLowestTerms( - int NumeratorIn, - int DenominatorIn, - int* pNumeratorOut, - int* pDenominatorOut - ) -{ - int GCD = gcd(NumeratorIn, DenominatorIn); - - *pNumeratorOut = NumeratorIn / GCD; - *pDenominatorOut = DenominatorIn / GCD; -} - -HRESULT DX11VideoRenderer::CPresenter::SetMonitor(UINT adapterID) -{ - HRESULT hr = S_OK; - DWORD dwMatchID = 0; - - CAutoLock lock(&m_critSec); - - do - { - hr = m_pMonitors->MatchGUID(adapterID, &dwMatchID); - if (FAILED(hr)) - { - break; - } - - if (hr == S_FALSE) - { - hr = E_INVALIDARG; - break; - } - - m_lpCurrMon = &(*m_pMonitors)[dwMatchID]; - m_ConnectionGUID = adapterID; - } - while (FALSE); - - return hr; -} - -//+------------------------------------------------------------------------- -// -// Member: SetVideoContextParameters -// -// Synopsis: Updates the various parameters used for VpBlt call -// -//-------------------------------------------------------------------------- - -void DX11VideoRenderer::CPresenter::SetVideoContextParameters(ID3D11VideoContext* pVideoContext, const RECT* pSRect, const RECT* pTRect, UINT32 unInterlaceMode) -{ - D3D11_VIDEO_FRAME_FORMAT FrameFormat = D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE; - if ( MFVideoInterlace_FieldInterleavedUpperFirst == unInterlaceMode || MFVideoInterlace_FieldSingleUpper == unInterlaceMode || MFVideoInterlace_MixedInterlaceOrProgressive == unInterlaceMode ) - { - FrameFormat = D3D11_VIDEO_FRAME_FORMAT_INTERLACED_TOP_FIELD_FIRST; - } - else if ( MFVideoInterlace_FieldInterleavedLowerFirst == unInterlaceMode || MFVideoInterlace_FieldSingleLower == unInterlaceMode ) - { - FrameFormat = D3D11_VIDEO_FRAME_FORMAT_INTERLACED_BOTTOM_FIELD_FIRST; - } - - // input format - pVideoContext->VideoProcessorSetStreamFrameFormat(m_pVideoProcessor, 0, FrameFormat); - - // Output rate (repeat frames) - pVideoContext->VideoProcessorSetStreamOutputRate(m_pVideoProcessor, 0, D3D11_VIDEO_PROCESSOR_OUTPUT_RATE_NORMAL, TRUE, NULL); - - // Source rect - pVideoContext->VideoProcessorSetStreamSourceRect(m_pVideoProcessor, 0, TRUE, pSRect); - - // Stream dest rect - pVideoContext->VideoProcessorSetStreamDestRect(m_pVideoProcessor, 0, TRUE, pTRect); - - pVideoContext->VideoProcessorSetOutputTargetRect(m_pVideoProcessor, TRUE, &m_rcDstApp); - - // Stream color space - D3D11_VIDEO_PROCESSOR_COLOR_SPACE colorSpace = {}; - colorSpace.YCbCr_xvYCC = 1; - pVideoContext->VideoProcessorSetStreamColorSpace(m_pVideoProcessor, 0, &colorSpace); - - // Output color space - pVideoContext->VideoProcessorSetOutputColorSpace(m_pVideoProcessor, &colorSpace); - - // Output background color (black) - D3D11_VIDEO_COLOR backgroundColor = {}; - backgroundColor.RGBA.A = 1.0F; - backgroundColor.RGBA.R = 1.0F * static_cast(GetRValue(0)) / 255.0F; - backgroundColor.RGBA.G = 1.0F * static_cast(GetGValue(0)) / 255.0F; - backgroundColor.RGBA.B = 1.0F * static_cast(GetBValue(0)) / 255.0F; - - pVideoContext->VideoProcessorSetOutputBackgroundColor(m_pVideoProcessor, FALSE, &backgroundColor); -} - -HRESULT DX11VideoRenderer::CPresenter::SetVideoMonitor(HWND hwndVideo) -{ - HRESULT hr = S_OK; - CAMDDrawMonitorInfo* pMonInfo = NULL; - HMONITOR hMon = NULL; - - if (!m_pMonitors) - { - return E_UNEXPECTED; - } - - hMon = MonitorFromWindow(hwndVideo, MONITOR_DEFAULTTONULL); - - do - { - if (NULL != hMon) - { - m_pMonitors->TerminateDisplaySystem(); - m_lpCurrMon = NULL; - - hr = m_pMonitors->InitializeDisplaySystem(hwndVideo); - if (FAILED(hr)) - { - break; - } - - pMonInfo = m_pMonitors->FindMonitor(hMon); - if (NULL != pMonInfo && pMonInfo->uDevID != m_ConnectionGUID) - { - hr = SetMonitor(pMonInfo->uDevID); - if (FAILED(hr)) - { - break; - } - hr = S_FALSE; - } - } - else - { - hr = E_POINTER; - break; - } - } - while(FALSE); - - return hr; -} - -//------------------------------------------------------------------- -// Name: SetXVPOutputMediaType -// Description: Tells the XVP about the size of the destination surface -// and where within the surface we should be writing. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CPresenter::SetXVPOutputMediaType(IMFMediaType* pType, DXGI_FORMAT vpOutputFormat) -{ - HRESULT hr = S_OK; - IMFVideoMediaType* pMTOutput = NULL; - MFVIDEOFORMAT mfvf = {}; - - if (SUCCEEDED(hr)) - { - hr = MFInitVideoFormat_RGB( - &mfvf, - m_rcDstApp.right, - m_rcDstApp.bottom, - MFMapDXGIFormatToDX9Format(vpOutputFormat)); - } - - if (SUCCEEDED(hr)) - { - hr = MFCreateVideoMediaType(&mfvf, &pMTOutput); - } - - if (SUCCEEDED(hr)) - { - hr = m_pXVP->SetOutputType(0, pMTOutput, 0); - } - - SafeRelease(pMTOutput); - - return hr; -} - -//+------------------------------------------------------------------------- -// -// Member: UpdateDXGISwapChain -// -// Synopsis: Creates SwapChain for HWND or DComp or Resizes buffers in case of resolution change -// -//-------------------------------------------------------------------------- - -_Post_satisfies_(this->m_pSwapChain1 != NULL) -HRESULT DX11VideoRenderer::CPresenter::UpdateDXGISwapChain(void) -{ - HRESULT hr = S_OK; - - // Get the DXGISwapChain1 - DXGI_SWAP_CHAIN_DESC1 scd; - ZeroMemory(&scd, sizeof(scd)); - scd.SampleDesc.Count = 1; - scd.SampleDesc.Quality = 0; - scd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; - scd.Scaling = DXGI_SCALING_STRETCH; - scd.Width = m_rcDstApp.right; - scd.Height = m_rcDstApp.bottom; - scd.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - scd.Stereo = m_bStereoEnabled; - scd.BufferUsage = DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_RENDER_TARGET_OUTPUT; - scd.Flags = m_bStereoEnabled ? DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH : 0; //opt in to do direct flip; - scd.BufferCount = 4; - - do - { - if (m_pSwapChain1) - { - // Resize our back buffers for the desired format. - hr = m_pSwapChain1->ResizeBuffers - ( - 4, - m_rcDstApp.right, - m_rcDstApp.bottom, - scd.Format, - scd.Flags - ); - - break; - } - - if (!m_useDCompVisual) - { - hr = m_pDXGIFactory2->CreateSwapChainForHwnd(m_pD3D11Device, m_hwndVideo, &scd, NULL, NULL, &m_pSwapChain1); - if (FAILED(hr)) - { - break; - } - - if (m_bFullScreenState) - { - hr = m_pSwapChain1->SetFullscreenState(TRUE, NULL); - if (FAILED(hr)) - { - break; - } - } - else - { - hr = m_pSwapChain1->SetFullscreenState(FALSE, NULL); - if (FAILED(hr)) - { - break; - } - } - } - else - { - // Create a swap chain for composition - hr = m_pDXGIFactory2->CreateSwapChainForComposition(m_pD3D11Device, &scd, NULL, &m_pSwapChain1); - if (FAILED(hr)) - { - break; - } - - hr = m_pRootVisual->SetContent(m_pSwapChain1); - if (FAILED(hr)) - { - break; - } - - hr = m_pDCompDevice->Commit(); - if (FAILED(hr)) - { - break; - } - } - } - while (FALSE); - - return hr; -} - -//+------------------------------------------------------------------------- -// -// Member: UpodateRectangles -// -// Synopsis: Figures out the real source and destination rectangles -// to use when drawing the video frame into the clients -// destination location. Takes into account pixel aspect -// ration correction, letterboxing and source rectangles. -// -//-------------------------------------------------------------------------- - -void DX11VideoRenderer::CPresenter::UpdateRectangles(RECT* pDst, RECT* pSrc) -{ - // take the given src rect and reverse map it into the native video - // image rectange. For example, consider a video with a buffer size of - // 720x480 and an active area of 704x480 - 8,0 with a picture aspect - // ratio of 4:3. The user sees the native video size as 640x480. - // - // If the user gave us a src rectangle of (180, 135, 540, 405) - // then this gets reversed mapped to - // - // 8 + (180 * 704 / 640) = 206 - // 0 + (135 * 480 / 480) = 135 - // 8 + (540 * 704 / 640) = 602 - // 0 + (405 * 480 / 480) = 405 - - RECT Src = *pSrc; - - pSrc->left = m_displayRect.left + MulDiv(pSrc->left, (m_displayRect.right - m_displayRect.left), m_uiRealDisplayWidth); - pSrc->right = m_displayRect.left + MulDiv(pSrc->right, (m_displayRect.right - m_displayRect.left), m_uiRealDisplayWidth); - - pSrc->top = m_displayRect.top + MulDiv(pSrc->top, (m_displayRect.bottom - m_displayRect.top), m_uiRealDisplayHeight); - pSrc->bottom = m_displayRect.top + MulDiv(pSrc->bottom, (m_displayRect.bottom - m_displayRect.top), m_uiRealDisplayHeight); - - LetterBoxDstRect(pDst, Src, m_rcDstApp); -} diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Presenter.h b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Presenter.h deleted file mode 100644 index 1f379e70..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Presenter.h +++ /dev/null @@ -1,704 +0,0 @@ -#pragma once - -#include "Common.h" -#include "display.h" - -namespace DX11VideoRenderer -{ - class CPresenter : - public IMFVideoDisplayControl, - public IMFGetService, - private CBase - { - public: - CPresenter(void); - virtual ~CPresenter(void); - - // IUnknown - STDMETHODIMP_(ULONG) AddRef(void); - STDMETHODIMP QueryInterface(REFIID iid, __RPC__deref_out _Result_nullonfailure_ void** ppv); - STDMETHODIMP_(ULONG) Release(void); - - // IMFVideoDisplayControl - STDMETHODIMP GetAspectRatioMode(__RPC__out DWORD* pdwAspectRatioMode) { return E_NOTIMPL; } - STDMETHODIMP GetBorderColor(__RPC__out COLORREF* pClr) { return E_NOTIMPL; } - STDMETHODIMP GetCurrentImage(__RPC__inout BITMAPINFOHEADER* pBih, __RPC__deref_out_ecount_full_opt(*pcbDib) BYTE** pDib, __RPC__out DWORD* pcbDib, __RPC__inout_opt LONGLONG* pTimestamp) { return E_NOTIMPL; } - STDMETHODIMP GetFullscreen(__RPC__out BOOL* pfFullscreen); - STDMETHODIMP GetIdealVideoSize(__RPC__inout_opt SIZE* pszMin, __RPC__inout_opt SIZE* pszMax) { return E_NOTIMPL; } - STDMETHODIMP GetNativeVideoSize(__RPC__inout_opt SIZE* pszVideo, __RPC__inout_opt SIZE* pszARVideo) { return E_NOTIMPL; } - STDMETHODIMP GetRenderingPrefs(__RPC__out DWORD* pdwRenderFlags) { return E_NOTIMPL; } - STDMETHODIMP GetVideoPosition(__RPC__out MFVideoNormalizedRect* pnrcSource, __RPC__out LPRECT prcDest) { return E_NOTIMPL; } - STDMETHODIMP GetVideoWindow(__RPC__deref_out_opt HWND* phwndVideo) { return E_NOTIMPL; } - STDMETHODIMP RepaintVideo(void) { return E_NOTIMPL; } - STDMETHODIMP SetAspectRatioMode(DWORD dwAspectRatioMode) { return E_NOTIMPL; } - STDMETHODIMP SetBorderColor(COLORREF Clr) { return E_NOTIMPL; } - STDMETHODIMP SetFullscreen(BOOL fFullscreen); - STDMETHODIMP SetRenderingPrefs(DWORD dwRenderingPrefs) { return E_NOTIMPL; } - STDMETHODIMP SetVideoPosition(__RPC__in_opt const MFVideoNormalizedRect* pnrcSource, __RPC__in_opt const LPRECT prcDest) { return E_NOTIMPL; } - STDMETHODIMP SetVideoWindow(__RPC__in HWND hwndVideo); - - // IMFGetService - STDMETHODIMP GetService(__RPC__in REFGUID guidService, __RPC__in REFIID riid, __RPC__deref_out_opt LPVOID* ppvObject); - - BOOL CanProcessNextSample(void); - HRESULT Flush(void); - HRESULT GetMonitorRefreshRate(DWORD* pdwMonitorRefreshRate); - HRESULT IsMediaTypeSupported(IMFMediaType* pMediaType, DXGI_FORMAT dxgiFormat); - HRESULT PresentFrame(void); - HRESULT ProcessFrame(IMFMediaType* pCurrentType, IMFSample* pSample, UINT32* punInterlaceMode, BOOL* pbDeviceChanged, BOOL* pbProcessAgain, IMFSample** ppOutputSample = NULL); - HRESULT SetCurrentMediaType(IMFMediaType* pMediaType); - HRESULT Shutdown(void); - - private: - - void AspectRatioCorrectSize( - LPSIZE lpSizeImage, // size to be aspect ratio corrected - const SIZE& sizeAr, // aspect ratio of image - const SIZE& sizeOrig, // original image size - BOOL ScaleXorY // axis to correct in - ); - void CheckDecodeSwitchRegKey(void); - HRESULT CheckDeviceState(BOOL* pbDeviceChanged); - BOOL CheckEmptyRect(RECT* pDst); - HRESULT CheckShutdown(void) const; - HRESULT CreateDCompDeviceAndVisual(void); - HRESULT CreateDXGIManagerAndDevice(D3D_DRIVER_TYPE DriverType=D3D_DRIVER_TYPE_HARDWARE); - HRESULT CreateXVP(void); - HRESULT FindBOBProcessorIndex(DWORD* pIndex); - HRESULT GetVideoDisplayArea(IMFMediaType* pType, MFVideoArea* pArea); - void LetterBoxDstRect( - LPRECT lprcLBDst, // output letterboxed rectangle - const RECT& rcSrc, // input source rectangle - const RECT& rcDst // input destination rectangle - ); - void PixelAspectToPictureAspect( - int Width, - int Height, - int PixelAspectX, - int PixelAspectY, - int* pPictureAspectX, - int* pPictureAspectY - ); - HRESULT ProcessFrameUsingD3D11( ID3D11Texture2D* pLeftTexture2D, ID3D11Texture2D* pRightTexture2D, UINT dwLeftViewIndex, UINT dwRightViewIndex, RECT rcDest, UINT32 unInterlaceMode, IMFSample** ppVideoOutFrame ); - HRESULT ProcessFrameUsingXVP( IMFMediaType* pCurrentType, IMFSample* pVideoFrame, ID3D11Texture2D* pTexture2D, RECT rcDest, IMFSample** ppVideoOutFrame, BOOL* pbInputFrameUsed ); - void ReduceToLowestTerms( - int NumeratorIn, - int DenominatorIn, - int* pNumeratorOut, - int* pDenominatorOut - ); - HRESULT SetMonitor(UINT adapterID); - void SetVideoContextParameters(ID3D11VideoContext* pVideoContext, const RECT* pSRect, const RECT* pTRect, UINT32 unInterlaceMode); - HRESULT SetVideoMonitor(HWND hwndVideo); - HRESULT SetXVPOutputMediaType(IMFMediaType* pType, DXGI_FORMAT vpOutputFormat); - _Post_satisfies_(this->m_pSwapChain1 != NULL) - HRESULT UpdateDXGISwapChain(void); - void UpdateRectangles(RECT* pDst, RECT* pSrc); - - long m_nRefCount; // reference count - CCritSec m_critSec; // critical section for thread safety - BOOL m_IsShutdown; // Flag to indicate if Shutdown() method was called. - IDXGIFactory2* m_pDXGIFactory2; - ID3D11Device* m_pD3D11Device; - ID3D11DeviceContext* m_pD3DImmediateContext; - IMFDXGIDeviceManager* m_pDXGIManager; - IDXGIOutput1* m_pDXGIOutput1; - IMFVideoSampleAllocatorEx* m_pSampleAllocatorEx; - IDCompositionDevice* m_pDCompDevice; - IDCompositionTarget* m_pHwndTarget; - IDCompositionVisual* m_pRootVisual; - BOOL m_bSoftwareDXVADeviceInUse; - HWND m_hwndVideo; - CMonitorArray* m_pMonitors; - CAMDDrawMonitorInfo* m_lpCurrMon; - UINT m_DeviceResetToken; - UINT m_ConnectionGUID; - UINT m_DXSWSwitch; - UINT m_useXVP; - UINT m_useDCompVisual; - UINT m_useDebugLayer; - ID3D11VideoDevice* m_pDX11VideoDevice; - ID3D11VideoProcessorEnumerator* m_pVideoProcessorEnum; - ID3D11VideoProcessor* m_pVideoProcessor; - IDXGISwapChain1* m_pSwapChain1; - BOOL m_bDeviceChanged; - BOOL m_bResize; - BOOL m_b3DVideo; - BOOL m_bStereoEnabled; - MFVideo3DFormat m_vp3DOutput; - BOOL m_bFullScreenState; - BOOL m_bCanProcessNextSample; - RECT m_displayRect; - UINT32 m_imageWidthInPixels; - UINT32 m_imageHeightInPixels; - UINT32 m_uiRealDisplayWidth; - UINT32 m_uiRealDisplayHeight; - RECT m_rcSrcApp; - RECT m_rcDstApp; - IMFTransform* m_pXVP; - IMFVideoProcessorControl* m_pXVPControl; - }; - - ///////////////////////////////////////////////////////////////////////////////////////////// - // Wrapper class for D3D11 Device and D3D11 Video device used for DXVA to Software decode switch - class CPrivate_ID3D11VideoDevice : public ID3D11VideoDevice - { - private: - - ID3D11VideoDevice* m_pReal; - ULONG m_cRef; - - public: - - CPrivate_ID3D11VideoDevice(ID3D11VideoDevice* pReal) : - m_pReal(pReal), - m_cRef(0) - { - } - - virtual ~CPrivate_ID3D11VideoDevice(void) - { - } - - STDMETHODIMP QueryInterface( - /* [in] */ REFIID riid, - /* [iid_is][out] */ __RPC__deref_out void __RPC_FAR* __RPC_FAR* ppvObject) - { - if (__uuidof(ID3D11VideoDevice) == riid) - { - this->AddRef(); - *ppvObject = this; - return S_OK; - } - else - { - return m_pReal->QueryInterface(riid,ppvObject); - } - } - - STDMETHODIMP_(ULONG) AddRef(void) - { - InterlockedIncrement(&m_cRef); - return m_pReal->AddRef(); - } - - STDMETHODIMP_(ULONG) Release(void) - { - ULONG ulVal = m_pReal->Release(); - if (0 == InterlockedDecrement(&m_cRef)) - { - } - return ulVal; - } - - STDMETHODIMP CreateVideoDecoder( - _In_ const D3D11_VIDEO_DECODER_DESC* pVideoDesc, - _In_ const D3D11_VIDEO_DECODER_CONFIG* pConfig, - _Out_ ID3D11VideoDecoder** ppDecoder) - { - return E_FAIL; - } - - STDMETHODIMP CreateVideoProcessor( - _In_ ID3D11VideoProcessorEnumerator* pEnum, - _In_ UINT RateConversionIndex, - _Out_ ID3D11VideoProcessor** ppVideoProcessor) - { - return m_pReal->CreateVideoProcessor(pEnum,RateConversionIndex,ppVideoProcessor); - } - - STDMETHODIMP CreateAuthenticatedChannel( - _In_ D3D11_AUTHENTICATED_CHANNEL_TYPE ChannelType, - _Out_ ID3D11AuthenticatedChannel** ppAuthenticatedChannel) - { - return m_pReal->CreateAuthenticatedChannel(ChannelType,ppAuthenticatedChannel); - } - - STDMETHODIMP CreateCryptoSession( - _In_ const GUID* pCryptoType, - _In_opt_ const GUID* pDecoderProfile, - _In_ const GUID* pKeyExchangeType, - _Outptr_ ID3D11CryptoSession** ppCryptoSession) - { - return m_pReal->CreateCryptoSession(pCryptoType,pDecoderProfile,pKeyExchangeType,ppCryptoSession); - } - - STDMETHODIMP CreateVideoDecoderOutputView( - _In_ ID3D11Resource* pResource, - _In_ const D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC* pDesc, - _Out_opt_ ID3D11VideoDecoderOutputView** ppVDOVView) - { - return m_pReal->CreateVideoDecoderOutputView(pResource,pDesc,ppVDOVView); - } - - STDMETHODIMP CreateVideoProcessorInputView( - _In_ ID3D11Resource* pResource, - _In_ ID3D11VideoProcessorEnumerator* pEnum, - _In_ const D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC* pDesc, - _Out_opt_ ID3D11VideoProcessorInputView** ppVPIView) - { - return m_pReal->CreateVideoProcessorInputView(pResource,pEnum,pDesc,ppVPIView); - } - - STDMETHODIMP CreateVideoProcessorOutputView( - _In_ ID3D11Resource* pResource, - _In_ ID3D11VideoProcessorEnumerator* pEnum, - _In_ const D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC* pDesc, - _Out_opt_ ID3D11VideoProcessorOutputView** ppVPOView) - { - return m_pReal->CreateVideoProcessorOutputView(pResource,pEnum,pDesc,ppVPOView); - } - - STDMETHODIMP CreateVideoProcessorEnumerator( - _In_ const D3D11_VIDEO_PROCESSOR_CONTENT_DESC* pDesc, - _Out_ ID3D11VideoProcessorEnumerator** ppEnum) - { - return m_pReal->CreateVideoProcessorEnumerator(pDesc,ppEnum); - } - - STDMETHODIMP_(UINT) GetVideoDecoderProfileCount(void) - { - return m_pReal->GetVideoDecoderProfileCount(); - } - - STDMETHODIMP GetVideoDecoderProfile( - _In_ UINT Index, - _Out_ GUID* pDecoderProfile) - { - return m_pReal->GetVideoDecoderProfile(Index,pDecoderProfile); - } - - STDMETHODIMP CheckVideoDecoderFormat( - _In_ const GUID* pDecoderProfile, - _In_ DXGI_FORMAT Format, - _Out_ BOOL* pSupported) - { - return m_pReal->CheckVideoDecoderFormat(pDecoderProfile,Format,pSupported); - } - - STDMETHODIMP GetVideoDecoderConfigCount( - _In_ const D3D11_VIDEO_DECODER_DESC* pDesc, - _Out_ UINT* pCount) - { - return m_pReal->GetVideoDecoderConfigCount(pDesc,pCount); - } - - STDMETHODIMP GetVideoDecoderConfig( - _In_ const D3D11_VIDEO_DECODER_DESC* pDesc, - _In_ UINT Index, - _Out_ D3D11_VIDEO_DECODER_CONFIG* pConfig) - { - return m_pReal->GetVideoDecoderConfig(pDesc,Index,pConfig); - } - - STDMETHODIMP GetContentProtectionCaps( - _In_opt_ const GUID* pCryptoType, - _In_opt_ const GUID* pDecoderProfile, - _Out_ D3D11_VIDEO_CONTENT_PROTECTION_CAPS* pCaps) - { - return m_pReal->GetContentProtectionCaps(pCryptoType,pDecoderProfile,pCaps); - } - - STDMETHODIMP CheckCryptoKeyExchange( - _In_ const GUID* pCryptoType, - _In_opt_ const GUID* pDecoderProfile, - _In_ UINT Index, - _Out_ GUID* pKeyExchangeType) - { - return m_pReal->CheckCryptoKeyExchange(pCryptoType,pDecoderProfile,Index,pKeyExchangeType); - } - - STDMETHODIMP SetPrivateData( - _In_ REFGUID guid, - _In_ UINT DataSize, - _In_reads_bytes_opt_(DataSize) const void* pData) - { - return m_pReal->SetPrivateData(guid,DataSize,pData); - } - - STDMETHODIMP SetPrivateDataInterface( - _In_ REFGUID guid, - _In_opt_ const IUnknown* pData) - { - return m_pReal->SetPrivateDataInterface(guid,pData); - } - }; - - class CPrivate_ID3D11Device : public ID3D11Device - { - private: - - ID3D11Device* m_pReal; - ULONG m_cRef; - CPrivate_ID3D11VideoDevice* m_pVideoDevice; - - public: - - CPrivate_ID3D11Device(ID3D11Device* pReal) : - m_pReal(pReal), - m_cRef(1), - m_pVideoDevice(NULL) - { - ID3D11VideoDevice* pDevice; - m_pReal->QueryInterface(__uuidof(ID3D11VideoDevice),(void**)&pDevice); - m_pVideoDevice = new CPrivate_ID3D11VideoDevice(pDevice); - if (pDevice != NULL) - { - pDevice->Release(); - } - } - - virtual ~CPrivate_ID3D11Device(void) - { - SafeDelete(m_pVideoDevice); - } - - STDMETHODIMP QueryInterface( - /* [in] */ REFIID riid, - /* [iid_is][out] */ __RPC__deref_out void __RPC_FAR* __RPC_FAR* ppvObject) - { - if (__uuidof(ID3D11VideoDevice) == riid) - { - m_pVideoDevice->AddRef(); - *ppvObject = m_pVideoDevice; - return S_OK; - } - else if (__uuidof(ID3D11Device) == riid) - { - this->AddRef(); - *ppvObject = this; - return S_OK; - } - else - { - return m_pReal->QueryInterface(riid,ppvObject); - } - } - - STDMETHODIMP_(ULONG) AddRef(void) - { - InterlockedIncrement(&m_cRef); - return m_pReal->AddRef(); - } - - STDMETHODIMP_(ULONG) Release(void) - { - ULONG ulVal = m_pReal->Release(); - if (0 == InterlockedDecrement(&m_cRef)) - { - delete this; - } - return ulVal; - } - - STDMETHODIMP CreateBuffer( - _In_ const D3D11_BUFFER_DESC* pDesc, - _In_opt_ const D3D11_SUBRESOURCE_DATA* pInitialData, - _Out_opt_ ID3D11Buffer** ppBuffer) - { - return m_pReal->CreateBuffer(pDesc,pInitialData,ppBuffer); - } - - STDMETHODIMP CreateTexture1D( - _In_ const D3D11_TEXTURE1D_DESC* pDesc, - _In_reads_opt_(pDesc->MipLevels * pDesc->ArraySize) const D3D11_SUBRESOURCE_DATA* pInitialData, - _Out_opt_ ID3D11Texture1D** ppTexture1D) - { - return m_pReal->CreateTexture1D(pDesc,pInitialData,ppTexture1D); - } - - STDMETHODIMP CreateTexture2D( - _In_ const D3D11_TEXTURE2D_DESC* pDesc, - _In_reads_opt_(pDesc->MipLevels * pDesc->ArraySize) const D3D11_SUBRESOURCE_DATA* pInitialData, - _Out_opt_ ID3D11Texture2D** ppTexture2D) - { - return m_pReal->CreateTexture2D(pDesc,pInitialData,ppTexture2D); - } - - STDMETHODIMP CreateTexture3D( - _In_ const D3D11_TEXTURE3D_DESC* pDesc, - _In_reads_opt_(pDesc->MipLevels) const D3D11_SUBRESOURCE_DATA* pInitialData, - _Out_opt_ ID3D11Texture3D** ppTexture3D) - { - return m_pReal->CreateTexture3D(pDesc,pInitialData,ppTexture3D); - } - - STDMETHODIMP CreateShaderResourceView( - _In_ ID3D11Resource* pResource, - _In_opt_ const D3D11_SHADER_RESOURCE_VIEW_DESC* pDesc, - _Out_opt_ ID3D11ShaderResourceView** ppSRView) - { - return m_pReal->CreateShaderResourceView(pResource,pDesc,ppSRView); - } - - STDMETHODIMP CreateUnorderedAccessView( - _In_ ID3D11Resource* pResource, - _In_opt_ const D3D11_UNORDERED_ACCESS_VIEW_DESC* pDesc, - _Out_opt_ ID3D11UnorderedAccessView** ppUAView) - { - return m_pReal->CreateUnorderedAccessView(pResource,pDesc,ppUAView); - } - - STDMETHODIMP CreateRenderTargetView( - _In_ ID3D11Resource* pResource, - _In_opt_ const D3D11_RENDER_TARGET_VIEW_DESC* pDesc, - _Out_opt_ ID3D11RenderTargetView** ppRTView) - { - return m_pReal->CreateRenderTargetView(pResource,pDesc,ppRTView); - } - - STDMETHODIMP CreateDepthStencilView( - _In_ ID3D11Resource* pResource, - _In_opt_ const D3D11_DEPTH_STENCIL_VIEW_DESC* pDesc, - _Out_opt_ ID3D11DepthStencilView** ppDepthStencilView) - { - return m_pReal->CreateDepthStencilView(pResource,pDesc,ppDepthStencilView); - } - - STDMETHODIMP CreateInputLayout( - _In_reads_(NumElements) const D3D11_INPUT_ELEMENT_DESC* pInputElementDescs, - _In_range_( 0, D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT ) UINT NumElements, - _In_ const void* pShaderBytecodeWithInputSignature, - _In_ SIZE_T BytecodeLength, - _Out_opt_ ID3D11InputLayout** ppInputLayout) - { - return m_pReal->CreateInputLayout(pInputElementDescs,NumElements,pShaderBytecodeWithInputSignature,BytecodeLength,ppInputLayout); - } - - STDMETHODIMP CreateVertexShader( - _In_ const void* pShaderBytecode, - _In_ SIZE_T BytecodeLength, - _In_opt_ ID3D11ClassLinkage* pClassLinkage, - _Out_opt_ ID3D11VertexShader** ppVertexShader) - { - return m_pReal->CreateVertexShader(pShaderBytecode,BytecodeLength,pClassLinkage,ppVertexShader); - } - - STDMETHODIMP CreateGeometryShader( - _In_ const void* pShaderBytecode, - _In_ SIZE_T BytecodeLength, - _In_opt_ ID3D11ClassLinkage* pClassLinkage, - _Out_opt_ ID3D11GeometryShader** ppGeometryShader) - { - return m_pReal->CreateGeometryShader(pShaderBytecode,BytecodeLength,pClassLinkage,ppGeometryShader); - } - - STDMETHODIMP CreateGeometryShaderWithStreamOutput( - _In_ const void* pShaderBytecode, - _In_ SIZE_T BytecodeLength, - _In_reads_opt_(NumEntries) const D3D11_SO_DECLARATION_ENTRY* pSODeclaration, - _In_range_( 0, D3D11_SO_STREAM_COUNT * D3D11_SO_OUTPUT_COMPONENT_COUNT ) UINT NumEntries, - _In_reads_opt_(NumStrides) const UINT* pBufferStrides, - _In_range_( 0, D3D11_SO_BUFFER_SLOT_COUNT ) UINT NumStrides, - _In_ UINT RasterizedStream, - _In_opt_ ID3D11ClassLinkage* pClassLinkage, - _Out_opt_ ID3D11GeometryShader** ppGeometryShader) - { - return m_pReal->CreateGeometryShaderWithStreamOutput(pShaderBytecode,BytecodeLength,pSODeclaration,NumEntries,pBufferStrides,NumStrides,RasterizedStream,pClassLinkage,ppGeometryShader); - } - - STDMETHODIMP CreatePixelShader( - _In_ const void* pShaderBytecode, - _In_ SIZE_T BytecodeLength, - _In_opt_ ID3D11ClassLinkage* pClassLinkage, - _Out_opt_ ID3D11PixelShader** ppPixelShader) - { - return m_pReal->CreatePixelShader(pShaderBytecode,BytecodeLength,pClassLinkage,ppPixelShader); - } - - STDMETHODIMP CreateHullShader( - _In_ const void* pShaderBytecode, - _In_ SIZE_T BytecodeLength, - _In_opt_ ID3D11ClassLinkage* pClassLinkage, - _Out_opt_ ID3D11HullShader** ppHullShader) - { - return m_pReal->CreateHullShader(pShaderBytecode,BytecodeLength,pClassLinkage,ppHullShader); - } - - STDMETHODIMP CreateDomainShader( - _In_ const void* pShaderBytecode, - _In_ SIZE_T BytecodeLength, - _In_opt_ ID3D11ClassLinkage* pClassLinkage, - _Out_opt_ ID3D11DomainShader** ppDomainShader) - { - return m_pReal->CreateDomainShader(pShaderBytecode,BytecodeLength,pClassLinkage,ppDomainShader); - } - - STDMETHODIMP CreateComputeShader( - _In_ const void* pShaderBytecode, - _In_ SIZE_T BytecodeLength, - _In_opt_ ID3D11ClassLinkage* pClassLinkage, - _Out_opt_ ID3D11ComputeShader** ppComputeShader) - { - return m_pReal->CreateComputeShader(pShaderBytecode,BytecodeLength,pClassLinkage,ppComputeShader); - } - - STDMETHODIMP CreateClassLinkage( - _Out_ ID3D11ClassLinkage** ppLinkage) - { - return m_pReal->CreateClassLinkage(ppLinkage); - } - - STDMETHODIMP CreateBlendState( - _In_ const D3D11_BLEND_DESC* pBlendStateDesc, - _Out_opt_ ID3D11BlendState** ppBlendState) - { - return m_pReal->CreateBlendState(pBlendStateDesc,ppBlendState); - } - - STDMETHODIMP CreateDepthStencilState( - _In_ const D3D11_DEPTH_STENCIL_DESC* pDepthStencilDesc, - _Out_opt_ ID3D11DepthStencilState** ppDepthStencilState) - { - return m_pReal->CreateDepthStencilState(pDepthStencilDesc,ppDepthStencilState); - } - - STDMETHODIMP CreateRasterizerState( - _In_ const D3D11_RASTERIZER_DESC* pRasterizerDesc, - _Out_opt_ ID3D11RasterizerState** ppRasterizerState) - { - return m_pReal->CreateRasterizerState(pRasterizerDesc,ppRasterizerState); - } - - STDMETHODIMP CreateSamplerState( - _In_ const D3D11_SAMPLER_DESC* pSamplerDesc, - _Out_opt_ ID3D11SamplerState** ppSamplerState) - { - return m_pReal->CreateSamplerState(pSamplerDesc,ppSamplerState); - } - - STDMETHODIMP CreateQuery( - _In_ const D3D11_QUERY_DESC* pQueryDesc, - _Out_opt_ ID3D11Query** ppQuery) - { - return m_pReal->CreateQuery(pQueryDesc,ppQuery); - } - - STDMETHODIMP CreatePredicate( - _In_ const D3D11_QUERY_DESC* pPredicateDesc, - _Out_opt_ ID3D11Predicate** ppPredicate) - { - return m_pReal->CreatePredicate(pPredicateDesc,ppPredicate); - } - - STDMETHODIMP CreateCounter( - _In_ const D3D11_COUNTER_DESC* pCounterDesc, - _Out_opt_ ID3D11Counter** ppCounter) - { - return m_pReal->CreateCounter(pCounterDesc,ppCounter); - } - - STDMETHODIMP CreateDeferredContext( - UINT ContextFlags, - _Out_opt_ ID3D11DeviceContext** ppDeferredContext) - { - return m_pReal->CreateDeferredContext(ContextFlags,ppDeferredContext); - } - - STDMETHODIMP OpenSharedResource( - _In_ HANDLE hResource, - _In_ REFIID ReturnedInterface, - _Out_opt_ void** ppResource) - { - return m_pReal->OpenSharedResource(hResource,ReturnedInterface,ppResource); - } - - STDMETHODIMP CheckFormatSupport( - _In_ DXGI_FORMAT Format, - _Out_ UINT* pFormatSupport) - { - return m_pReal->CheckFormatSupport(Format,pFormatSupport); - } - - STDMETHODIMP CheckMultisampleQualityLevels( - _In_ DXGI_FORMAT Format, - _In_ UINT SampleCount, - _Out_ UINT* pNumQualityLevels) - { - return m_pReal->CheckMultisampleQualityLevels(Format,SampleCount,pNumQualityLevels); - } - - STDMETHODIMP_(void) CheckCounterInfo( - _Out_ D3D11_COUNTER_INFO* pCounterInfo) - { - return m_pReal->CheckCounterInfo(pCounterInfo); - } - - STDMETHODIMP CheckCounter( - _In_ const D3D11_COUNTER_DESC* pDesc, - _Out_ D3D11_COUNTER_TYPE* pType, - _Out_ UINT* pActiveCounters, - _Out_writes_opt_(*pNameLength) LPSTR szName, - _Inout_opt_ UINT* pNameLength, - _Out_writes_opt_(*pUnitsLength) LPSTR szUnits, - _Inout_opt_ UINT* pUnitsLength, - _Out_writes_opt_(*pDescriptionLength) LPSTR szDescription, - _Inout_opt_ UINT* pDescriptionLength) - { - return m_pReal->CheckCounter(pDesc,pType,pActiveCounters,szName,pNameLength,szUnits,pUnitsLength,szDescription,pDescriptionLength); - } - - STDMETHODIMP CheckFeatureSupport( - D3D11_FEATURE Feature, - _Out_writes_bytes_(FeatureSupportDataSize) void* pFeatureSupportData, - UINT FeatureSupportDataSize) - { - return m_pReal->CheckFeatureSupport(Feature,pFeatureSupportData,FeatureSupportDataSize); - } - - STDMETHODIMP GetPrivateData( - _In_ REFGUID guid, - _Inout_ UINT* pDataSize, - _Out_writes_bytes_opt_(*pDataSize) void* pData) - { - return m_pReal->GetPrivateData(guid,pDataSize,pData); - } - - STDMETHODIMP SetPrivateData( - _In_ REFGUID guid, - _In_ UINT DataSize, - _In_reads_bytes_opt_(DataSize) const void* pData) - { - return m_pReal->SetPrivateData(guid,DataSize,pData); - } - - STDMETHODIMP SetPrivateDataInterface( - _In_ REFGUID guid, - _In_opt_ const IUnknown* pData) - { - return m_pReal->SetPrivateDataInterface(guid,pData); - } - - STDMETHODIMP_(D3D_FEATURE_LEVEL) GetFeatureLevel(void) - { - return m_pReal->GetFeatureLevel(); - } - - STDMETHODIMP_(UINT) GetCreationFlags(void) - { - return m_pReal->GetCreationFlags(); - } - - STDMETHODIMP GetDeviceRemovedReason(void) - { - return m_pReal->GetDeviceRemovedReason(); - } - - STDMETHODIMP_(void) GetImmediateContext( - _Out_ ID3D11DeviceContext** ppImmediateContext) - { - return m_pReal->GetImmediateContext(ppImmediateContext); - } - - STDMETHODIMP SetExceptionMode( - UINT RaiseFlags) - { - return m_pReal->SetExceptionMode(RaiseFlags); - } - - STDMETHODIMP_(UINT) GetExceptionMode(void) - { - return m_pReal->GetExceptionMode(); - } - }; -} diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Scheduler.cpp b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Scheduler.cpp deleted file mode 100644 index 7ba67cf2..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Scheduler.cpp +++ /dev/null @@ -1,416 +0,0 @@ -#include "Scheduler.h" - -//----------------------------------------------------------------------------- -// Constructor -//----------------------------------------------------------------------------- - -DX11VideoRenderer::CScheduler::CScheduler(CCritSec& critSec) : - m_nRefCount(1), - m_critSec(critSec), - m_pCB(NULL), - m_ScheduledSamples(), // default ctor - m_pClock(NULL), - m_fRate(1.0f), - m_hWaitTimer(NULL), - m_LastSampleTime(0), - m_PerFrameInterval(0), - m_PerFrame_1_4th(0), - m_keyTimer(0) -{ -} - - -//----------------------------------------------------------------------------- -// Destructor -//----------------------------------------------------------------------------- - -DX11VideoRenderer::CScheduler::~CScheduler(void) -{ - if (m_hWaitTimer != NULL) - { - CloseHandle(m_hWaitTimer); - m_hWaitTimer = NULL; - } - - // Discard samples. - m_ScheduledSamples.Clear(); - - SafeRelease(m_pClock); -} - -// IUnknown methods - -ULONG DX11VideoRenderer::CScheduler::AddRef() -{ - return InterlockedIncrement(&m_nRefCount); -} - -ULONG DX11VideoRenderer::CScheduler::Release() -{ - ULONG uCount = InterlockedDecrement(&m_nRefCount); - if (uCount == 0) - { - delete this; - } - // For thread safety, return a temporary variable. - return uCount; -} - -HRESULT DX11VideoRenderer::CScheduler::QueryInterface(REFIID iid, __RPC__deref_out _Result_nullonfailure_ void** ppv) -{ - if (!ppv) - { - return E_POINTER; - } - if (iid == IID_IUnknown) - { - *ppv = static_cast(this); - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -//----------------------------------------------------------------------------- -// SetFrameRate -// Specifies the frame rate of the video, in frames per second. -//----------------------------------------------------------------------------- - -void DX11VideoRenderer::CScheduler::SetFrameRate(const MFRatio& fps) -{ - UINT64 AvgTimePerFrame = 0; - - // Convert to a duration. - MFFrameRateToAverageTimePerFrame(fps.Numerator, fps.Denominator, &AvgTimePerFrame); - - m_PerFrameInterval = (MFTIME)AvgTimePerFrame; - - // Calculate 1/4th of this value, because we use it frequently. - m_PerFrame_1_4th = m_PerFrameInterval / 4; -} - - - -//----------------------------------------------------------------------------- -// StartScheduler -// Starts the scheduler's worker thread. -// -// IMFClock: Pointer to the DX11VideoRenderer's presentation clock. Can be NULL. -//----------------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CScheduler::StartScheduler(IMFClock* pClock) -{ - HRESULT hr = S_OK; - - SafeRelease(m_pClock); - m_pClock = pClock; - if (m_pClock != NULL) - { - m_pClock->AddRef(); - } - - // Set a high the timer resolution (ie, short timer period). - timeBeginPeriod(1); - - // create the waitable timer - m_hWaitTimer = CreateWaitableTimer(NULL, FALSE, NULL); - if (m_hWaitTimer == NULL) - { - hr = HRESULT_FROM_WIN32(GetLastError()); - } - - return hr; -} - - -//----------------------------------------------------------------------------- -// StopScheduler -// -// Stops the scheduler's worker thread. -//----------------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CScheduler::StopScheduler(void) -{ - if (m_hWaitTimer != NULL) - { - CloseHandle(m_hWaitTimer); - m_hWaitTimer = NULL; - } - - // Discard samples. - m_ScheduledSamples.Clear(); - - // Restore the timer resolution. - timeEndPeriod(1); - - SafeRelease(m_pClock); - - return S_OK; -} - - -//----------------------------------------------------------------------------- -// Flush -// -// Flushes all samples that are queued for presentation. -// -// Note: This method is synchronous; ie., it waits for the flush operation to -// complete on the worker thread. -//----------------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CScheduler::Flush(void) -{ - CAutoLock lock(&m_critSec); - - // Flushing: Clear the sample queue and set the event. - m_ScheduledSamples.Clear(); - - // Cancel timer callback - if (m_keyTimer != 0) - { - (void)MFCancelWorkItem(m_keyTimer); - m_keyTimer = 0; - } - - return S_OK; -} - - -//----------------------------------------------------------------------------- -// ScheduleSample -// -// Schedules a new sample for presentation. -// -// pSample: Pointer to the sample. -// bPresentNow: If TRUE, the sample is presented immediately. Otherwise, the -// sample's time stamp is used to schedule the sample. -//----------------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CScheduler::ScheduleSample(IMFSample* pSample, BOOL bPresentNow) -{ - if (m_pCB == NULL) - { - return MF_E_NOT_INITIALIZED; - } - - HRESULT hr = S_OK; - - if (bPresentNow || (m_pClock == NULL)) - { - // Present the sample immediately. - hr = m_pCB->PresentFrame(); - } - else - { - // Queue the sample and ask the scheduler thread to wake up. - hr = m_ScheduledSamples.Queue(pSample); - - if (SUCCEEDED(hr)) - { - // process the frame asynchronously - hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_MULTITHREADED, &m_xOnTimer, nullptr); - } - } - - return hr; -} - -//----------------------------------------------------------------------------- -// ProcessSamplesInQueue -// -// Processes all the samples in the queue. -// -// plNextSleep: Receives the length of time the scheduler thread should sleep -// before it calls ProcessSamplesInQueue again. -//----------------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CScheduler::ProcessSamplesInQueue(LONG* plNextSleep) -{ - HRESULT hr = S_OK; - LONG lWait = 0; - IMFSample* pSample = NULL; - - // Process samples until the queue is empty or until the wait time > 0. - - // Note: Dequeue returns S_FALSE when the queue is empty. - - while (m_ScheduledSamples.Dequeue(&pSample) == S_OK) - { - // Process the next sample in the queue. If the sample is not ready - // for presentation. the value returned in lWait is > 0, which - // means the scheduler should sleep for that amount of time. - - hr = ProcessSample(pSample, &lWait); - SafeRelease(pSample); - - if (FAILED(hr) || lWait > 0) - { - break; - } - } - - // If the wait time is zero, it means we stopped because the queue is - // empty (or an error occurred). Set the wait time to infinite; this will - // make the scheduler thread sleep until it gets another thread message. - if (lWait == 0) - { - lWait = INFINITE; - } - - *plNextSleep = lWait; - return hr; -} - - -//----------------------------------------------------------------------------- -// ProcessSample -// -// Processes a sample. -// -// plNextSleep: Receives the length of time the scheduler thread should sleep. -//----------------------------------------------------------------------------- - - -HRESULT DX11VideoRenderer::CScheduler::ProcessSample(IMFSample* pSample, LONG* plNextSleep) -{ - HRESULT hr = S_OK; - - LONGLONG hnsPresentationTime = 0; - LONGLONG hnsTimeNow = 0; - MFTIME hnsSystemTime = 0; - LONGLONG hnsDelta = 0; - - BOOL bPresentNow = TRUE; - LONG lNextSleep = 0; - - if (m_pClock) - { - // Get the sample's time stamp. It is valid for a sample to - // have no time stamp. - hr = pSample->GetSampleTime(&hnsPresentationTime); - - // Get the clock time. (But if the sample does not have a time stamp, - // we don't need the clock time.) - if (SUCCEEDED(hr)) - { - hr = m_pClock->GetCorrelatedTime(0, &hnsTimeNow, &hnsSystemTime); - } - - if (SUCCEEDED(hr)) - { - // Calculate the time until the sample's presentation time. - // A negative value means the sample is late. - hnsDelta = hnsPresentationTime - hnsTimeNow; - if (m_fRate < 0) - { - // For reverse playback, the clock runs backward. Therefore, the - // delta is reversed. - hnsDelta = - hnsDelta; - } - - if (hnsDelta < - m_PerFrame_1_4th) - { - // This sample is late. - bPresentNow = TRUE; - } - else if (hnsDelta > (3 * m_PerFrame_1_4th)) - { - // This sample is still too early. Go to sleep. - lNextSleep = static_cast(TicksToMilliseconds(hnsDelta - (3 * m_PerFrame_1_4th))); - - // Adjust the sleep time for the clock rate. (The presentation clock runs - // at m_fRate, but sleeping uses the system clock.) - lNextSleep = static_cast(lNextSleep / fabsf(m_fRate)); - - // Don't present yet. - bPresentNow = FALSE; - } - } - } - - if (bPresentNow) - { - hr = m_pCB->PresentFrame(); - } - else - { - // The sample is not ready yet. Return it to the queue. - hr = m_ScheduledSamples.PutBack(pSample); - } - - *plNextSleep = lNextSleep; - - return hr; -} - -//----------------------------------------------------------------------------- -// StartProcessSample -// -// Synopsis: Main entrypoint for the frame processing -//----------------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CScheduler::StartProcessSample() -{ - HRESULT hr = S_OK; - - LONG lWait = INFINITE; - BOOL bExitThread = FALSE; - IMFAsyncResult *pAsyncResult = NULL; - - hr = ProcessSamplesInQueue(&lWait); - - if(SUCCEEDED(hr)) - { - if(INFINITE != lWait && 0 < lWait) - { - // not time to process the frame yet, wait until the right time - LARGE_INTEGER llDueTime; - llDueTime.QuadPart = -1 * MillisecondsToTicks(lWait); - if (SetWaitableTimer(m_hWaitTimer, &llDueTime, 0, NULL, NULL, FALSE) == 0) - { - hr = HRESULT_FROM_WIN32(GetLastError()); - } - - if(SUCCEEDED(hr)) - { - // queue a waititem to wait for timer completion - hr = MFCreateAsyncResult(nullptr, &m_xOnTimer, nullptr, &pAsyncResult); - if(SUCCEEDED(hr)) - { - hr = MFPutWaitingWorkItem(m_hWaitTimer, 0, pAsyncResult, &m_keyTimer); - } - } - } - } - - SafeRelease(pAsyncResult); - - return hr; -} - -//+------------------------------------------------------------------------- -// -// Function: OnTimer -// -// Synopsis: Callback fired when the timer expires. Used as entrypoint to -// check whether a frame should now be presented -// -//-------------------------------------------------------------------------- -HRESULT DX11VideoRenderer::CScheduler::OnTimer(__RPC__in_opt IMFAsyncResult *pResult) -{ - HRESULT hr = S_OK; - - CAutoLock lock(&m_critSec); - - m_keyTimer = 0; - - // if we have a pending frame, process it - // it's possible that we don't have a frame at this point if the pending frame was cancelled - hr = StartProcessSample(); - - return hr; -} \ No newline at end of file diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Scheduler.h b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Scheduler.h deleted file mode 100644 index 9cf53419..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/Scheduler.h +++ /dev/null @@ -1,89 +0,0 @@ -#pragma once - -#include "Common.h" - -namespace DX11VideoRenderer -{ - //----------------------------------------------------------------------------- - // SchedulerCallback - // - // Defines the callback method to present samples. - //----------------------------------------------------------------------------- - - struct SchedulerCallback - { - virtual HRESULT PresentFrame(void) = 0; - }; - - //----------------------------------------------------------------------------- - // Scheduler class - // - // Schedules when a sample should be displayed. - // - // Note: Presentation of each sample is performed by another object which - // must implement SchedulerCallback::PresentSample. - // - // General design: - // The scheduler generally receives samples before their presentation time. It - // puts the samples on a queue and presents them in FIFO order on a worker - // thread. The scheduler communicates with the worker thread by posting thread - // messages. - // - // The caller has the option of presenting samples immediately (for example, - // for repaints). - //----------------------------------------------------------------------------- - - class CScheduler: - public IUnknown, - private CBase - { - public: - - CScheduler(CCritSec& critSec); - virtual ~CScheduler(void); - - // IUnknown - STDMETHODIMP_(ULONG) AddRef(); - STDMETHODIMP_(ULONG) Release(); - STDMETHODIMP QueryInterface(REFIID iid, __RPC__deref_out _Result_nullonfailure_ void** ppv); - - void SetCallback(SchedulerCallback* pCB) - { - m_pCB = pCB; - } - - void SetFrameRate(const MFRatio& fps); - void SetClockRate(float fRate) { m_fRate = fRate; } - - const LONGLONG& LastSampleTime(void) const { return m_LastSampleTime; } - const LONGLONG& FrameDuration(void) const { return m_PerFrameInterval; } - - HRESULT StartScheduler(IMFClock* pClock); - HRESULT StopScheduler(void); - - HRESULT ScheduleSample(IMFSample* pSample, BOOL bPresentNow); - HRESULT ProcessSamplesInQueue(LONG* plNextSleep); - HRESULT ProcessSample(IMFSample* pSample, LONG* plNextSleep); - HRESULT Flush(void); - - DWORD GetCount(void){ return m_ScheduledSamples.GetCount(); } - - private: - - HRESULT StartProcessSample(); - HRESULT OnTimer(__RPC__in_opt IMFAsyncResult* pResult); - METHODASYNCCALLBACKEX(OnTimer, CScheduler, 0, MFASYNC_CALLBACK_QUEUE_MULTITHREADED); - - long m_nRefCount; - CCritSec& m_critSec; // critical section for thread safety - SchedulerCallback* m_pCB; // Weak reference; do not delete. - ThreadSafeQueue m_ScheduledSamples; // Samples waiting to be presented. - IMFClock* m_pClock; // Presentation clock. Can be NULL. - float m_fRate; // Playback rate. - HANDLE m_hWaitTimer; // Wait Timer after which frame is presented. - MFTIME m_LastSampleTime; // Most recent sample time. - MFTIME m_PerFrameInterval; // Duration of each frame. - LONGLONG m_PerFrame_1_4th; // 1/4th of the frame duration. - MFWORKITEM_KEY m_keyTimer; - }; -} diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/StaticAsyncCallback.h b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/StaticAsyncCallback.h deleted file mode 100644 index c979f907..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/StaticAsyncCallback.h +++ /dev/null @@ -1,116 +0,0 @@ -#ifndef __STATICASYNCCALLBACK__ -#define __STATICASYNCCALLBACK__ - -//////////////////////////////////////////////////////// -// -#define STATICASYNCCALLBACK(Callback, Parent) \ -class Callback##AsyncCallback; \ -friend class Callback##AsyncCallback; \ -class Callback##AsyncCallback : public IMFAsyncCallback \ -{ \ -public: \ - STDMETHOD_( ULONG, AddRef )() \ - { \ - Parent * pThis = ((Parent*)((BYTE*)this - offsetof(Parent, m_x##Callback))); \ - return pThis->AddRef(); \ - } \ - STDMETHOD_( ULONG, Release )() \ - { \ - Parent * pThis = ((Parent*)((BYTE*)this - offsetof(Parent, m_x##Callback))); \ - return pThis->Release(); \ - } \ - STDMETHOD( QueryInterface )( REFIID riid, __RPC__deref_out _Result_nullonfailure_ void **ppvObject ) \ - { \ - return E_NOINTERFACE; \ - } \ - STDMETHOD( GetParameters )( \ - __RPC__out DWORD *pdwFlags, \ - __RPC__out DWORD *pdwQueue) \ - { \ - return S_OK; \ - } \ - STDMETHOD( Invoke )( __RPC__in_opt IMFAsyncResult * pResult ) \ - { \ - Callback( pResult ); \ - return S_OK; \ - } \ -} m_x##Callback; - - -//////////////////////////////////////////////////////// -// -// -// We need to support QI interface so that DCOM is happy when it tries to marshal the interface pointer -// - -#define METHODASYNCCALLBACKEX(Callback, Parent, Flag, Queue) \ -class Callback##AsyncCallback; \ -friend class Callback##AsyncCallback; \ -class Callback##AsyncCallback : public IMFAsyncCallback \ -{ \ -public: \ - STDMETHOD_( ULONG, AddRef )() \ - { \ - return GetParent()->AddRef(); \ - } \ - STDMETHOD_( ULONG, Release )() \ - { \ - return GetParent()->Release(); \ - } \ - STDMETHOD( QueryInterface )( REFIID riid, __RPC__deref_out _Result_nullonfailure_ void **ppvObject ) \ - { \ - if(riid == IID_IMFAsyncCallback || riid == IID_IUnknown) \ - { \ - (*ppvObject) = this; \ - AddRef(); \ - return S_OK; \ - } \ - (*ppvObject) = NULL; \ - return E_NOINTERFACE; \ - } \ - STDMETHOD( GetParameters )( \ - __RPC__out DWORD *pdwFlags, \ - __RPC__out DWORD *pdwQueue) \ - { \ - *pdwFlags = Flag; \ - *pdwQueue = Queue; \ - return S_OK; \ - } \ - STDMETHOD( Invoke )( __RPC__in_opt IMFAsyncResult * pResult ) \ - { \ - GetParent()->Callback( pResult ); \ - return S_OK; \ - } \ -protected: \ - Parent* GetParent() \ - { \ - return ((Parent*)((BYTE*)this - offsetof(Parent, m_x##Callback))); \ - } \ -} m_x##Callback; - -//////////////////////////////////////////////////////// -// -#define METHODFASTCALLBACK(Callback, Parent) \ - METHODASYNCCALLBACKEX(Callback, Parent, MFASYNC_FAST_IO_PROCESSING_CALLBACK, MFASYNC_CALLBACK_QUEUE_STANDARD) - -#define METHODASYNCCALLBACK(Callback, Parent) \ - METHODASYNCCALLBACKEX(Callback, Parent, 0, MFASYNC_CALLBACK_QUEUE_STANDARD) - -#define METHODASYNCRTCALLBACK(Callback, Parent) \ - METHODASYNCCALLBACKEX(Callback, Parent, 0, MFASYNC_CALLBACK_QUEUE_RT) - -#define METHODASYNCIOCALLBACK(Callback, Parent) \ - METHODASYNCCALLBACKEX(Callback, Parent, MFASYNC_FAST_IO_PROCESSING_CALLBACK, MFASYNC_CALLBACK_QUEUE_IO) - -//////////////////////////////////////////////////////// -// -#define METHODASYNCCALLBACKEX2(Callback, Parent, GetQueue ) \ - METHODASYNCCALLBACKEX(Callback, Parent, \ - 0, \ - GetParent()->GetQueue() ) - -#define METHODASYNCCALLBACKEX3(Callback, Parent, GetFlags, GetQueue ) \ - METHODASYNCCALLBACKEX(Callback, Parent, \ - GetParent()->GetFlags(), GetParent()->GetQueue() ) - -#endif diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/StreamSink.cpp b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/StreamSink.cpp deleted file mode 100644 index 66272336..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/StreamSink.cpp +++ /dev/null @@ -1,1648 +0,0 @@ -#include "StreamSink.h" - -GUID const* const DX11VideoRenderer::CStreamSink::s_pVideoFormats[] = -{ - &MFVideoFormat_NV12, - &MFVideoFormat_IYUV, - &MFVideoFormat_YUY2, - &MFVideoFormat_YV12, - &MFVideoFormat_RGB32, - &MFVideoFormat_RGB32, - &MFVideoFormat_RGB24, - &MFVideoFormat_RGB555, - &MFVideoFormat_RGB565, - &MFVideoFormat_RGB8, - &MFVideoFormat_AYUV, - &MFVideoFormat_UYVY, - &MFVideoFormat_YVYU, - &MFVideoFormat_YVU9, - &MEDIASUBTYPE_V216, - &MFVideoFormat_v410, - &MFVideoFormat_I420, - &MFVideoFormat_NV11, - &MFVideoFormat_420O -}; - -const DWORD DX11VideoRenderer::CStreamSink::s_dwNumVideoFormats = sizeof(DX11VideoRenderer::CStreamSink::s_pVideoFormats) / sizeof(DX11VideoRenderer::CStreamSink::s_pVideoFormats[0]); - -const MFRatio DX11VideoRenderer::CStreamSink::s_DefaultFrameRate = { 30, 1 }; - -const DX11VideoRenderer::CStreamSink::FormatEntry DX11VideoRenderer::CStreamSink::s_DXGIFormatMapping[] = -{ - { MFVideoFormat_RGB32, DXGI_FORMAT_B8G8R8X8_UNORM }, - { MFVideoFormat_ARGB32, DXGI_FORMAT_R8G8B8A8_UNORM }, - { MFVideoFormat_AYUV, DXGI_FORMAT_AYUV }, - { MFVideoFormat_YUY2, DXGI_FORMAT_YUY2 }, - { MFVideoFormat_NV12, DXGI_FORMAT_NV12 }, - { MFVideoFormat_NV11, DXGI_FORMAT_NV11 }, - { MFVideoFormat_AI44, DXGI_FORMAT_AI44 }, - { MFVideoFormat_P010, DXGI_FORMAT_P010 }, - { MFVideoFormat_P016, DXGI_FORMAT_P016 }, - { MFVideoFormat_Y210, DXGI_FORMAT_Y210 }, - { MFVideoFormat_Y216, DXGI_FORMAT_Y216 }, - { MFVideoFormat_Y410, DXGI_FORMAT_Y410 }, - { MFVideoFormat_Y416, DXGI_FORMAT_Y416 }, - { MFVideoFormat_420O, DXGI_FORMAT_420_OPAQUE } -}; - -// Control how we batch work from the decoder. -// On receiving a sample we request another one if the number on the queue is -// less than the hi water threshold. -// When displaying samples (removing them from the sample queue) we request -// another one if the number of falls below the lo water threshold -// -#define SAMPLE_QUEUE_HIWATER_THRESHOLD 3 -// maximum # of past reference frames required for deinterlacing -#define MAX_PAST_FRAMES 3 - -///////////////////////////////////////////////////////////////////////////////////////////// -// -// CStreamSink class. - Implements the stream sink. -// -// Notes: -// - Most of the real work gets done in this class. -// - The sink has one stream. If it had multiple streams, it would need to coordinate them. -// - Most operations are done asynchronously on a work queue. -// - Async methods are handled like this: -// 1. Call ValidateOperation to check if the operation is permitted at this time -// 2. Create an CAsyncOperation object for the operation. -// 3. Call QueueAsyncOperation. This puts the operation on the work queue. -// 4. The workqueue calls OnDispatchWorkItem. -// - Locking: -// To avoid deadlocks, do not hold the CStreamSink lock followed by the CMediaSink lock. -// The other order is OK (CMediaSink, then CStreamSink). -// -///////////////////////////////////////////////////////////////////////////////////////////// - -//------------------------------------------------------------------- -// Name: ValidStateMatrix -// Description: Class-static matrix of operations vs states. -// -// If an entry is TRUE, the operation is valid from that state. -//------------------------------------------------------------------- - -BOOL DX11VideoRenderer::CStreamSink::ValidStateMatrix[DX11VideoRenderer::CStreamSink::State_Count][DX11VideoRenderer::CStreamSink::Op_Count] = -{ - // States: Operations: - // SetType Start Restart Pause Stop Sample Marker - /* NotSet */ TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, - - /* Ready */ TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, - - /* Start */ TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, - - /* Pause */ TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, - - /* Stop */ TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE - - // Note about states: - // 1. OnClockRestart should only be called from paused state. - // 2. While paused, the sink accepts samples but does not process them. - -}; - -//------------------------------------------------------------------- -// CStreamSink constructor -//------------------------------------------------------------------- - -#pragma warning( push ) -#pragma warning( disable : 4355 ) // 'this' used in base member initializer list - -DX11VideoRenderer::CStreamSink::CStreamSink(DWORD dwStreamId, CCritSec& critSec, CScheduler* pScheduler) : - STREAM_ID(dwStreamId), - m_nRefCount(1), - m_critSec(critSec), - m_state(State_TypeNotSet), - m_IsShutdown(FALSE), - m_WorkQueueId(0), - m_WorkQueueCB(this, &CStreamSink::OnDispatchWorkItem), - m_ConsumeData(ProcessFrames), - m_StartTime(0), - m_cbDataWritten(0), - m_cOutstandingSampleRequests(0), - m_pSink(NULL), - m_pEventQueue(NULL), - m_pByteStream(NULL), - m_pPresenter(NULL), - m_pScheduler(pScheduler), - m_pCurrentType(NULL), - m_fPrerolling(FALSE), - m_fWaitingForOnClockStart(FALSE), - m_SamplesToProcess(), // default ctor - m_unInterlaceMode(MFVideoInterlace_Progressive), - m_imageBytesPP(), // default ctor - m_dxgiFormat(DXGI_FORMAT_UNKNOWN) -{ - m_imageBytesPP.Numerator = 1; - m_imageBytesPP.Denominator = 1; -} - -#pragma warning( pop ) - -//------------------------------------------------------------------- -// CStreamSink destructor -//------------------------------------------------------------------- - -DX11VideoRenderer::CStreamSink::~CStreamSink(void) -{ -} - -// IUnknown methods - -ULONG DX11VideoRenderer::CStreamSink::AddRef(void) -{ - return InterlockedIncrement(&m_nRefCount); -} - -HRESULT DX11VideoRenderer::CStreamSink::QueryInterface(REFIID iid, __RPC__deref_out _Result_nullonfailure_ void** ppv) -{ - if (!ppv) - { - return E_POINTER; - } - if (iid == IID_IUnknown) - { - *ppv = static_cast(static_cast(this)); - } - else if (iid == __uuidof(IMFStreamSink )) - { - *ppv = static_cast(this); - } - else if (iid == __uuidof(IMFMediaEventGenerator)) - { - *ppv = static_cast(this); - } - else if (iid == __uuidof(IMFMediaTypeHandler)) - { - *ppv = static_cast(this); - } - else if (iid == __uuidof(IMFGetService)) - { - *ppv = static_cast(this); - } - else if (iid == __uuidof(IMFAttributes)) - { - *ppv = static_cast(this); - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -ULONG DX11VideoRenderer::CStreamSink::Release(void) -{ - ULONG uCount = InterlockedDecrement(&m_nRefCount); - if (uCount == 0) - { - delete this; - } - // For thread safety, return a temporary variable. - return uCount; -} - -/// IMFStreamSink methods - -//------------------------------------------------------------------- -// Name: Flush -// Description: Discards all samples that were not processed yet. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::Flush(void) -{ - CAutoLock lock(&m_critSec); - - HRESULT hr = CheckShutdown(); - - if (SUCCEEDED(hr)) - { - m_ConsumeData = DropFrames; - // Note: Even though we are flushing data, we still need to send - // any marker events that were queued. - hr = ProcessSamplesFromQueue(m_ConsumeData); - } - - if (SUCCEEDED(hr)) - { - // This call blocks until the scheduler threads discards all scheduled samples. - m_pScheduler->Flush(); - - hr = m_pPresenter->Flush(); - } - - m_ConsumeData = ProcessFrames; - - return hr; -} - -//------------------------------------------------------------------- -// Name: GetIdentifier -// Description: Returns the stream identifier. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::GetIdentifier(__RPC__out DWORD* pdwIdentifier) -{ - CAutoLock lock(&m_critSec); - - if (pdwIdentifier == NULL) - { - return E_POINTER; - } - - HRESULT hr = CheckShutdown(); - - if (SUCCEEDED(hr)) - { - *pdwIdentifier = STREAM_ID; - } - - return hr; -} - -//------------------------------------------------------------------- -// Name: GetMediaSink -// Description: Returns the parent media sink. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::GetMediaSink(__RPC__deref_out_opt IMFMediaSink** ppMediaSink) -{ - CAutoLock lock(&m_critSec); - - if (ppMediaSink == NULL) - { - return E_POINTER; - } - - HRESULT hr = CheckShutdown(); - - if (SUCCEEDED(hr)) - { - *ppMediaSink = m_pSink; - (*ppMediaSink)->AddRef(); - } - - return hr; - -} - -//------------------------------------------------------------------- -// Name: GetMediaTypeHandler -// Description: Returns a media type handler for this stream. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::GetMediaTypeHandler(__RPC__deref_out_opt IMFMediaTypeHandler** ppHandler) -{ - CAutoLock lock(&m_critSec); - - if (ppHandler == NULL) - { - return E_POINTER; - } - - HRESULT hr = CheckShutdown(); - - // This stream object acts as its own type handler, so we QI ourselves. - if (SUCCEEDED(hr)) - { - hr = this->QueryInterface(IID_IMFMediaTypeHandler, (void**)ppHandler); - } - - return hr; -} - -//------------------------------------------------------------------- -// Name: PlaceMarker -// Description: Receives a marker. [Asynchronous] -// -// Note: The client can call PlaceMarker at any time. In response, -// we need to queue an MEStreamSinkMarker event, but not until -// *after* we have processed all samples that we have received -// up to this point. -// -// Also, in general you might need to handle specific marker -// types, although this sink does not. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::PlaceMarker(MFSTREAMSINK_MARKER_TYPE eMarkerType, __RPC__in const PROPVARIANT* pvarMarkerValue, __RPC__in const PROPVARIANT* pvarContextValue) -{ - - CAutoLock lock(&m_critSec); - - HRESULT hr = S_OK; - - IMarker* pMarker = NULL; - - hr = CheckShutdown(); - - if (SUCCEEDED(hr)) - { - hr = ValidateOperation(OpPlaceMarker); - } - - // Create a marker object and put it on the sample queue. - if (SUCCEEDED(hr)) - { - hr = CMarker::Create( - eMarkerType, - pvarMarkerValue, - pvarContextValue, - &pMarker); - } - - if (SUCCEEDED(hr)) - { - hr = m_SamplesToProcess.Queue(pMarker); - } - - // Unless we are paused, start an async operation to dispatch the next sample/marker. - if (SUCCEEDED(hr)) - { - if (m_state != State_Paused) - { - // Queue the operation. - hr = QueueAsyncOperation(OpPlaceMarker); // Increments ref count on pOp. - } - } - SafeRelease(pMarker); - - return hr; -} - -//------------------------------------------------------------------- -// Name: ProcessSample -// Description: Receives an input sample. [Asynchronous] -// -// Note: The client should only give us a sample after we send an -// MEStreamSinkRequestSample event. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::ProcessSample(__RPC__in_opt IMFSample* pSample) -{ - CAutoLock lock(&m_critSec); - - if (pSample == NULL) - { - return E_POINTER; - } - - if (0 == m_cOutstandingSampleRequests) - { - return MF_E_INVALIDREQUEST; - } - - HRESULT hr = S_OK; - - do - { - hr = CheckShutdown(); - if (FAILED(hr)) - { - break; - } - - m_cOutstandingSampleRequests--; - - if (!m_fPrerolling && !m_fWaitingForOnClockStart) - { - // Validate the operation. - hr = ValidateOperation(OpProcessSample); - if (FAILED(hr)) - { - break; - } - } - - // Add the sample to the sample queue. - hr = m_SamplesToProcess.Queue(pSample); - if (FAILED(hr)) - { - break; - } - - if (m_fPrerolling) - { - m_fPrerolling = FALSE; - return QueueEvent(MEStreamSinkPrerolled, GUID_NULL, S_OK, NULL); - } - - // Unless we are paused/stopped, start an async operation to dispatch the next sample. - if (m_state != State_Paused && m_state != State_Stopped) - { - // Queue the operation. - hr = QueueAsyncOperation(OpProcessSample); - } - } - while (FALSE); - - return hr; -} - -// IMFMediaEventGenerator methods. -// Note: These methods call through to the event queue helper object. - -HRESULT DX11VideoRenderer::CStreamSink::BeginGetEvent(IMFAsyncCallback* pCallback, IUnknown* punkState) -{ - HRESULT hr = S_OK; - - CAutoLock lock(&m_critSec); - hr = CheckShutdown(); - - if (SUCCEEDED(hr)) - { - hr = m_pEventQueue->BeginGetEvent(pCallback, punkState); - } - - return hr; -} - -HRESULT DX11VideoRenderer::CStreamSink::EndGetEvent(IMFAsyncResult* pResult, _Out_ IMFMediaEvent** ppEvent) -{ - HRESULT hr = S_OK; - - CAutoLock lock(&m_critSec); - hr = CheckShutdown(); - - if (SUCCEEDED(hr)) - { - hr = m_pEventQueue->EndGetEvent(pResult, ppEvent); - } - - return hr; -} - -HRESULT DX11VideoRenderer::CStreamSink::GetEvent(DWORD dwFlags, __RPC__deref_out_opt IMFMediaEvent** ppEvent) -{ - // NOTE: - // GetEvent can block indefinitely, so we don't hold the lock. - // This requires some juggling with the event queue pointer. - - HRESULT hr = S_OK; - - IMFMediaEventQueue* pQueue = NULL; - - { // scope for lock - - CAutoLock lock(&m_critSec); - - // Check shutdown - hr = CheckShutdown(); - - // Get the pointer to the event queue. - if (SUCCEEDED(hr)) - { - pQueue = m_pEventQueue; - pQueue->AddRef(); - } - - } // release lock - - // Now get the event. - if (SUCCEEDED(hr)) - { - hr = pQueue->GetEvent(dwFlags, ppEvent); - } - - SafeRelease(pQueue); - - return hr; -} - -HRESULT DX11VideoRenderer::CStreamSink::QueueEvent(MediaEventType met, __RPC__in REFGUID guidExtendedType, HRESULT hrStatus, __RPC__in_opt const PROPVARIANT* pvValue) -{ - HRESULT hr = S_OK; - - CAutoLock lock(&m_critSec); - hr = CheckShutdown(); - - if (SUCCEEDED(hr)) - { - hr = m_pEventQueue->QueueEventParamVar(met, guidExtendedType, hrStatus, pvValue); - } - - return hr; -} - -/// IMFMediaTypeHandler methods - -//------------------------------------------------------------------- -// Name: GetCurrentMediaType -// Description: Return the current media type, if any. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::GetCurrentMediaType(_Outptr_ IMFMediaType** ppMediaType) -{ - CAutoLock lock(&m_critSec); - - if (ppMediaType == NULL) - { - return E_POINTER; - } - - HRESULT hr = CheckShutdown(); - - if (SUCCEEDED(hr)) - { - if (m_pCurrentType == NULL) - { - hr = MF_E_NOT_INITIALIZED; - } - } - - if (SUCCEEDED(hr)) - { - *ppMediaType = m_pCurrentType; - (*ppMediaType)->AddRef(); - } - - return hr; -} - -//------------------------------------------------------------------- -// Name: GetMajorType -// Description: Return the major type GUID. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::GetMajorType(__RPC__out GUID* pguidMajorType) -{ - if (pguidMajorType == NULL) - { - return E_POINTER; - } - - HRESULT hr = CheckShutdown(); - if (FAILED(hr)) - { - return hr; - } - - if (m_pCurrentType == NULL) - { - return MF_E_NOT_INITIALIZED; - } - - return m_pCurrentType->GetGUID(MF_MT_MAJOR_TYPE, pguidMajorType); -} - -//------------------------------------------------------------------- -// Name: GetMediaTypeByIndex -// Description: Return a preferred media type by index. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::GetMediaTypeByIndex(DWORD dwIndex, _Outptr_ IMFMediaType** ppType) -{ - HRESULT hr = S_OK; - - do - { - if (ppType == NULL) - { - hr = E_POINTER; - break; - } - - hr = CheckShutdown(); - if (FAILED(hr)) - { - break; - } - - if (dwIndex >= s_dwNumVideoFormats) - { - hr = MF_E_NO_MORE_TYPES; - break; - } - - IMFMediaType* pVideoMediaType = NULL; - - do - { - hr = MFCreateMediaType(&pVideoMediaType); - if (FAILED(hr)) - { - break; - } - - hr = pVideoMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); - if (FAILED(hr)) - { - break; - } - - hr = pVideoMediaType->SetGUID(MF_MT_SUBTYPE, *(s_pVideoFormats[dwIndex])); - if (FAILED(hr)) - { - break; - } - - pVideoMediaType->AddRef(); - *ppType = pVideoMediaType; - } - while (FALSE); - - SafeRelease(pVideoMediaType); - - if (FAILED(hr)) - { - break; - } - } - while (FALSE); - - return hr; -} - -//------------------------------------------------------------------- -// Name: GetMediaTypeCount -// Description: Return the number of preferred media types. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::GetMediaTypeCount(__RPC__out DWORD* pdwTypeCount) -{ - HRESULT hr = S_OK; - - do - { - if (pdwTypeCount == NULL) - { - hr = E_POINTER; - break; - } - - hr = CheckShutdown(); - if (FAILED(hr)) - { - break; - } - - *pdwTypeCount = s_dwNumVideoFormats; - } - while (FALSE); - - return hr; -} - -//------------------------------------------------------------------- -// Name: IsMediaTypeSupported -// Description: Check if a media type is supported. -// -// pMediaType: The media type to check. -// ppMediaType: Optionally, receives a "close match" media type. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::IsMediaTypeSupported(IMFMediaType* pMediaType, _Outptr_opt_result_maybenull_ IMFMediaType** ppMediaType) -{ - HRESULT hr = S_OK; - GUID subType = GUID_NULL; - - do - { - hr = CheckShutdown(); - if (FAILED(hr)) - { - break; - } - - if (pMediaType == NULL) - { - hr = E_POINTER; - break; - } - - hr = pMediaType->GetGUID(MF_MT_SUBTYPE, &subType); - if (FAILED(hr)) - { - break; - } - - hr = MF_E_INVALIDMEDIATYPE; // This will be set to OK if we find the subtype is accepted - - for(DWORD i = 0; i < s_dwNumVideoFormats; i++) - { - if (subType == (*s_pVideoFormats[i])) - { - hr = S_OK; - break; - } - } - - if (FAILED(hr)) - { - break; - } - - for( DWORD i = 0; i < ARRAYSIZE( s_DXGIFormatMapping ); i++ ) - { - const FormatEntry& e = s_DXGIFormatMapping[i]; - if ( e.Subtype == subType ) - { - m_dxgiFormat = e.DXGIFormat; - break; - } - } - - hr = m_pPresenter->IsMediaTypeSupported(pMediaType, m_dxgiFormat); - if (FAILED(hr)) - { - break; - } - } - while (FALSE); - - // We don't return any "close match" types. - if (ppMediaType) - { - *ppMediaType = NULL; - } - - return hr; -} - -//------------------------------------------------------------------- -// Name: SetCurrentMediaType -// Description: Set the current media type. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::SetCurrentMediaType(IMFMediaType* pMediaType) -{ - if (pMediaType == NULL) - { - return E_POINTER; - } - - HRESULT hr = S_OK; - MFRatio fps = { 0, 0 }; - GUID guidSubtype = GUID_NULL; - - CAutoLock lock(&m_critSec); - - do - { - hr = CheckShutdown(); - if (FAILED(hr)) - { - break; - } - - hr = ValidateOperation(OpSetMediaType); - if (FAILED(hr)) - { - break; - } - - hr = IsMediaTypeSupported(pMediaType, NULL); - if (FAILED(hr)) - { - break; - } - - SafeRelease(m_pCurrentType); - m_pCurrentType = pMediaType; - m_pCurrentType->AddRef(); - - pMediaType->GetGUID(MF_MT_SUBTYPE, &guidSubtype); - - if ((guidSubtype == MFVideoFormat_NV12) || - (guidSubtype == MFVideoFormat_YV12) || - (guidSubtype == MFVideoFormat_IYUV) || - (guidSubtype == MFVideoFormat_YVU9) || - (guidSubtype == MFVideoFormat_I420)) - { - m_imageBytesPP.Numerator = 3; - m_imageBytesPP.Denominator = 2; - } - else if ((guidSubtype == MFVideoFormat_YUY2)|| - (guidSubtype == MFVideoFormat_RGB555) || - (guidSubtype == MFVideoFormat_RGB565) || - (guidSubtype == MFVideoFormat_UYVY) || - (guidSubtype == MFVideoFormat_YVYU) || - (guidSubtype == MEDIASUBTYPE_V216)) - { - m_imageBytesPP.Numerator = 2; - m_imageBytesPP.Denominator = 1; - } - else if (guidSubtype == MFVideoFormat_RGB24) - { - m_imageBytesPP.Numerator = 3; - m_imageBytesPP.Denominator = 1; - } - else if (guidSubtype == MFVideoFormat_RGB32) - { - m_imageBytesPP.Numerator = 4; - m_imageBytesPP.Denominator = 1; - } - else if (guidSubtype == MFVideoFormat_v410) - { - m_imageBytesPP.Numerator = 5; - m_imageBytesPP.Denominator = 4; - } - else // includes: - // MFVideoFormat_RGB8 - // MFVideoFormat_AYUV - // MFVideoFormat_NV11 - { - // This is just a fail-safe - m_imageBytesPP.Numerator = 1; - m_imageBytesPP.Denominator = 1; - } - - pMediaType->GetUINT32(MF_MT_INTERLACE_MODE, &m_unInterlaceMode); - - // Set the frame rate on the scheduler. - if (SUCCEEDED(GetFrameRate(pMediaType, &fps)) && (fps.Numerator != 0) && (fps.Denominator != 0)) - { - if (MFVideoInterlace_FieldInterleavedUpperFirst == m_unInterlaceMode || - MFVideoInterlace_FieldInterleavedLowerFirst == m_unInterlaceMode || - MFVideoInterlace_FieldSingleUpper == m_unInterlaceMode || - MFVideoInterlace_FieldSingleLower == m_unInterlaceMode || - MFVideoInterlace_MixedInterlaceOrProgressive == m_unInterlaceMode) - { - fps.Numerator*=2; - } - - m_pScheduler->SetFrameRate(fps); - } - else - { - // NOTE: The mixer's proposed type might not have a frame rate, in which case - // we'll use an arbitary default. (Although it's unlikely the video source - // does not have a frame rate.) - m_pScheduler->SetFrameRate(s_DefaultFrameRate); - } - - // Update the required sample count based on the media type (progressive vs. interlaced) - if (m_unInterlaceMode == MFVideoInterlace_Progressive) - { - // XVP will hold on to 1 sample but that's the same sample we will internally hold on to - hr = SetUINT32(MF_SA_REQUIRED_SAMPLE_COUNT, SAMPLE_QUEUE_HIWATER_THRESHOLD); - } - else - { - // Assume we will need a maximum of 3 backward reference frames for deinterlacing - // However, one of the frames is "shared" with SVR - hr = SetUINT32(MF_SA_REQUIRED_SAMPLE_COUNT, SAMPLE_QUEUE_HIWATER_THRESHOLD + MAX_PAST_FRAMES - 1); - } - - if (SUCCEEDED(hr)) - { - hr = m_pPresenter->SetCurrentMediaType(pMediaType); - if (FAILED(hr)) - { - break; - } - } - - if ( State_Started != m_state && State_Paused != m_state ) - { - m_state = State_Ready; - } - else - { - //Flush all current samples in the Queue as this is a format change - hr = Flush(); - } - } - while (FALSE); - - return hr; -} - -//------------------------------------------------------------------------- -// Name: GetService -// Description: IMFGetService -//------------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::GetService(__RPC__in REFGUID guidService, __RPC__in REFIID riid, __RPC__deref_out_opt LPVOID* ppvObject) -{ - IMFGetService* pGetService = NULL; - HRESULT hr = m_pSink->QueryInterface(IID_PPV_ARGS(&pGetService)); - if (SUCCEEDED(hr)) - { - hr = pGetService->GetService(guidService, riid, ppvObject); - } - SafeRelease(pGetService); - return hr; -} - -//+------------------------------------------------------------------------- -// -// Member: PresentFrame -// -// Synopsis: Present the current outstanding frame in the DX queue -// -//-------------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::PresentFrame(void) -{ - HRESULT hr = S_OK; - - if (DropFrames == m_ConsumeData) - { - return hr; - } - - CAutoLock lock(&m_critSec); - - do - { - hr = CheckShutdown(); - if (FAILED(hr)) - { - break; - } - - hr = m_pPresenter->PresentFrame(); - if (FAILED(hr)) - { - break; - } - } - while (FALSE); - - if (SUCCEEDED(hr)) - { - // Unless we are paused/stopped, start an async operation to dispatch the next sample. - if (m_state != State_Paused && m_state != State_Stopped) - { - // Queue the operation. - hr = QueueAsyncOperation(OpProcessSample); - } - } - else - { - // We are in the middle of an asynchronous operation, so if something failed, send an error. - hr = QueueEvent(MEError, GUID_NULL, hr, NULL); - } - - return hr; -} - -HRESULT DX11VideoRenderer::CStreamSink::GetMaxRate(BOOL fThin, float* pflRate) -{ - HRESULT hr = S_OK; - DWORD dwMonitorRefreshRate = 0; - UINT32 unNumerator = 0; - UINT32 unDenominator = 0; - - do - { - hr = m_pPresenter->GetMonitorRefreshRate(&dwMonitorRefreshRate); - if (FAILED(hr)) - { - break; - } - - if (m_pCurrentType == NULL) - { - hr = MF_E_INVALIDREQUEST; - break; - } - - if (fThin == TRUE) - { - *pflRate = FLT_MAX; - break; - } - - MFGetAttributeRatio(m_pCurrentType, MF_MT_FRAME_RATE, &unNumerator, &unDenominator); - - if (unNumerator == 0 || unDenominator == 0) - { - // We support anything. - *pflRate = FLT_MAX; - } - else - { - if (MFVideoInterlace_FieldInterleavedUpperFirst == m_unInterlaceMode || - MFVideoInterlace_FieldInterleavedLowerFirst == m_unInterlaceMode || - MFVideoInterlace_FieldSingleUpper == m_unInterlaceMode || - MFVideoInterlace_FieldSingleLower == m_unInterlaceMode || - MFVideoInterlace_MixedInterlaceOrProgressive == m_unInterlaceMode) - { - unNumerator*=2; - } - - // - // Only support rates up to the refresh rate of the monitor. - // - *pflRate = (float)MulDiv(dwMonitorRefreshRate, unDenominator, unNumerator); - } - } - while (FALSE); - - return hr; -} - -//------------------------------------------------------------------- -// Name: Initialize -// Description: Initializes the stream sink. -// -// Note: This method is called once when the media sink is first -// initialized. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::Initialize(IMFMediaSink* pParent, CPresenter* pPresenter) -{ - HRESULT hr = S_OK; - - if (SUCCEEDED(hr)) - { - hr = CMFAttributesImpl::Initialize(); - } - - // Create the event queue helper. - if (SUCCEEDED(hr)) - { - hr = MFCreateEventQueue(&m_pEventQueue); - } - - // Allocate a new work queue for async operations. - if (SUCCEEDED(hr)) - { - hr = MFAllocateWorkQueue(&m_WorkQueueId); - } - - if (SUCCEEDED(hr)) - { - m_pPresenter = pPresenter; - m_pPresenter->AddRef(); - } - - if (SUCCEEDED(hr)) - { - m_pSink = pParent; - m_pSink->AddRef(); - } - - return hr; -} - -//------------------------------------------------------------------- -// Name: Pause -// Description: Called when the presentation clock pauses. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::Pause(void) -{ - CAutoLock lock(&m_critSec); - - HRESULT hr = ValidateOperation(OpPause); - - if (SUCCEEDED(hr)) - { - m_state = State_Paused; - hr = QueueAsyncOperation(OpPause); - } - - return hr; -} - -HRESULT DX11VideoRenderer::CStreamSink::Preroll(void) -{ - HRESULT hr = S_OK; - - CAutoLock lock(&m_critSec); - - hr = CheckShutdown(); - - if (SUCCEEDED(hr)) - { - m_fPrerolling = TRUE; - m_fWaitingForOnClockStart = TRUE; - - // Kick things off by requesting a sample... - m_cOutstandingSampleRequests++; - - hr = QueueEvent(MEStreamSinkRequestSample, GUID_NULL, hr, NULL); - } - - return hr; -} - -//------------------------------------------------------------------- -// Name: Restart -// Description: Called when the presentation clock restarts. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::Restart(void) -{ - CAutoLock lock(&m_critSec); - - HRESULT hr = ValidateOperation(OpRestart); - - if (SUCCEEDED(hr)) - { - m_state = State_Started; - hr = QueueAsyncOperation(OpRestart); - } - - return hr; -} - -//------------------------------------------------------------------- -// Name: Shutdown -// Description: Shuts down the stream sink. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::Shutdown(void) -{ - CAutoLock lock(&m_critSec); - - m_IsShutdown = TRUE; - - if (m_pEventQueue) - { - m_pEventQueue->Shutdown(); - } - - MFUnlockWorkQueue(m_WorkQueueId); - - m_SamplesToProcess.Clear(); - - SafeRelease(m_pSink); - SafeRelease(m_pEventQueue); - SafeRelease(m_pByteStream); - SafeRelease(m_pPresenter); - SafeRelease(m_pCurrentType); - - return MF_E_SHUTDOWN; -} - -//------------------------------------------------------------------- -// Name: Start -// Description: Called when the presentation clock starts. -// Note: Start time can be PRESENTATION_CURRENT_POSITION meaning -// resume from the last current position. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::Start(MFTIME start) -{ - CAutoLock lock(&m_critSec); - - HRESULT hr = S_OK; - - do - { - hr = ValidateOperation(OpStart); - if (FAILED(hr)) - { - break; - } - - if (start != PRESENTATION_CURRENT_POSITION) - { - // We're starting from a "new" position - m_StartTime = start; // Cache the start time. - } - - m_state = State_Started; - hr = QueueAsyncOperation(OpStart); - } - while (FALSE); - - m_fWaitingForOnClockStart = FALSE; - - return hr; -} - -//------------------------------------------------------------------- -// Name: Stop -// Description: Called when the presentation clock stops. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::Stop(void) -{ - CAutoLock lock(&m_critSec); - - HRESULT hr = ValidateOperation(OpStop); - - if (SUCCEEDED(hr)) - { - m_state = State_Stopped; - hr = QueueAsyncOperation(OpStop); - } - - return hr; -} - -// private methods - -//------------------------------------------------------------------- -// Name: DispatchProcessSample -// Description: Complete a ProcessSample or PlaceMarker request. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::DispatchProcessSample(CAsyncOperation* pOp) -{ - HRESULT hr = S_OK; - assert(pOp != NULL); - - hr = CheckShutdown(); - if (FAILED(hr)) - { - return hr; - } - - if (m_pPresenter->CanProcessNextSample()) - { - hr = ProcessSamplesFromQueue(ProcessFrames); - - // Ask for another sample - if (SUCCEEDED(hr)) - { - if (pOp->m_op == OpProcessSample) - { - hr = RequestSamples(); - } - } - - // We are in the middle of an asynchronous operation, so if something failed, send an error. - if (FAILED(hr)) - { - hr = QueueEvent(MEError, GUID_NULL, hr, NULL); - } - } - - return hr; -} - -HRESULT DX11VideoRenderer::CStreamSink::CheckShutdown(void) const -{ - if (m_IsShutdown) - { - return MF_E_SHUTDOWN; - } - else - { - return S_OK; - } -} - -inline HRESULT DX11VideoRenderer::CStreamSink::GetFrameRate(IMFMediaType* pType, MFRatio* pRatio) -{ - return MFGetAttributeRatio(pType, MF_MT_FRAME_RATE, (UINT32*)&pRatio->Numerator, (UINT32*)&pRatio->Denominator); -} - -//+------------------------------------------------------------------------- -// -// Member: NeedMoreSamples -// -// Synopsis: Returns true if the number of samples in flight -// (queued + requested) is less than the max allowed -// -//-------------------------------------------------------------------------- -BOOL DX11VideoRenderer::CStreamSink::NeedMoreSamples(void) -{ - const DWORD cSamplesInFlight = m_SamplesToProcess.GetCount() + m_cOutstandingSampleRequests; - - return cSamplesInFlight < SAMPLE_QUEUE_HIWATER_THRESHOLD; -} - -//------------------------------------------------------------------- -// Name: OnDispatchWorkItem -// Description: Callback for MFPutWorkItem. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::OnDispatchWorkItem(IMFAsyncResult* pAsyncResult) -{ - // Called by work queue thread. Need to hold the critical section. - CAutoLock lock(&m_critSec); - - HRESULT hr = CheckShutdown(); - if (FAILED(hr)) - { - return hr; - } - - IUnknown* pState = NULL; - - hr = pAsyncResult->GetState(&pState); - - if (SUCCEEDED(hr)) - { - // The state object is a CAsncOperation object. - CAsyncOperation* pOp = (CAsyncOperation*)pState; - - StreamOperation op = pOp->m_op; - - switch (op) - { - case OpStart: - case OpRestart: - // Send MEStreamSinkStarted. - hr = QueueEvent(MEStreamSinkStarted, GUID_NULL, hr, NULL); - - // Kick things off by requesting two samples... - if (SUCCEEDED(hr)) - { - m_cOutstandingSampleRequests++; - hr = QueueEvent(MEStreamSinkRequestSample, GUID_NULL, hr, NULL); - } - - // There might be samples queue from earlier (ie, while paused). - if (SUCCEEDED(hr)) - { - hr = ProcessSamplesFromQueue(m_ConsumeData); - } - - break; - - case OpStop: - - m_pPresenter->SetFullscreen(FALSE); - - // Drop samples from queue. - Flush(); - - m_cOutstandingSampleRequests = 0; - - // Send the event even if the previous call failed. - hr = QueueEvent(MEStreamSinkStopped, GUID_NULL, hr, NULL); - - break; - - case OpPause: - hr = QueueEvent(MEStreamSinkPaused, GUID_NULL, hr, NULL); - break; - - case OpProcessSample: - case OpPlaceMarker: - if (!(m_fWaitingForOnClockStart)) - { - hr = DispatchProcessSample(pOp); - } - break; - } - } - - SafeRelease(pState); - - return hr; -} - -//------------------------------------------------------------------- -// Name: ProcessSamplesFromQueue -// Description: -// -// Removes all of the samples and markers that are currently in the -// queue and processes them. -// -// If bConsumeData = DropFrames -// For each marker, send an MEStreamSinkMarker event, with hr = E_ABORT. -// For each sample, drop the sample. -// -// If bConsumeData = ProcessFrames -// For each marker, send an MEStreamSinkMarker event, with hr = S_OK. -// For each sample, write the sample to the file. -// -// This method is called when we flush, stop, restart, receive a new -// sample, or receive a marker. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::ProcessSamplesFromQueue(ConsumeState bConsumeData) -{ - HRESULT hr = S_OK; - IUnknown* pUnk = NULL; - BOOL bProcessMoreSamples = TRUE; - BOOL bDeviceChanged = FALSE; - BOOL bProcessAgain = FALSE; - - // Enumerate all of the samples/markers in the queue. - - // Note: Dequeue returns S_FALSE when the queue is empty. - while (m_SamplesToProcess.Dequeue(&pUnk) == S_OK) - { - bProcessMoreSamples = TRUE; - IMarker* pMarker = NULL; - IMFSample* pSample = NULL; - IMFSample* pOutSample = NULL; - - // Figure out if this is a marker or a sample. - - hr = pUnk->QueryInterface(__uuidof(IMarker), (void**)&pMarker); - if (hr == E_NOINTERFACE) - { - // If this is a sample, write it to the file. - hr = pUnk->QueryInterface(IID_IMFSample, (void**)&pSample); - } - - // Now handle the sample/marker appropriately. - if (SUCCEEDED(hr)) - { - if (pMarker) - { - hr = SendMarkerEvent(pMarker, bConsumeData); - } - else - { - assert(pSample != NULL); // Not a marker, must be a sample - if (bConsumeData == ProcessFrames) - { - hr = m_pPresenter->ProcessFrame(m_pCurrentType, pSample, &m_unInterlaceMode, &bDeviceChanged, &bProcessAgain, &pOutSample); - - if (SUCCEEDED(hr)) - { - if (bDeviceChanged) - { - QueueEvent(MEStreamSinkDeviceChanged, GUID_NULL, S_OK, NULL); - } - - if (bProcessAgain) - { - // The input sample is not used. Return it to the queue. - hr = m_SamplesToProcess.PutBack(pSample); - } - } - - // If we are not actively playing, OR we are scrubbing (rate = 0) OR this is a - // repaint request, then we need to present the sample immediately. Otherwise, - // schedule it normally. - if (SUCCEEDED(hr)) - { - if (pOutSample) - { - hr = m_pScheduler->ScheduleSample(pOutSample, (State_Started != m_state)); - bProcessMoreSamples = FALSE; - } - } - } - } - } - - SafeRelease(pUnk); - SafeRelease(pMarker); - SafeRelease(pSample); - SafeRelease(pOutSample); - - if (!bProcessMoreSamples) - { - break; - } - } // while loop - - SafeRelease(pUnk); - - return hr; -} - -//------------------------------------------------------------------- -// Name: QueueAsyncOperation -// Description: Puts an async operation on the work queue. -//------------------------------------------------------------------- -HRESULT DX11VideoRenderer::CStreamSink::QueueAsyncOperation(StreamOperation op) -{ - HRESULT hr = S_OK; - CAsyncOperation* pOp = new CAsyncOperation(op); // Created with ref count = 1 - if (pOp == NULL) - { - hr = E_OUTOFMEMORY; - } - - if (SUCCEEDED(hr)) - { - hr = MFPutWorkItem(m_WorkQueueId, &m_WorkQueueCB, pOp); - } - - SafeRelease(pOp); // Releases ref count - - return hr; -} - -//+------------------------------------------------------------------------- -// -// Member: RequestSamples -// -// Synopsis: Issue more sample requests if necessary. -// -//-------------------------------------------------------------------------- -HRESULT DX11VideoRenderer::CStreamSink::RequestSamples(void) -{ - HRESULT hr = S_OK; - - while (NeedMoreSamples()) - { - hr = CheckShutdown(); - if (FAILED(hr)) - { - break; - } - - m_cOutstandingSampleRequests++; - - hr = QueueEvent(MEStreamSinkRequestSample, GUID_NULL, S_OK, NULL); - } - - return hr; -} - -//------------------------------------------------------------------- -// Name: SendMarkerEvent -// Description: Saned a marker event. -// -// pMarker: Pointer to our custom IMarker interface, which holds -// the marker information. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::SendMarkerEvent(IMarker* pMarker, ConsumeState ConsumeState) -{ - HRESULT hr = S_OK; - HRESULT hrStatus = S_OK; // Status code for marker event. - - PROPVARIANT var; - PropVariantInit(&var); - - do - { - if (ConsumeState == DropFrames) - { - hrStatus = E_ABORT; - } - - // Get the context data. - hr = pMarker->GetContext(&var); - - if (SUCCEEDED(hr)) - { - hr = QueueEvent(MEStreamSinkMarker, GUID_NULL, hrStatus, &var); - } - } - while (FALSE); - - PropVariantClear(&var); - - return hr; -} - -//------------------------------------------------------------------- -// Name: ValidateOperation -// Description: Checks if an operation is valid in the current state. -//------------------------------------------------------------------- - -HRESULT DX11VideoRenderer::CStreamSink::ValidateOperation(StreamOperation op) -{ - HRESULT hr = S_OK; - - BOOL bTransitionAllowed = ValidStateMatrix[m_state][op]; - - if (bTransitionAllowed) - { - return S_OK; - } - else - { - return MF_E_INVALIDREQUEST; - } -} - -///////////////////////////////////////////////////////////////////////////////////////////// -// -// CAsyncOperation class. - Private class used by CStreamSink class. -// -///////////////////////////////////////////////////////////////////////////////////////////// - -DX11VideoRenderer::CStreamSink::CAsyncOperation::CAsyncOperation(StreamOperation op) : - m_nRefCount(1), - m_op(op) -{ -} - -ULONG DX11VideoRenderer::CStreamSink::CAsyncOperation::AddRef(void) -{ - return InterlockedIncrement(&m_nRefCount); -} - -HRESULT DX11VideoRenderer::CStreamSink::CAsyncOperation::QueryInterface(REFIID iid, __RPC__deref_out _Result_nullonfailure_ void** ppv) -{ - if (!ppv) - { - return E_POINTER; - } - if (iid == IID_IUnknown) - { - *ppv = static_cast(this); - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -ULONG DX11VideoRenderer::CStreamSink::CAsyncOperation::Release(void) -{ - ULONG uCount = InterlockedDecrement(&m_nRefCount); - if (uCount == 0) - { - delete this; - } - // For thread safety, return a temporary variable. - return uCount; -} - -DX11VideoRenderer::CStreamSink::CAsyncOperation::~CAsyncOperation(void) -{ -} \ No newline at end of file diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/StreamSink.h b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/StreamSink.h deleted file mode 100644 index c0c73a7d..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/StreamSink.h +++ /dev/null @@ -1,186 +0,0 @@ -#pragma once - -#include "Common.h" -#include "display.h" -#include "MFAttributesImpl.h" -#include "Marker.h" -#include "Presenter.h" -#include "Scheduler.h" - -namespace DX11VideoRenderer -{ - class CStreamSink : - public IMFStreamSink, - public IMFMediaTypeHandler, - public IMFGetService, - public SchedulerCallback, - public CMFAttributesImpl, - private CBase - { - public: - - CStreamSink(DWORD dwStreamId, CCritSec& critSec, CScheduler* pScheduler); - virtual ~CStreamSink(void); - - // IUnknown - STDMETHODIMP_(ULONG) AddRef(void); - STDMETHODIMP QueryInterface(REFIID iid, __RPC__deref_out _Result_nullonfailure_ void** ppv); - STDMETHODIMP_(ULONG) Release(void); - - // IMFStreamSink - STDMETHODIMP Flush(void); - STDMETHODIMP GetIdentifier(__RPC__out DWORD* pdwIdentifier); - STDMETHODIMP GetMediaSink(__RPC__deref_out_opt IMFMediaSink** ppMediaSink); - STDMETHODIMP GetMediaTypeHandler(__RPC__deref_out_opt IMFMediaTypeHandler** ppHandler); - STDMETHODIMP PlaceMarker(MFSTREAMSINK_MARKER_TYPE eMarkerType, __RPC__in const PROPVARIANT* pvarMarkerValue, __RPC__in const PROPVARIANT* pvarContextValue); - STDMETHODIMP ProcessSample(__RPC__in_opt IMFSample* pSample); - - // IMFMediaEventGenerator (from IMFStreamSink) - STDMETHODIMP BeginGetEvent(IMFAsyncCallback* pCallback,IUnknown* punkState); - STDMETHODIMP EndGetEvent(IMFAsyncResult* pResult, _Out_ IMFMediaEvent** ppEvent); - STDMETHODIMP GetEvent(DWORD dwFlags, __RPC__deref_out_opt IMFMediaEvent** ppEvent); - STDMETHODIMP QueueEvent(MediaEventType met, __RPC__in REFGUID guidExtendedType, HRESULT hrStatus, __RPC__in_opt const PROPVARIANT* pvValue); - - // IMFMediaTypeHandler - STDMETHODIMP GetCurrentMediaType(_Outptr_ IMFMediaType** ppMediaType); - STDMETHODIMP GetMajorType(__RPC__out GUID* pguidMajorType); - STDMETHODIMP GetMediaTypeByIndex(DWORD dwIndex, _Outptr_ IMFMediaType** ppType); - STDMETHODIMP GetMediaTypeCount(__RPC__out DWORD* pdwTypeCount); - STDMETHODIMP IsMediaTypeSupported(IMFMediaType* pMediaType, _Outptr_opt_result_maybenull_ IMFMediaType** ppMediaType); - STDMETHODIMP SetCurrentMediaType(IMFMediaType* pMediaType); - - // IMFGetService - STDMETHODIMP GetService(__RPC__in REFGUID guidService, __RPC__in REFIID riid, __RPC__deref_out_opt LPVOID* ppvObject); - - // SchedulerCallback - HRESULT PresentFrame(void); - - HRESULT GetMaxRate(BOOL fThin, float* pflRate); - HRESULT Initialize(IMFMediaSink* pParent, CPresenter* pPresenter); - inline BOOL IsActive(void) const // IsActive: The "active" state is started or paused. - { - return ((m_state == State_Started) || (m_state == State_Paused)); - } - HRESULT Pause(void); - HRESULT Preroll(void); - HRESULT Restart(void); - HRESULT Shutdown(void); - HRESULT Start(MFTIME start); - HRESULT Stop(void); - - private: - - // State enum: Defines the current state of the stream. - enum State - { - State_TypeNotSet = 0, // No media type is set - State_Ready, // Media type is set, Start has never been called. - State_Started, - State_Paused, - State_Stopped, - - State_Count // Number of states - }; - - // StreamOperation: Defines various operations that can be performed on the stream. - enum StreamOperation - { - OpSetMediaType = 0, - OpStart, - OpRestart, - OpPause, - OpStop, - OpProcessSample, - OpPlaceMarker, - - Op_Count // Number of operations - }; - - enum ConsumeState - { - DropFrames = 0, - ProcessFrames - }; - - // CAsyncOperation: - // Used to queue asynchronous operations. When we call MFPutWorkItem, we use this - // object for the callback state (pState). Then, when the callback is invoked, - // we can use the object to determine which asynchronous operation to perform. - - // Optional data can include a sample (IMFSample) or a marker. - // When ProcessSample is called, we use it to queue a sample. When ProcessMarker is - // called, we use it to queue a marker. This way, samples and markers can live in - // the same queue. We need this because the sink has to serialize marker events - // with sample processing. - class CAsyncOperation : public IUnknown - { - public: - - CAsyncOperation(StreamOperation op); - - // IUnknown methods. - STDMETHODIMP_(ULONG) AddRef(void); - STDMETHODIMP QueryInterface(REFIID iid, __RPC__deref_out _Result_nullonfailure_ void** ppv); - STDMETHODIMP_(ULONG) Release(void); - - // Structure data. - StreamOperation m_op; // The operation to perform. - PROPVARIANT m_varDataWM; // Optional data, only used for water mark - - private: - - virtual ~CAsyncOperation(void); - - long m_nRefCount; - }; - - static GUID const* const s_pVideoFormats[]; - static const DWORD s_dwNumVideoFormats; - static const MFRatio s_DefaultFrameRate; - static const struct FormatEntry - { - GUID Subtype; - DXGI_FORMAT DXGIFormat; - } s_DXGIFormatMapping[]; - static BOOL ValidStateMatrix[State_Count][Op_Count]; // Defines a look-up table that says which operations are valid from which states. - - HRESULT DispatchProcessSample(CAsyncOperation* pOp); - HRESULT CheckShutdown(void) const; - HRESULT GetFrameRate(IMFMediaType* pType, MFRatio* pRatio); - BOOL NeedMoreSamples(void); - HRESULT OnDispatchWorkItem(IMFAsyncResult* pAsyncResult); - HRESULT ProcessSamplesFromQueue(ConsumeState bConsumeData); - HRESULT QueueAsyncOperation(StreamOperation op); - HRESULT RequestSamples(void); - HRESULT SendMarkerEvent(IMarker* pMarker, ConsumeState bConsumeData); - HRESULT ValidateOperation(StreamOperation op); - - const DWORD STREAM_ID; - long m_nRefCount; // reference count - CCritSec& m_critSec; // critical section for thread safety - State m_state; - BOOL m_IsShutdown; // Flag to indicate if Shutdown() method was called. - DWORD m_WorkQueueId; // ID of the work queue for asynchronous operations. - CAsyncCallback m_WorkQueueCB; // Callback for the work queue. - ConsumeState m_ConsumeData; // Flag to indicate process or drop frames - MFTIME m_StartTime; // Presentation time when the clock started. - DWORD m_cbDataWritten; // How many bytes we have written so far. - DWORD m_cOutstandingSampleRequests; // Outstanding reuqests for samples. - IMFMediaSink* m_pSink; // Parent media sink - IMFMediaEventQueue* m_pEventQueue; // Event queue - IMFByteStream* m_pByteStream; // Bytestream where we write the data. - CPresenter* m_pPresenter; - CScheduler* m_pScheduler; - IMFMediaType* m_pCurrentType; - BOOL m_fPrerolling; - BOOL m_fWaitingForOnClockStart; - ThreadSafeQueue m_SamplesToProcess; // Queue to hold samples and markers. Applies to: ProcessSample, PlaceMarker - UINT32 m_unInterlaceMode; - struct sFraction - { - DWORD Numerator; - DWORD Denominator; - } m_imageBytesPP; - DXGI_FORMAT m_dxgiFormat; - }; -} diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/display.cpp b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/display.cpp deleted file mode 100644 index 131e8270..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/display.cpp +++ /dev/null @@ -1,313 +0,0 @@ -/******************************Module*Header*******************************\ -* Module Name: display.cpp -* -* Support for DDraw device on Multiple Monitors. -* -* -* Created: Mon 01/24/2000 -* Author: Stephen Estrop [StEstrop] -* Mod: KirtD - First integration into MF renderer model -* -* Copyright (c) Microsoft Corporation -\**************************************************************************/ -#include -#include -#include "display.h" -#include - - -#ifndef DEFAULT_DENSITY_LIMIT -#define DEFAULT_DENSITY_LIMIT 60 -#endif -#ifndef WIDTH -#define WIDTH(x) ((x)->right - (x)->left) -#endif -#ifndef HEIGHT -#define HEIGHT(x) ((x)->bottom - (x)->top) -#endif - - -/* ------------------------------------------------------------------------- -** Structure use to pass info to the DDrawEnumEx callback -** ------------------------------------------------------------------------- -*/ - -struct DDRAWINFO -{ - DWORD dwCount; - DWORD dwPmiSize; - HRESULT hrCallback; - const GUID* pGUID; - CAMDDrawMonitorInfo* pmi; - HWND hwnd; -}; - -/******************************Public*Routine******************************\ -* TermDDrawMonitorInfo -* -* -* -* History: -* 01-17-2000 - StEstrop - Created -* -\**************************************************************************/ -void CMonitorArray::TermDDrawMonitorInfo( - _Inout_ CAMDDrawMonitorInfo* pmi - ) -{ - - - ZeroMemory(pmi, sizeof(CAMDDrawMonitorInfo)); -} - -/*****************************Private*Routine******************************\ -* GetAMDDrawMonitorInfo -* -* -* -* History: -* Tue 08/17/1999 - StEstrop - Created -* -\**************************************************************************/ -BOOL CMonitorArray::GetAMDDrawMonitorInfo( - UINT uDevID, - _Out_ CAMDDrawMonitorInfo* lpmi, - _In_ HMONITOR hm - ) -{ - MONITORINFOEX miInfoEx; - miInfoEx.cbSize = sizeof(miInfoEx); - - lpmi->hMon = NULL; - lpmi->uDevID = 0; - lpmi->physMonDim.cx = 0; - lpmi->physMonDim.cy = 0; - lpmi->dwRefreshRate = DEFAULT_DENSITY_LIMIT; - - if (GetMonitorInfo(hm, &miInfoEx)) - { - HRESULT hr = StringCchCopy(lpmi->szDevice, sizeof(lpmi->szDevice)/sizeof(lpmi->szDevice[0]), miInfoEx.szDevice); - - if ( FAILED( hr ) ) - { - return FALSE; - } - - lpmi->hMon = hm; - lpmi->uDevID = uDevID; - lpmi->physMonDim.cx = WIDTH(&miInfoEx.rcMonitor); - lpmi->physMonDim.cy = HEIGHT(&miInfoEx.rcMonitor); - - int j = 0; - DISPLAY_DEVICE ddMonitor; - - ddMonitor.cb = sizeof(ddMonitor); - while (EnumDisplayDevices(lpmi->szDevice, j, &ddMonitor, 0)) - { - if (ddMonitor.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) - { - DEVMODE dm; - - ZeroMemory(&dm, sizeof(dm)); - dm.dmSize = sizeof(dm); - if (EnumDisplaySettings(lpmi->szDevice, ENUM_CURRENT_SETTINGS, &dm)) - { - lpmi->dwRefreshRate = dm.dmDisplayFrequency == 0 ? lpmi->dwRefreshRate : dm.dmDisplayFrequency; - } - - // Remove registry snooping for monitor dimensions, as this is not supported by LDDM. - // if (!FindMonitorDimensions(ddMonitor.DeviceID, &lpmi->physMonDim.cx, &lpmi->physMonDim.cy)) - { - lpmi->physMonDim.cx = WIDTH(&miInfoEx.rcMonitor); - lpmi->physMonDim.cy = HEIGHT(&miInfoEx.rcMonitor); - } - } - j++; - } - - return TRUE; - } - - return FALSE; -} - - -BOOL CMonitorArray::InitMonitor( - _In_ HMONITOR hMon, - BOOL fXclMode - ) -{ - - - if (GetAMDDrawMonitorInfo(m_dwNumMonitors, &m_DDMon[m_dwNumMonitors], hMon)) - { - m_DDMon[m_dwNumMonitors].pDD = (IUnknown*)1; // make checks for pDD succeed. - m_dwNumMonitors++; - } - - if (EVR_MAX_MONITORS >= m_dwNumMonitors) - { - // don't exceed array bounds - return TRUE; - } - - return FALSE; -} - - -BOOL CALLBACK CMonitorArray::MonitorEnumProc( - _In_ HMONITOR hMon, - _In_opt_ HDC hDC, - _In_ LPRECT pRect, - LPARAM dwData - ) -{ - MonitorEnumProcInfo* info = (MonitorEnumProcInfo*)dwData; - - if (!info) - { - return TRUE; - } - - return info->pMonArray->InitMonitor(hMon, FALSE); -} - -/*****************************Private*Routine******************************\ -* InitializeDisplaySystem -* -* -* -* History: -* Mon 01/24/2000 - StEstrop - Created -* -\**************************************************************************/ -HRESULT CMonitorArray::InitializeDisplaySystem( - _In_ HWND hwnd - ) -{ - HRESULT hr = S_OK; - - MonitorEnumProcInfo info; - - info.hwnd = hwnd; - info.pMonArray = this; - - EnumDisplayMonitors(NULL, NULL, &MonitorEnumProc, (LPARAM)&info); - - if (m_dwNumMonitors == 0) - { - hr = HRESULT_FROM_WIN32(GetLastError()); - return(hr); - } - - return(hr); -} - -/*****************************Private*Routine******************************\ -* FindMonitor -* -* find the current monitor -* -* History: -* Fri 04/25/2000 - GlennE - Created -* -\**************************************************************************/ -CAMDDrawMonitorInfo* CMonitorArray::FindMonitor( - _In_ HMONITOR hMon - ) -{ - - - for (DWORD i = 0; i < m_dwNumMonitors; i++) - { - if (hMon == m_DDMon[i].hMon) - { - return &m_DDMon[i]; - } - } - - return NULL; -} - -/*****************************Private*Routine******************************\ -* MatchGUID -* -* -* -* History: -* Fri 04/25/2000 - GlennE - Created -* -\**************************************************************************/ -HRESULT CMonitorArray::MatchGUID( - UINT uDevID, - _Out_ DWORD* pdwMatchID - ) -{ - HRESULT hr = S_OK; - - *pdwMatchID = 0; - - for (DWORD i = 0; i < m_dwNumMonitors; i++) - { - - UINT uMonDevID = m_DDMon[i].uDevID; - - if (uDevID == uMonDevID) - { - - *pdwMatchID = i; - hr = S_OK; - return( hr ); - } - } - - hr = S_FALSE; - return( hr ); -} - - -/*****************************Private*Routine******************************\ -* TerminateDisplaySystem -* -* -* -* History: -* Mon 01/24/2000 - StEstrop - Created -* -\**************************************************************************/ -void CMonitorArray::TerminateDisplaySystem() -{ - - - for (DWORD i = 0; i < m_dwNumMonitors; i++) - { - TermDDrawMonitorInfo(&m_DDMon[i]); - } - m_dwNumMonitors = 0; -} - - -/******************************Public*Routine******************************\ -* Constructor and destructor -* -* -* -* History: -* Fri 11/17/2001 - StEstrop - Created -* -\**************************************************************************/ -CMonitorArray::CMonitorArray() - : m_dwNumMonitors(0) -{ - - - ZeroMemory(m_DDMon, sizeof(m_DDMon)); -} - - -CMonitorArray::~CMonitorArray() -{ - - TerminateDisplaySystem(); -} - diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/display.h b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/display.h deleted file mode 100644 index 529d35dc..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/display.h +++ /dev/null @@ -1,73 +0,0 @@ -/******************************Module*Header*******************************\ -* Module Name: display.h -* -* -* -* -* Created: Mon 01/24/2000 -* Author: Stephen Estrop [StEstrop] -* -* Copyright (c) Microsoft Corporation -\**************************************************************************/ - -#if !defined(__DISPLAY_H__) -#define __DISPLAY_H__ - -#define AMDDRAWMONITORINFO_PRIMARY_MONITOR 0x0001 - -struct CAMDDrawMonitorInfo -{ - UINT uDevID; - HMONITOR hMon; - TCHAR szDevice[ 32 ]; - LARGE_INTEGER liDriverVersion; - DWORD dwVendorId; - DWORD dwDeviceId; - DWORD dwSubSysId; - DWORD dwRevision; - SIZE physMonDim; - DWORD dwRefreshRate; - IUnknown *pDD; -}; - -#define EVR_MAX_MONITORS 16 - -class CMonitorArray -{ -public: - CMonitorArray(); - virtual ~CMonitorArray(); - - virtual HRESULT InitializeDisplaySystem(_In_ HWND hwnd); - - virtual HRESULT InitializeXclModeDisplaySystem(_In_ IUnknown* lpDD, _Out_ UINT* pAdapterID) { return E_NOTIMPL; } - - virtual void TerminateDisplaySystem(); - CAMDDrawMonitorInfo* FindMonitor(_In_ HMONITOR hMon); - HRESULT MatchGUID(UINT uDevID, _Out_ DWORD* pdwMatchID ); - - - CAMDDrawMonitorInfo& operator[](int i) - { return m_DDMon[i]; } - DWORD Count() const - { return m_dwNumMonitors; } - - static BOOL CALLBACK MonitorEnumProc(_In_ HMONITOR hMon, _In_opt_ HDC hDC, _In_ LPRECT pRect, LPARAM dwData); - - virtual BOOL InitMonitor(_In_ HMONITOR hMon, BOOL fXclMode); -protected: - BOOL GetAMDDrawMonitorInfo(UINT uDevID, _Out_ CAMDDrawMonitorInfo* lpmi, _In_ HMONITOR hm); - - virtual void TermDDrawMonitorInfo(_Inout_ CAMDDrawMonitorInfo* pmi); - - DWORD m_dwNumMonitors; - CAMDDrawMonitorInfo m_DDMon[EVR_MAX_MONITORS]; -}; - -typedef struct { - HWND hwnd; - CMonitorArray* pMonArray; -} MonitorEnumProcInfo; - -#endif // !defined(__DISPLAY_H__) - diff --git a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/linklist.h b/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/linklist.h deleted file mode 100644 index 95e277e4..00000000 --- a/Samples/BackgroundBlur/BackgroundBlur/DX11VideoRenderer/cpp/linklist.h +++ /dev/null @@ -1,735 +0,0 @@ -//----------------------------------------------------------------------------- -// File: Linklist.h -// Desc: Linked list class. -// Copyright (C) Microsoft Corporation. All rights reserved. -//----------------------------------------------------------------------------- - - -// Notes: -// -// This class template implements a simple double-linked list. -// Objects are held as pointers. (Does not use STL's copy semantics.) -// The Clear() method takes a functor object that releases the objects. - -#pragma once - -#include -#include -#include - -template -class List -{ -protected: - - // Nodes in the linked list - struct Node - { - Node *prev; - Node *next; - T *item; - - Node() : prev(NULL), next(NULL), item(NULL) - { - } - - Node(T* item) : prev(NULL), next(NULL) - { - this->item = item; - } - - T* Item() const { return item; } - }; - - - -protected: - Node m_anchor; // Anchor node for the linked list. - DWORD m_count; // Number of items in the list - - Node *m_pEnum; // Enumeration node - - void InvalidateEnumerator() - { - m_pEnum = NULL; - } - - Node* Front() const - { - return m_anchor.next; - } - - Node* Back() const - { - return m_anchor.prev; - } - - virtual HRESULT InsertAfter(T* item, Node *pBefore) - { - if (item == NULL || pBefore == NULL) - { - return E_POINTER; - } - - Node *pNode = new Node(item); - if (pNode == NULL) - { - return E_OUTOFMEMORY; - } - - Node *pAfter = pBefore->next; - - pBefore->next = pNode; - pAfter->prev = pNode; - - pNode->prev = pBefore; - pNode->next = pAfter; - - m_count++; - - InvalidateEnumerator(); - - return S_OK; - } - - virtual HRESULT GetItem(Node *pNode, T** ppItem) - { - if (pNode == NULL || ppItem == NULL) - { - return E_POINTER; - } - - if (pNode->item) - { - *ppItem = pNode->item; - return S_OK; - } - else - { - return E_INVALIDARG; - } - } - - - // RemoveItem: - // Removes a node and optionally returns the item. - // ppItem can be NULL. - virtual HRESULT RemoveItem(Node *pNode, T **ppItem) - { - if (pNode == NULL) - { - return E_POINTER; - } - - if (pNode == &m_anchor) - { - return E_INVALIDARG; - } - - - T* item = NULL; - - // anchor points back to the previous thing - m_anchor.prev = pNode->prev; - - // the previous thing points to the anchor - pNode->prev->next = &m_anchor; - - item = pNode->item; - delete pNode; - - m_count--; - - if (ppItem) - { - *ppItem = item; - } - - InvalidateEnumerator(); - - return S_OK; - } - -public: - - List() - { - m_anchor.next = &m_anchor; - m_anchor.prev = &m_anchor; - - m_count = 0; - - m_pEnum = NULL; - } - - virtual ~List() - { - - } - - // Insertion functions - HRESULT InsertBack(T* item) - { - return InsertAfter(item, m_anchor.prev); - } - - HRESULT InsertFront(T* item) - { - return InsertAfter(item, &m_anchor); - } - - // RemoveBack: Removes the tail of the list and returns the value. - HRESULT RemoveBack(T **ppItem) - { - if (IsEmpty()) - { - return E_FAIL; - } - else - { - return RemoveItem(Back(), ppItem); - } - } - - // RemoveFront: Removes the head of the list and returns the value. - HRESULT RemoveFront(T **ppItem) - { - if (IsEmpty()) - { - return E_FAIL; - } - else - { - return RemoveItem(Front(), ppItem); - } - } - - HRESULT PopFront() - { - return RemoveFront(NULL); - } - - HRESULT PopBack() - { - return RemoveBack(NULL); - } - - HRESULT GetBack(T **ppItem) - { - if (IsEmpty()) - { - return E_FAIL; - } - else - { - return GetItem(Back(), ppItem); - } - } - - HRESULT GetFront(T **ppItem) - { - if (IsEmpty()) - { - return E_FAIL; - } - else - { - return GetItem(Front(), ppItem); - } - } - - // GetCount: Returns the number of items in the list. - DWORD GetCount() const { return m_count; } - - bool IsEmpty() const - { - return (GetCount() == 0); - } - - // Clear: Takes a functor object whose operator() - // frees the object on the list. - template - void Clear(FN& clear_fn) - { - Node *n = m_anchor.next; - - // Delete the nodes - while (n != &m_anchor) - { - clear_fn(n->item); - - Node *tmp = n->next; - delete n; - n = tmp; - } - - // Reset the anchor to point at itself - m_anchor.next = &m_anchor; - m_anchor.prev = &m_anchor; - - m_count = 0; - } - - // Enumerator functions - void ResetEnumerator() - { - m_pEnum = Front(); - } - - HRESULT Next(T **ppItem) - { - if (ppItem == NULL) - { - return E_POINTER; - } - - if (m_pEnum == NULL) - { - return E_FAIL; // Needs reset - } - - if (m_pEnum == &m_anchor) - { - return __HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS); - } - - HRESULT hr = GetItem(m_pEnum, ppItem); - - if (SUCCEEDED(hr)) - { - m_pEnum = m_pEnum->next; - } - return hr; - } - -}; - - - -// Typical functors for Clear method. - -// ComAutoRelease: Releases COM pointers. -// MemDelete: Deletes pointers to new'd memory. - -class ComAutoRelease -{ -public: - void operator()(IUnknown *p) - { - if (p) - { - p->Release(); - } - } -}; - -class MemDelete -{ -public: - void operator()(void *p) - { - if (p) - { - delete p; - } - } -}; - - - //ComPtrList class - //Derived class that makes it safer to store COM pointers in the List<> class. - //It automatically AddRef's the pointers that are inserted onto the list - //(unless the insertion method fails). - - //T must be a COM interface type. - -template -class ComPtrList : public List -{ -public: - void Clear() - { - List::Clear(ComAutoRelease()); - } - -protected: - HRESULT InsertAfter(T* item, typename List::Node * pBefore) - { - item->AddRef(); - - HRESULT hr = List::InsertAfter(item, pBefore); - if (FAILED(hr)) - { - item->Release(); - } - return hr; - } - - HRESULT GetItem(typename List::Node *pNode, T** ppItem) - { - HRESULT hr = List::GetItem(pNode, ppItem); - if (SUCCEEDED(hr)) - { - (*ppItem)->AddRef(); - } - return hr; - } - - HRESULT RemoveItem(typename List::Node *pNode, T **ppItem) - { - // ppItem can be NULL, but we need to get the - // item so that we can release it. - - // If ppItem is not NULL, we will AddRef it on the way out/ - - T* item = NULL; - - HRESULT hr = List::RemoveItem(pNode, &item); - - if (SUCCEEDED(hr)) - { - if (ppItem) - { - *ppItem = item; - (*ppItem)->AddRef(); - } - - item->Release(); - } - - return hr; - } - -}; - -template -class ComPtrListEx -{ -protected: - - typedef T* Ptr; - - // Nodes in the linked list - struct Node - { - Node *prev; - Node *next; - Ptr item; - - Node() : prev(NULL), next(NULL), item(NULL) - { - } - - Node(Ptr item) : prev(NULL), next(NULL) - { - this->item = item; - if (item) - { - item->AddRef(); - } - } - ~Node() - { - if (item) - { - item->Release(); - } - } - - Ptr Item() const { return item; } - }; - -public: - - // Object for enumerating the list. - class POSITION - { - friend class ComPtrListEx; - - public: - POSITION() : pNode(NULL) - { - } - - bool operator==(const POSITION &p) const - { - return pNode == p.pNode; - } - - bool operator!=(const POSITION &p) const - { - return pNode != p.pNode; - } - - private: - const Node *pNode; - - POSITION(Node *p) : pNode(p) - { - } - }; - -protected: - Node m_anchor; // Anchor node for the linked list. - DWORD m_count; // Number of items in the list. - - Node* Front() const - { - return m_anchor.next; - } - - Node* Back() const - { - return m_anchor.prev; - } - - virtual HRESULT InsertAfter(Ptr item, Node *pBefore) - { - if (pBefore == NULL) - { - return E_POINTER; - } - - // Do not allow NULL item pointers unless NULLABLE is true. - if (!item && !NULLABLE) - { - return E_POINTER; - } - - Node *pNode = new Node(item); - if (pNode == NULL) - { - return E_OUTOFMEMORY; - } - - Node *pAfter = pBefore->next; - - pBefore->next = pNode; - pAfter->prev = pNode; - - pNode->prev = pBefore; - pNode->next = pAfter; - - m_count++; - - return S_OK; - } - - virtual HRESULT GetItem(const Node *pNode, Ptr* ppItem) - { - if (pNode == NULL || ppItem == NULL) - { - return E_POINTER; - } - - *ppItem = pNode->item; - - if (*ppItem) - { - (*ppItem)->AddRef(); - } - - return S_OK; - } - - // RemoveItem: - // Removes a node and optionally returns the item. - // ppItem can be NULL. - virtual HRESULT RemoveItem(Node *pNode, Ptr *ppItem) - { - if (pNode == NULL) - { - return E_POINTER; - } - - assert(pNode != &m_anchor); // We should never try to remove the anchor node. - if (pNode == &m_anchor) - { - return E_INVALIDARG; - } - - - Ptr item; - - // The next node's previous is this node's previous. - pNode->next->prev = pNode->prev; - - // The previous node's next is this node's next. - pNode->prev->next = pNode->next; - - item = pNode->item; - - if (ppItem) - { - *ppItem = item; - - if (*ppItem) - { - (*ppItem)->AddRef(); - } - } - - delete pNode; - m_count--; - - return S_OK; - } - -public: - - ComPtrListEx() - { - m_anchor.next = &m_anchor; - m_anchor.prev = &m_anchor; - - m_count = 0; - } - - virtual ~ComPtrListEx() - { - Clear(); - } - - void Clear() - { - Node *n = m_anchor.next; - - // Delete the nodes - while (n != &m_anchor) - { - if (n->item) - { - n->item->Release(); - n->item = NULL; - } - - Node *tmp = n->next; - delete n; - n = tmp; - } - - // Reset the anchor to point at itself - m_anchor.next = &m_anchor; - m_anchor.prev = &m_anchor; - - m_count = 0; - } - - // Insertion functions - HRESULT InsertBack(Ptr item) - { - return InsertAfter(item, m_anchor.prev); - } - - - HRESULT InsertFront(Ptr item) - { - return InsertAfter(item, &m_anchor); - } - - // RemoveBack: Removes the tail of the list and returns the value. - // ppItem can be NULL if you don't want the item back. - HRESULT RemoveBack(Ptr *ppItem) - { - if (IsEmpty()) - { - return E_FAIL; - } - else - { - return RemoveItem(Back(), ppItem); - } - } - - // RemoveFront: Removes the head of the list and returns the value. - // ppItem can be NULL if you don't want the item back. - HRESULT RemoveFront(Ptr *ppItem) - { - if (IsEmpty()) - { - return E_FAIL; - } - else - { - return RemoveItem(Front(), ppItem); - } - } - - // GetBack: Gets the tail item. - HRESULT GetBack(Ptr *ppItem) - { - if (IsEmpty()) - { - return E_FAIL; - } - else - { - return GetItem(Back(), ppItem); - } - } - - // GetFront: Gets the front item. - HRESULT GetFront(Ptr *ppItem) - { - if (IsEmpty()) - { - return E_FAIL; - } - else - { - return GetItem(Front(), ppItem); - } - } - - - // GetCount: Returns the number of items in the list. - DWORD GetCount() const { return m_count; } - - bool IsEmpty() const - { - return (GetCount() == 0); - } - - // Enumerator functions - - POSITION FrontPosition() - { - if (IsEmpty()) - { - return POSITION(NULL); - } - else - { - return POSITION(Front()); - } - } - - POSITION EndPosition() const - { - return POSITION(); - } - - HRESULT GetItemByPosition(POSITION pos, Ptr *ppItem) - { - if (pos.pNode) - { - return GetItem(pos.pNode, ppItem); - } - else - { - return E_FAIL; - } - } - - POSITION Next(const POSITION pos) - { - if (pos.pNode && (pos.pNode->next != &m_anchor)) - { - return POSITION(pos.pNode->next); - } - else - { - return POSITION(NULL); - } - } -}; \ No newline at end of file diff --git a/Samples/BackgroundBlur/BackgroundBlur/TransformBlur.cpp b/Samples/BackgroundBlur/BackgroundBlur/TransformBlur.cpp index 99bd1c92..89bbc7d4 100644 --- a/Samples/BackgroundBlur/BackgroundBlur/TransformBlur.cpp +++ b/Samples/BackgroundBlur/BackgroundBlur/TransformBlur.cpp @@ -12,9 +12,9 @@ const FOURCC FOURCC_RGB24 = 20; const GUID* g_MediaSubtypes[] = { &MFVideoFormat_RGB24, - //&MEDIASUBTYPE_NV12, - //&MEDIASUBTYPE_YUY2, - //&MEDIASUBTYPE_UYVY + &MEDIASUBTYPE_NV12, + &MEDIASUBTYPE_YUY2, + &MEDIASUBTYPE_UYVY }; // Number of media types in the aray. @@ -72,7 +72,9 @@ TransformBlur::TransformBlur(HRESULT& hr) : m_cbImageSize(0), m_pTransformFn(NULL), m_pD3DDeviceManager(NULL), - m_pDecoderService(NULL) + m_pHandle(NULL), + m_pD3DDevice(NULL), + m_pD3DVideoDevice(NULL) { } @@ -84,8 +86,11 @@ TransformBlur::~TransformBlur() SAFE_RELEASE(m_pInputType); SAFE_RELEASE(m_pOutputType); SAFE_RELEASE(m_pSample); + + m_pD3DDeviceManager->CloseDeviceHandle(m_pHandle); SAFE_RELEASE(m_pD3DDeviceManager); - SAFE_RELEASE(m_pDecoderService); + SAFE_RELEASE(m_pD3DDevice); + SAFE_RELEASE(m_pD3DVideoDevice); } // IUnknown methods @@ -492,44 +497,31 @@ HRESULT TransformBlur::SetInputType( CHECK_HR(hr = OnCheckInputType(pType)); } - // Find a d3d decoder configuration, if have a video device to use - // TODO: Clear false if this is the way to go later - // TODO: Move to checkinputtype - - - if (m_pD3DDeviceManager && m_pDecoderService) + // Find a decoder configuration + if (m_pD3DDeviceManager) { UINT numDevices = 0; UINT numFormats = 0; GUID* pguids = NULL; D3DFORMAT* d3dFormats = NULL; - m_pDecoderService->GetDecoderDeviceGuids(&numDevices, &pguids); - for (UINT i = 0; i < numDevices; i++) + + UINT numProfiles = m_pD3DVideoDevice->GetVideoDecoderProfileCount(); + for (UINT i = 0; i < numProfiles; i++) { - g = pguids[i]; - if (g == DXVA2_ModeH264_E || g == DXVA2_ModeH264_VLD_NoFGT) - { - OutputDebugString(L"Found h264 decoder E"); - //break; - } - m_pDecoderService->GetDecoderRenderTargets(g, &numFormats, &d3dFormats); - for (UINT j = 0; j < numDevices; j++) - { - d = d3dFormats[j]; - //(D3DFORMAT)subtype.Data1; - for (int k = 0; k < g_cNumSubtypes; k++) - { - GUID gtest = *g_MediaSubtypes[k]; - if (d == (D3DFORMAT)(gtest.Data1)) - { - OutputDebugString(L"Found a decoder with a supported format"); - // pType = ; - break; - } - } + GUID pDecoderProfile = GUID_NULL; + CHECK_HR(hr = m_pD3DVideoDevice->GetVideoDecoderProfile(i, &pDecoderProfile)); + + BOOL rgbSupport; + hr = m_pD3DVideoDevice->CheckVideoDecoderFormat(&pDecoderProfile, DXGI_FORMAT_AYUV, &rgbSupport); + // IF H264 and supports a yuv/rgb format + if (rgbSupport) { + // D3D11_DECODER_PROFILE_H264_VLD_NOFGT + OutputDebugString(L"supports AYUV!"); } } + + // TODO: Move to done CoTaskMemFree(pguids); CoTaskMemFree(d3dFormats); @@ -854,14 +846,14 @@ HRESULT TransformBlur::OnSetD3DManager(ULONG_PTR ulParam) } // Get a handle to the DXVA decoder service + // TODO: Change to give to the field instead of local variable hr = m_pD3DDeviceManager->OpenDeviceHandle(&p_deviceHandle); // Get the d3d11 device - m_pD3DDeviceManager->GetVideoService(p_deviceHandle, IID_ID3D12Device, (void**) &pd3dDevice); + m_pD3DDeviceManager->GetVideoService(p_deviceHandle, IID_ID3D12Device, (void**) &m_pD3DDevice); // Get the d3d11 video device - hr = m_pD3DDeviceManager->GetVideoService(p_deviceHandle, IID_ID3D11VideoDevice, (void**) &m_pDecoderService); - + hr = m_pD3DDeviceManager->GetVideoService(p_deviceHandle, IID_ID3D11VideoDevice, (void**) &m_pD3DVideoDevice); if (FAILED(hr)) { @@ -869,6 +861,8 @@ HRESULT TransformBlur::OnSetD3DManager(ULONG_PTR ulParam) ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER, NULL); } + // TOOD: Get the ID3D11DeviceContext and use to add multi-thread protection on the device context + done: //TODO: Safe release anything as needed SAFE_RELEASE(ptr); @@ -888,7 +882,6 @@ HRESULT TransformBlur::ProcessInput( ) { AutoLock lock(m_critSec); - IDirect3DSurface11* ppSurface = NULL; IMFMediaBuffer* pBuffer = NULL; if (pSample == NULL) @@ -935,12 +928,12 @@ HRESULT TransformBlur::ProcessInput( m_pSample = pSample; // Check if for some reason already have d3dsurface - hr = pSample->GetBufferByIndex(0, &pBuffer); + /*hr = pSample->GetBufferByIndex(0, &pBuffer); if (SUCCEEDED(hr)) { HRESULT test = MFGetService(pBuffer, MR_BUFFER_SERVICE, IID_PPV_ARGS(ppSurface)); pBuffer->Release(); - } + }*/ pSample->AddRef(); // Hold a reference count on the sample. @@ -1236,21 +1229,6 @@ HRESULT TransformBlur::OnSetInputType(IMFMediaType* pmt) // Update the format information. UpdateFormatInfo(); - IDirect3DSurface9* ppSurfaces[4]; - if (m_pDecoderService) { - hr = m_pDecoderService->CreateSurface( - m_imageWidthInPixels, - m_imageHeightInPixels, - 3, // Number of backbuffers - des.Format, // D3DFORMAT - D3DPOOL_DEFAULT, // Memory pool to create the surfaces - 0, // Reserved - DXVA2_VideoProcessorRenderTarget, //DXVATYPE Type of surface to make - ppSurfaces, // Out array of d3d9 surfaces - NULL - ); - } - return S_OK; } diff --git a/Samples/BackgroundBlur/BackgroundBlur/TransformBlur.h b/Samples/BackgroundBlur/BackgroundBlur/TransformBlur.h index 5c64d3e4..fa324063 100644 --- a/Samples/BackgroundBlur/BackgroundBlur/TransformBlur.h +++ b/Samples/BackgroundBlur/BackgroundBlur/TransformBlur.h @@ -19,7 +19,7 @@ #define USE_LOGGING -#include "common.h" +#include "common/common.h" using namespace MediaFoundationSamples; #include "SegmentModel.h" @@ -212,8 +212,12 @@ private: IMAGE_TRANSFORM_FN m_pTransformFn; // D3D fields - IMFDXGIDeviceManager* m_pD3DDeviceManager; - IDirectXVideoDecoderService* m_pDecoderService; + IMFDXGIDeviceManager* m_pD3DDeviceManager; + HANDLE m_pHandle; // Handle to the current device + // IDirectXVideoDecoderService*m_pDecoderService; + ID3D11Device* m_pD3DDevice; + ID3D11VideoDevice* m_pD3DVideoDevice; + // Model fields SegmentModel m_segmentModel; }; \ No newline at end of file diff --git a/Samples/BackgroundBlur/BackgroundBlur/player.cpp b/Samples/BackgroundBlur/BackgroundBlur/player.cpp index 8bd633cc..050b9925 100644 --- a/Samples/BackgroundBlur/BackgroundBlur/player.cpp +++ b/Samples/BackgroundBlur/BackgroundBlur/player.cpp @@ -958,55 +958,6 @@ done: return hr; } -// Create an object for a renderer, based on the stream media type. -HRESULT CreateMediaSink( - IMFStreamDescriptor* pSourceSD, // Pointer to the stream descriptor. - HWND hVideoWindow, // Handle to the video clipping window. - IMFMediaSink** ppSink -) -{ - IMFMediaTypeHandler* pHandler = NULL; - IMFMediaSink* pSink = NULL; - - // Get the media type handler for the stream. - HRESULT hr = pSourceSD->GetMediaTypeHandler(&pHandler); - if (FAILED(hr)) - { - goto done; - } - - // Get the major media type. - GUID guidMajorType; - hr = pHandler->GetMajorType(&guidMajorType); - if (FAILED(hr)) - { - goto done; - } - - if (MFMediaType_Video == guidMajorType) - { - hr = CreateDX11VideoRenderer(__uuidof(IMFMediaSink), (void**)&pSink); - } - else - { - // Unknown stream type. - hr = E_FAIL; - // Optionally, you could deselect this stream instead of failing. - } - if (FAILED(hr)) - { - goto done; - } - - // Return IMFMediaSink pointer to caller. - *ppSink = pSink; - (*ppSink)->AddRef(); - -done: - SafeRelease(&pHandler); - SafeRelease(&pSink); - return hr; -} // Create an activation object for a renderer, based on the stream media type. @@ -1249,65 +1200,6 @@ done: return hr; } -// Add an output node to a topology. -HRESULT AddOutputNode( - IMFTopology* pTopology, // Topology. - IMFMediaSink* pSink, // Media sink activation object. - DWORD dwId, // Identifier of the stream sink. - IMFTopologyNode** ppNode) // Receives the node pointer. -{ - IMFTopologyNode* pNode = NULL; - IDirect3DDeviceManager9* man = NULL; - IMFStreamSink* pStreamSink = NULL; - - // Create the node. - HRESULT hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &pNode); - if (FAILED(hr)) - { - goto done; - } - - CHECK_HR(hr = pSink->GetStreamSinkByIndex(dwId, &pStreamSink)); - // Set the object pointer. - hr = pNode->SetObject(pStreamSink); - if (FAILED(hr)) - { - goto done; - } - - // Set the stream sink ID attribute. - hr = pNode->SetUINT32(MF_TOPONODE_STREAMID, dwId); - if (FAILED(hr)) - { - goto done; - } - - hr = pNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE); - if (FAILED(hr)) - { - goto done; - } - - // Add the node to the topology. - hr = pTopology->AddNode(pNode); - if (FAILED(hr)) - { - goto done; - } - BindOutputNode(pNode); - // Return the pointer to the caller. - *ppNode = pNode; - - - (*ppNode)->AddRef(); - -done: - SafeRelease(&pNode); - return hr; -} -// - - HRESULT AddTransformNode( IMFTopology* pTopology, // Topology. IMFDXGIDeviceManager* d3dManager, @@ -1331,12 +1223,12 @@ HRESULT AddTransformNode( { hr = pNode->SetObject(pMFT); - //Determine if d3d-aware + //Determine if the MFT is d3d-aware IMFAttributes* p_attr = NULL; UINT32 p_aware = FALSE; - pMFT->GetAttributes(&p_attr); + hr = pMFT->GetAttributes(&p_attr); UINT32 aware = MFGetAttributeUINT32(p_attr, MF_SA_D3D_AWARE, p_aware); - if (false && aware == TRUE && d3dManager) { + if (aware == TRUE && d3dManager) { pMFT->ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)d3dManager); pNode->SetUINT32(MF_TOPONODE_D3DAWARE, TRUE); } @@ -1404,8 +1296,6 @@ HRESULT AddBranchToPartialTopology( goto done; } - CHECK_HR(hr = CreateMediaSink(pSD, hVideoWnd, &pSink)); - // Add a source node for this stream. hr = AddSourceNode(pTopology, pSource, pPD, pSD, &pSourceNode); if (FAILED(hr)) @@ -1428,11 +1318,7 @@ HRESULT AddBranchToPartialTopology( CHECK_HR(hr = pHandler->GetMajorType(&guidMajorType)); if (MFMediaType_Video == guidMajorType) { - //TRACE((L"Adding MFT to video stream")); - class __declspec(uuid("{2F3DBC05-C011-4a8f-B264-E42E35C67BF4}")) ColorConverter; //"{98230571-0087-4204-b020-3282538e57d3}" - CLSID guid = __uuidof(ColorConverter); - - + // Query the output node for the d3d device manager IUnknown* pNodeObject = NULL; IMFDXGIDeviceManager* pD3DManager = NULL; hr = pOutputNode->GetObject(&pNodeObject);