Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
[Funkcja skojarzona z tą stroną, DirectShow, jest starszą funkcją. Został zastąpiony przez MediaPlayer, IMFMediaEnginei Audio/Video Capture w Media Foundation. Te funkcje zostały zoptymalizowane pod kątem systemów Windows 10 i Windows 11. Firma Microsoft zdecydowanie zaleca, aby nowy kod używał MediaPlayer, IMFMediaEngine i Audio/Video Capture w ramach Media Foundation zamiast DirectShow, jeśli to możliwe. Firma Microsoft sugeruje, że istniejący kod, który używa starszych interfejsów API, należy przepisać go do korzystania z nowych interfejsów API, jeśli to możliwe.]
Niektórych filtrów trybu jądra nie można utworzyć za pomocą CoCreateInstance, a tym samym nie mają identyfikatorów CLSID. Te filtry obejmują Tee/Sink-to-Sink Converter, filtr CC Decoder oraz filtr Koder WST. Aby utworzyć jeden z tych filtrów, użyj modułu wyliczającego urządzenia systemowego i wyszukaj filtr po nazwie.
- Utwórz enumerator urządzeń systemowych.
- Wywołaj metodę ICreateDevEnum::CreateClassEnumerator za pomocą identyfikatora CLSID kategorii filtru dla tego filtru. Ta metoda tworzy moduł wyliczający dla kategorii filtru. (Moduł wyliczający to po prostu obiekt, który zwraca listę innych obiektów przy użyciu zdefiniowanego interfejsu COM). Moduł wyliczający zwraca wskaźniki IMoniker, które reprezentują filtry w tej kategorii.
- Dla każdego monikera wywołaj IMoniker::BindToStorage, aby uzyskać interfejs IPropertyBag.
- Wywołaj IPropertyBag::Read, aby uzyskać nazwę filtru.
- Jeśli nazwa jest zgodna, wywołaj IMoniker::BindToObject, aby utworzyć filtr.
Poniższy kod przedstawia funkcję wykonującą następujące kroki:
HRESULT CreateKernelFilter(
const GUID &guidCategory, // Filter category.
LPCOLESTR szName, // The name of the filter.
IBaseFilter **ppFilter // Receives a pointer to the filter.
)
{
HRESULT hr;
ICreateDevEnum *pDevEnum = NULL;
IEnumMoniker *pEnum = NULL;
if (!szName || !ppFilter)
{
return E_POINTER;
}
// Create the system device enumerator.
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
IID_ICreateDevEnum, (void**)&pDevEnum);
if (FAILED(hr))
{
return hr;
}
// Create a class enumerator for the specified category.
hr = pDevEnum->CreateClassEnumerator(guidCategory, &pEnum, 0);
pDevEnum->Release();
if (hr != S_OK) // S_FALSE means the category is empty.
{
return E_FAIL;
}
// Enumerate devices within this category.
bool bFound = false;
IMoniker *pMoniker;
while (!bFound && (S_OK == pEnum->Next(1, &pMoniker, 0)))
{
IPropertyBag *pBag = NULL;
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
if (FAILED(hr))
{
pMoniker->Release();
continue; // Maybe the next one will work.
}
// Check the friendly name.
VARIANT var;
VariantInit(&var);
hr = pBag->Read(L"FriendlyName", &var, NULL);
if (SUCCEEDED(hr) && (lstrcmpiW(var.bstrVal, szName) == 0))
{
// This is the right filter.
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter,
(void**)ppFilter);
bFound = true;
}
VariantClear(&var);
pBag->Release();
pMoniker->Release();
}
pEnum->Release();
return (bFound ? hr : E_FAIL);
}
Poniższy przykład kodu używa tej funkcji do utworzenia filtru dekodera CC i dodania go do wykresu filtru:
IBaseFilter *pCC = NULL;
hr = CreateKernelFilter(AM_KSCATEGORY_VBICODEC,
OLESTR("CC Decoder"), &pCC);
if (SUCCEEDED(hr))
{
hr = pGraph->AddFilter(pCC, L"CC Decoder");
pCC->Release();
}
Tematy pokrewne