自訂拓撲載入器
當應用程式將媒體會話上的部分拓撲排入佇列時,媒體會話會使用拓撲載入器來解析拓撲。 根據預設,媒體會話會使用拓撲載入器的標準媒體基礎實作,但您也可以提供自訂實作。 這可讓您更充分掌控最終拓撲。 自訂拓撲載入器必須實作 IMFTopoLoader 介面。
若要在媒體會話上設定自訂拓撲載入器,請執行下列動作:
- 呼叫 MFCreateAttributes來建立空的屬性存放區。
- 在屬性存放區上設定 MF_SESSION_TOPOLOADER 屬性。 屬性的值是自訂載入器的 CLSID。
- 呼叫 MFCreateMediaSession 以建立未受保護的內容的媒體會話,或 MFCreatePMPMediaSession 在受保護的媒體路徑內建立媒體會話, (PMP) 。
注意
若要在 PMP 內使用自訂拓撲載入器,拓撲載入器必須是受信任的元件。 如需詳細資訊,請參閱 受保護的媒體路徑。
下列程式碼示範如何在媒體會話上設定自訂拓撲載入器。
HRESULT CreateSession_CustomTopoLoader(REFCLSID clsid, IMFMediaSession **ppSession)
{
*ppSession = NULL;
IMFMediaSession *pSession = NULL;
IMFAttributes *pConfig = NULL;
// Create an attribute store to configure the media session.
HRESULT hr = MFCreateAttributes(&pConfig, 1);
// Set the CLSID of the custom topology loader.
if (SUCCEEDED(hr))
{
hr = pConfig->SetGUID(MF_SESSION_TOPOLOADER, clsid);
}
// Create the media session.
if (SUCCEEDED(hr))
{
hr = MFCreateMediaSession(pConfig, &pSession);
}
// Return the pointer to the caller.
if (SUCCEEDED(hr))
{
*ppSession = pSession;
(*ppSession)->AddRef();
}
SafeRelease(&pSession);
SafeRelease(&pConfig);
return hr;
}
您不需要在拓撲載入器中實作整個拓撲載入演算法。 或者,您可以包裝標準媒體基礎拓撲載入器。 在 IMFTopoLoader::Load 方法的實作中,視需要修改拓撲,並將修改過的拓撲傳遞至標準拓撲載入器。 然後,標準拓撲載入器會完成拓撲。 您也可以先修改已完成的拓撲,再將它傳回媒體會話。
下列程式碼顯示此方法的一般大綱。 它不會顯示 Load 方法的任何詳細資料,因為這些詳細資料將取決於應用程式的特定需求。
class CTopoLoader : public IMFTopoLoader
{
public:
static HRESULT CreateInstance(REFIID iid, void **ppv)
{
HRESULT hr = S_OK;
CTopoLoader *pTopoLoader = new (std::nothrow) CTopoLoader(&hr);
if (pTopoLoader == NULL)
{
return E_OUTOFMEMORY;
}
if (SUCCEEDED(hr))
{
hr = pTopoLoader->QueryInterface(iid, ppv);
}
SafeRelease(&pTopoLoader);
return hr;
}
// IUnknown methods.
STDMETHODIMP QueryInterface(REFIID riid, void** ppv)
{
static const QITAB qit[] =
{
QITABENT(CTopoLoader, IMFTopoLoader),
{ 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;
}
// IMTopoLoader methods.
STDMETHODIMP Load(
IMFTopology *pInput,
IMFTopology **ppOutput,
IMFTopology *pCurrent
)
{
HRESULT hr = S_OK;
// TODO: Add custom topology-building code here.
// Modify pInput as needed.
if (SUCCEEDED(hr))
{
hr = m_pTopoLoader->Load(pInput, ppOutput, pCurrent);
}
// TODO: Add custom topology-building code here.
// Modify ppOutput as needed.
return hr;
}
private:
CTopoLoader(HRESULT *phr) : m_cRef(1), m_pTopoLoader(NULL)
{
*phr = MFCreateTopoLoader(&m_pTopoLoader);
}
virtual ~CTopoLoader()
{
SafeRelease(&m_pTopoLoader);
}
private:
long m_cRef; // Reference count.
IMFTopoLoader *m_pTopoLoader; // Standard topoloader.
};
相關主題