Niestandardowe moduły ładujących topologię
Gdy aplikacja kolejkuje częściową topologię w sesji multimediów, sesja multimediów używa modułu ładującego topologii w celu rozwiązania topologii. Domyślnie sesja multimediów używa standardowej implementacji programu Media Foundation modułu ładującego topologii, ale można również zapewnić niestandardową implementację. Zapewnia to większą kontrolę nad ostateczną topologią. Niestandardowy moduł ładujący topologii musi zaimplementować interfejs IMFTopoLoader.
Aby ustawić niestandardowy moduł ładujący topologii w sesji multimediów, wykonaj następujące czynności:
- Utwórz pusty magazyn atrybutów, wywołując MFCreateAttributes.
- Ustaw atrybut MF_SESSION_TOPOLOADER w magazynie atrybutów. Wartość atrybutu to CLSID modułu ładującego niestandardowego.
- Wywołaj MFCreateMediaSession, aby utworzyć sesję multimediów dla niechronionej zawartości lub MFCreatePMPMediaSession, aby utworzyć sesję multimediów wewnątrz ścieżki chronionego nośnika (PMP).
Nuta
Aby użyć niestandardowego modułu ładującego topologii wewnątrz PMP, moduł ładujący topologii musi być zaufanym składnikiem. Aby uzyskać więcej informacji, zobacz Ścieżka chronionego nośnika.
Poniższy kod pokazuje, jak ustawić niestandardowy moduł ładujący topologii w sesji multimediów.
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;
}
Nie jest konieczne zaimplementowanie całego algorytmu ładowania topologii w module ładujący topologii. Alternatywnie można opakowować standardowy moduł ładujący topologii programu Media Foundation. W implementacji metody IMFTopoLoader::Load zmodyfikuj topologię zgodnie z potrzebami i przekaż zmodyfikowaną topologię do standardowego modułu ładującego topologii. Następnie standardowy moduł ładujący topologii kończy topologię. Można również zmodyfikować ukończoną topologię przed przekazaniem jej z powrotem do sesji multimediów.
Poniższy kod przedstawia ogólny zarys tego podejścia. Nie zawiera żadnych szczegółów metody Load, ponieważ będą one zależeć od konkretnych wymagań aplikacji.
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.
};
Tematy pokrewne