1.采用系統設備枚舉器來枚舉.
根據硬件系統種類來枚舉系統中注冊的filter。
每一種不同的硬件可能有自己的filter,也可能所有的硬件設備共用filter。
系統設備枚舉器是根據不同的種類來創建的,如,音頻壓縮,視頻捕捉。
不同種類的枚舉器對于每一種設備返回一個獨立的名稱(moniker)。
下面的步驟是使用設備枚舉器來獲取設備:
1) 創建枚舉器組件,CLSID為CLSID_SystemDeviceEnum
2) 指定某一種類型設備,獲取該種類枚舉器
通過ICreateDevEnum::CreateClassEnumerator獲取某一種類的枚舉器,
該函數返回一個IEnumMoniker接口指針,
通過檢查返回值是否為S_OK來判斷是否獲取到該種類枚舉器.
3) 用IEnumMoniker::Next枚舉每一個moniker。
這個方法返回一個IMoniker接口指針。
4) 通過IMoniker::BindToStorage獲取設備的名稱
大致例子如下:
HRESULT hr;
ICreateDevEnum *pSysDevEnum = NULL;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void **)&pSysDevEnum);
if (FAILED(hr)) return hr;

//獲取video compressor 種類枚舉器
IEnumMoniker *pEnumCat = NULL;
hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory, &pEnumCat,0);

if (hr == S_OK)
{

IMoniker *pMoniker = NULL;
ULONG cFetched;


while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
{

IPropertyBag *pPropBag;
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);
if (SUCCEEDED(hr))

{
// 獲取設備名稱
VARIANT varName;
VariantInit(&varName);
hr = pPropBag->Read(L"FriendlyName", &varName, 0);

if (SUCCEEDED(hr))
{
//獲取設備名稱
}
VariantClear(&varName);
}
pMoniker->Release();
}
pEnumCat->Release();
}
pSysDevEnum->Release();


2.采用Filer Mapper。
類似條件查詢。
比系統設備枚舉器(System Device Enumerator)的效率要低一些。
當要枚舉某特定種類的filter時,應采用系統設備枚舉器方法,但搜索支持某種
媒體類型的filter時,用filter mapper.
Filter Mapper 通過IFilerMapper2接口搜索接口,
通過調用IFilterMapper2::EnumMatchingFilters方法,傳遞一些參數來定義搜索條件,
返回一個適合條件的filter的枚舉器,
返回的是一個IEnumMoniker接口,并對于每個適合的filter都提供一個單獨的moniker。
例子:
//枚舉所有的支持DV,并且至少有一個輸出pin的filter,
//這個filter支持任何媒體類型。
IFilterMapper2 *pMapper = NULL;
IEnumMoniker *pEnum = NULL;

hr =CoCreateInstance( CLSID_FilterMapper2,NULL, CLSCTX_INPROC, IID_IFilterMapper2, (void **) &pMapper);

if (FAILED(hr))
{ }

GUID arrayInTypes[2];
arrayInTypes[0] = MEDIATYPE_Video;
arrayInTypes[1] = MEDIASUBTYPE_dvsd;
hr = pMapper->EnumMatchingFilters(
&pEnum,
0, // Reserved.
TRUE, // Use exact match?
MERIT_DO_NOT_USE+1, // Minimum merit.
TRUE, // At least one input pin?
1, // Number of major type/subtype pairs for input.
arrayInTypes, // Array of major type/subtype pairs for input.
NULL, // Input medium.
NULL, // Input pin category.
FALSE, // Must be a renderer?
TRUE, // At least one output pin?
0, // Number of major type/subtype pairs for output.
NULL, // Array of major type/subtype pairs for output.
NULL, // Output medium.
NULL); // Output pin category.
IMoniker *pMoniker;
ULONG cFetched;

//枚舉filter,
while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)


{
IPropertyBag *pPropBag = NULL;
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);
if (SUCCEEDED(hr))

{
VARIANT varName;
VariantInit(&varName);
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
if (SUCCEEDED(hr))

{
//處理
}
VariantClear(&varName);
}
pMoniker->Release();
}

pMapper->Release();
pEnum->Release();

注:
* 有關directshow的api函數,估計只能在網上搜索,至于下載的msdn沒有,或者下個dssdk2002版本的help才能有。
* 在directshow中,關于capture dev,有專門的demo演示如何獲取音視設備。這里只是
明了獲取設備的方法。以備了解。