Media Foundation a COM
Microsoft Media Foundation používá kombinaci konstruktorů MODELU COM, ale není plně rozhraní API založené na modelu COM. Toto téma popisuje interakci mezi com a Media Foundation. Definuje také některé osvědčené postupy pro vývoj komponent modulu plug-in Media Foundation. Následující postupy vám můžou pomoct vyhnout se některým běžným, ale drobným chybám programování.
- osvědčené postupy pro aplikací
- osvědčené postupy pro komponenty Media Foundation
- souhrnu
- související témata
Osvědčené postupy pro aplikace
Ve službě Media Foundation se asynchronní zpracování a zpětná volání zpracovávají pracovní fronty. Pracovní fronty mají vždy vícevláknová vlákna (MTA), takže aplikace bude mít jednodušší implementaci, pokud běží i ve vlákně MTA. Proto se doporučuje volat CoInitializeEx příznakem COINIT_MULTITHREADED.
Media Foundation nezařadí objekty jednovláknového objektu (STA) do pracovních vláken fronty. Nezajistí ani zachování invariantů STA. Aplikace STA proto musí být opatrní, aby nepředávejte objekty STA nebo proxy rozhraní API media Foundation. Objekty, které jsou pouze STA, nejsou podporovány v Media Foundation.
Pokud máte proxy serveru STA pro MTA nebo objekt s volným vláknem, je možné tento objekt zařabit do proxy serveru MTA pomocí zpětného volání pracovní fronty. Funkce CoCreateInstance může v závislosti na objektovém modelu definovaném v registru pro tento identifikátor CLSID vrátit nezpracovaný ukazatel nebo proxy sta. Pokud se vrátí proxy sta, nesmíte předat ukazatel do rozhraní MEDIA Foundation API.
Předpokládejme například, že chcete předat IPropertyStore ukazatel na MMFSourceResolver::BeginCreateObjectFromURL metoda. Můžete zavolat PSCreateMemoryPropertyStore vytvořit ukazatel IPropertyStore. Pokud voláte ze sta, musíte před předáním ukazatele do BeginCreateObjectFromURL.
Následující kód ukazuje, jak zařazovací proxy server STA do rozhraní MEDIA Foundation API.
class CCreateSourceMarshalCallback
: public IMFAsyncCallback
{
public:
CCreateSourceMarshalCallback(
LPCWSTR szURL,
IMFSourceResolver* pResolver,
IPropertyStore* pSourceProps,
IMFAsyncCallback* pCompletionCallback,
HRESULT& hr
)
: m_szURL(szURL),
m_pResolver(pResolver),
m_pCompletionCallback(pCompletionCallback),
m_pGIT(NULL),
m_cRef(1)
{
hr = CoCreateInstance(CLSID_StdGlobalInterfaceTable, NULL,
CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&m_pGIT));
if(SUCCEEDED(hr))
{
hr = m_pGIT->RegisterInterfaceInGlobal(
pSourceProps, IID_IPropertyStore, &m_dwInterfaceCookie);
}
}
~CCreateSourceMarshalCallback()
{
SafeRelease(&m_pResolver);
SafeRelease(&m_pCompletionCallback);
SafeRelease(&m_pGIT);
}
STDMETHOD_(ULONG, AddRef)()
{
return InterlockedIncrement(&m_cRef);
}
STDMETHOD_(ULONG, Release)()
{
LONG cRef = InterlockedDecrement(&m_cRef);
if (0 == cRef)
{
delete this;
}
return cRef;
}
STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppvObject)
{
static const QITAB qit[] =
{
QITABENT(CCreateSourceMarshalCallback, IMFAsyncCallback),
{ 0 }
};
return QISearch(this, qit, riid, ppvObject);
}
STDMETHOD(GetParameters)(DWORD* pdwFlags, DWORD* pdwQueue)
{
return E_NOTIMPL;
}
STDMETHOD(Invoke)(IMFAsyncResult* pResult)
{
IPropertyStore *pSourceProps = NULL;
HRESULT hr = m_pGIT->GetInterfaceFromGlobal(
m_dwInterfaceCookie,
IID_PPV_ARGS(&pSourceProps)
);
if(SUCCEEDED(hr))
{
hr = m_pResolver->BeginCreateObjectFromURL(
m_szURL, MF_RESOLUTION_MEDIASOURCE, pSourceProps, NULL,
m_pCompletionCallback, NULL);
}
SafeRelease(&pSourceProps);
return hr;
}
private:
LPCWSTR m_szURL;
IMFSourceResolver *m_pResolver;
IMFAsyncCallback *m_pCompletionCallback;
IGlobalInterfaceTable *m_pGIT;
DWORD m_dwInterfaceCookie;
LONG m_cRef;
};
Další informace o tabulce globálního rozhraní naleznete v tématu IGlobalInterfaceTable.
Pokud používáte Media Foundation v procesu, objekty vrácené z metod Media Foundation a funkce jsou přímými ukazateli na objekt. V případě multiprocesového media Foundation mohou být tyto objekty proxy servery MTA a měly by být v případě potřeby zařazovány do vlákna STA. Podobně jsou objekty získané uvnitř zpětného volání – například topologie z MESessionTopologyStatus událostí – přímými ukazateli při použití Media Foundation v procesu, ale jsou proxy servery MTA při použití media Foundation napříč procesy.
Poznámka
Nejběžnějším scénářem použití křížového procesu Media Foundation je cesta k chráněnému médiu (PMP). Tyto poznámky se však vztahují na všechny situace, kdy se rozhraní MEDIA Foundation API používají prostřednictvím RPC.
Všechny implementace MMFAsyncCallback by měly být kompatibilní s MTA. Tyto objekty nemusí být vůbec objekty MODELU COM. Ale pokud ano, nemůžou běžet ve sta. Funkce MMFAsyncCallback::Invoke bude vyvolána ve vlákně workqueue MTA a poskytnutá MMFAsyncResult objekt bude buď přímý ukazatel objektu, nebo proxy MTA.
Osvědčené postupy pro komponenty Media Foundation
Existují dvě kategorie objektů Media Foundation, které se musí zabývat com. Některé komponenty, jako jsou transformace nebo obslužné rutiny bajtů datového proudu, jsou úplné objekty MODELU COM vytvořené pomocí CLSID. Tyto objekty musí dodržovat pravidla pro objekty COM, a to jak v procesu, tak i pro multiprocesové Media Foundation. Další komponenty Media Foundation nejsou úplné objekty MODELU COM, ale potřebují proxy com pro přehrávání mezi procesy. Objekty v této kategorii zahrnují zdroje médií a aktivační objekt. Tyto objekty mohou ignorovat problémy s apartmány, pokud se použijí pouze pro in-process Media Foundation.
I když nejsou všechny objekty Media Foundation objekty COM objekty, všechna rozhraní Media Foundation jsou odvozena z IUnknown. Proto všechny objekty Media Foundation musí implementovat IUnknown podle specifikací MODELU COM, včetně pravidel pro počítání odkazů a QueryInterface. Všechny počítané objekty odkazů by také měly zajistit, aby DllCanUnloadNow nepovolil uvolnění modulu, zatímco objekty stále přetrvávají.
Komponenty Media Foundation nemohou být objekty STA. Mnoho objektů Media Foundation nemusí být vůbec objekty MODELU COM. Ale pokud ano, nemůžou běžet ve sta. Všechny komponenty Media Foundation musí být bezpečné pro přístup z více vláken. Některé objekty Media Foundation musí být také bezvláknové nebo neutrální. Následující tabulka určuje požadavky pro vlastní implementace rozhraní:
Rozhraní | Kategorie | Požadovaný byt |
---|---|---|
MMFActivate | Proxy mezi procesy | Bezvláknové nebo neutrální |
MMFByteStreamHandler | Objekt COM | MTA |
MMFContentProtectionManager | Proxy mezi procesy | Bezvláknové nebo neutrální |
MMFQualityManager | Objekt COM | Bezvláknové nebo neutrální |
MMFMediaSource | Proxy mezi procesy | Bezvláknové nebo neutrální |
MMFSchemeHandler | Objekt COM | MTA |
MMFTopoLoader | Objekt COM | Bezvláknové nebo neutrální |
MMFTransform | Objekt COM | MTA |
V závislosti na implementaci můžou existovat další požadavky. Pokud například jímka médií implementuje jiné rozhraní, které aplikaci umožňuje provádět přímé volání funkce jímky, musí být jímka bez vláken nebo neutrální, aby mohla zpracovávat přímé volání mezi procesy. Jakýkoli objekt může být bez vláken; tato tabulka určuje minimální požadavky.
Doporučený způsob implementace bezvláknových nebo neutrálních objektů je agregace bezvláknového zařazovače. Další podrobnosti naleznete v CoCreateFreeThreadedMarshaler. V souladu s požadavkem nepředávejte objekty STA ani proxy rozhraní API služby Media Foundation, bezvláknové objekty se nemusí starat o zařazování vstupních ukazatelů STA ve součástech s volným vláknem.
Komponenty, které používají dlouhou pracovní frontu (MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION), musí věnovat větší péči. Vlákna v dlouhé funkci workqueue vytvářejí vlastní STA. Součásti, které používají dlouhou funkci workqueue pro zpětné volání, by se měly vyhnout vytváření objektů MODELU COM na těchto vláknech a musí být opatrní při zařazování proxy serverů na STA podle potřeby.
Shrnutí
Aplikace budou mít jednodušší čas, pokud pracují se službou Media Foundation z vlákna MTA, ale je možné s určitou opatrností použít Media Foundation z vlákna STA. Media Foundation nezpracuje komponenty STA a aplikace by měly být opatrní, aby nepředály objekty STA do rozhraní API služby Media Foundation. Některé objekty mají další požadavky, zejména objekty, které běží v situaci mezi procesy. Následující pokyny vám pomůžou vyhnout se chybám modelu COM, zablokováním a neočekávaným zpožděním při zpracování médií.
Související témata
-
architektury Media Foundation