Vlastní zavaděče topologie
Když aplikace zařadí částečnou topologii do fronty v relaci médií, použije relace médií k vyřešení topologie zavaděč topologie. Relace médií ve výchozím nastavení používá standardní implementaci zavaděče topologie Media Foundation, ale můžete také poskytnout vlastní implementaci. Tím získáte větší kontrolu nad konečnou topologií. Vlastní zavaděč topologie musí implementovat rozhraní DATACENTERTopoLoader.
Pokud chcete nastavit vlastní zavaděč topologie v relaci médií, postupujte takto:
- Vytvořte prázdné úložiště atributů voláním MFCreateAttributes.
- Nastavte atribut MF_SESSION_TOPOLOADER v úložišti atributů. Hodnota atributu je CLSID vašeho vlastního zavaděče.
- Volání MFCreateMediaSession vytvořit relaci média pro nechráněný obsah, nebo MFCreatePMPMediaSession vytvořit relaci médií uvnitř chráněné cesty média (PMP).
Poznámka
Pokud chcete použít vlastní zavaděč topologie uvnitř pmP, musí být zavaděč topologie důvěryhodnou komponentou. Další informace naleznete v tématu Chráněná cesta média.
Následující kód ukazuje, jak nastavit vlastní zavaděč topologie v relaci médií.
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;
}
V zavaděčí topologie není nutné implementovat celý algoritmus načítání topologie. Jako alternativu můžete zabalit standardní zavaděč topologie Media Foundation. Při implementaci metody DATACENTERTopoLoader::Load upravte topologii podle potřeby a předejte upravenou topologii do standardního zavaděče topologie. Poté standardní zavaděč topologie dokončí topologii. Dokončenou topologii můžete upravit také před jejím předáním zpět do relace médií.
Následující kód ukazuje obecný přehled tohoto přístupu. Nezobrazuje žádné podrobnosti o metodě Load, protože to bude záviset na konkrétních požadavcích vaší aplikace.
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.
};
Související témata