Chargeurs de topologie personnalisés
Lorsqu’une application met en file d’attente une topologie partielle sur la session multimédia, la session multimédia utilise un chargeur de topologie pour résoudre la topologie. Par défaut, media session utilise l’implémentation Media Foundation standard du chargeur de topologie, mais vous pouvez également fournir une implémentation personnalisée. Cela vous donne plus de contrôle sur la topologie finale. Un chargeur de topologie personnalisé doit implémenter l’interface IMFTopoLoader .
Pour définir un chargeur de topologie personnalisé sur la session multimédia, procédez comme suit :
- Créez un magasin d’attributs vide en appelant MFCreateAttributes.
- Définissez l’attribut MF_SESSION_TOPOLOADER sur le magasin d’attributs. La valeur de l’attribut est le CLSID de votre chargeur personnalisé.
- Appelez MFCreateMediaSession pour créer la session multimédia pour le contenu non protégé, ou MFCreatePMPMediaSession pour créer la session multimédia à l’intérieur du chemin d’accès multimédia protégé (PMP).
Notes
Pour utiliser un chargeur de topologie personnalisé à l’intérieur du PMP, le chargeur de topologie doit être un composant approuvé. Pour plus d’informations, consultez Chemin du média protégé.
Le code suivant montre comment définir un chargeur de topologie personnalisé sur la session multimédia.
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;
}
Il n’est pas nécessaire d’implémenter l’algorithme de chargement de topologie dans votre chargeur de topologie. Vous pouvez également encapsuler le chargeur de topologie Media Foundation standard. Dans votre implémentation de la méthode IMFTopoLoader::Load , modifiez la topologie en fonction des besoins et transmettez la topologie modifiée au chargeur de topologie standard. Ensuite, le chargeur de topologie standard termine la topologie. Vous pouvez également modifier la topologie terminée avant de la transmettre à la session multimédia.
Le code suivant présente la structure générale de cette approche. Il n’affiche aucun détail de la méthode Load , car ceux-ci dépendent des exigences particulières de votre application.
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.
};
Rubriques connexes