Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Toto téma popisuje, jak implementovat rozhraní MMFAsyncResult.
Je vzácné, že budete muset napsat vlastní implementaci MMFAsyncResult rozhraní. Téměř ve všech případech stačí standardní implementace Media Foundation. (Tuto implementaci vrátí funkce MFCreateAsyncResult.) Pokud ale napíšete vlastní implementaci, je potřeba si uvědomit některé problémy.
Nejprve musí implementace dědit MFASYNCRESULT strukturu. Pracovní fronty Media Foundation používají tuto strukturu interně k odeslání operace. Inicializuje všechny členy struktury na nulu, s výjimkou pCallback člen, který obsahuje ukazatel na rozhraní zpětného volání volajícího.
Za druhé, objekt by měl volat MFLockPlatform v jeho konstruktoru pro uzamčení platformy Media Foundation. Zavolejte MFUnlockPlatform k odemknutí platformy. Tyto funkce pomáhají zabránit vypnutí platformy před zničením objektu. Další informace naleznete v tématu Pracovní fronty.
Následující kód ukazuje základní implementaci rozhraní MMFAsyncResult. Jak je znázorněno, tento kód neposkytuje žádné další funkce nad rámec standardní implementace Media Foundation.
///////////////////////////////////////////////////////////////////////////////
// CMyAsyncResult
//
// Custom implementation of IMFAsyncResult. All implementations of this
// interface must inherit the MFASYNCRESULT structure.
//
///////////////////////////////////////////////////////////////////////////////
class CMyAsyncResult : public MFASYNCRESULT
{
protected:
LONG m_cRef; // Reference count.
BOOL m_bLockPlatform; // Locked the Media Foundation platform?
IUnknown* m_pState; // Caller's state object.
IUnknown* m_pObject; // Optional object. See IMFAsyncResult::GetObject.
// Constructor.
CMyAsyncResult(IMFAsyncCallback *pCallback, IUnknown *pState, HRESULT *phr) :
m_cRef(1),
m_bLockPlatform(FALSE),
m_pObject(NULL),
m_pState(pState)
{
*phr = MFLockPlatform();
m_bLockPlatform = TRUE;
// Initialize the MFASYNCRESULT members.
ZeroMemory(&this->overlapped, sizeof(OVERLAPPED));
hrStatusResult = S_OK;
dwBytesTransferred = 0;
hEvent = NULL;
this->pCallback = pCallback;
if (pCallback)
{
this->pCallback->AddRef();
}
if (m_pState)
{
m_pState->AddRef();
}
}
virtual ~CMyAsyncResult()
{
SafeRelease(&pCallback);
SafeRelease(&m_pState);
SafeRelease(&m_pObject);
if (m_bLockPlatform)
{
MFUnlockPlatform();
}
}
public:
// Static method to create an instance of this object.
static HRESULT CreateInstance(
IMFAsyncCallback *pCallback, // Callback to invoke.
IUnknown *pState, // Optional state object.
CMyAsyncResult **ppResult // Receives a pointer to the object.
)
{
HRESULT hr = S_OK;
*ppResult = NULL;
CMyAsyncResult *pResult =
new (std::nothrow) CMyAsyncResult(pCallback, pState, &hr);
if (pResult == NULL)
{
return E_OUTOFMEMORY;
}
if (FAILED(hr))
{
delete pResult;
return hr;
}
// If the callback is NULL, create an event that will be signaled.
if (pCallback == NULL)
{
pResult->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (pResult->hEvent == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
}
if (SUCCEEDED(hr))
{
*ppResult = pResult; // Return the pointer to the caller.
}
else
{
pResult->Release();
}
return hr;
}
// SetObject: Sets the optional result object.
// (This method is not part of the interface.)
HRESULT SetObject(IUnknown *pObject)
{
SafeRelease(&m_pObject);
m_pObject = pObject;
if (pObject)
{
m_pObject->AddRef();
}
return S_OK;
}
// IUnknown methods.
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
static const QITAB qit[] =
{
QITABENT(CMyAsyncResult, IMFAsyncResult),
{ 0 }
};
return QISearch(this, qit, riid, ppv);
}
STDMETHODIMP_(ULONG) AddRef()
{
return InterlockedIncrement(&m_cRef);
}
STDMETHODIMP_(ULONG) Release()
{
LONG cRef = InterlockedDecrement(&m_cRef);
if (cRef == 0)
{
delete this;
}
return cRef;
}
// IMFAsyncResult methods.
STDMETHODIMP GetState(IUnknown** ppunkState)
{
if (ppunkState == NULL)
{
return E_POINTER;
}
*ppunkState = m_pState;
if (m_pState)
{
(*ppunkState)->AddRef();
}
return S_OK;
}
STDMETHODIMP GetStatus( void)
{
return hrStatusResult;
}
STDMETHODIMP STDMETHODCALLTYPE SetStatus(HRESULT hrStatus)
{
hrStatusResult = hrStatus;
return S_OK;
}
STDMETHODIMP GetObject(IUnknown **ppObject)
{
if (ppObject == NULL)
{
return E_POINTER;
}
*ppObject = m_pObject;
if (m_pObject)
{
(*ppObject)->AddRef();
}
return S_OK;
}
IUnknown* STDMETHODCALLTYPE GetStateNoAddRef()
{
return m_pState; // Warning! Can be NULL.
}
};
Související témata