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演示如何获取音视设备。这里只是
明了获取设备的方法。以备了解。