DirectShow系统设备的枚举

步骤:
1.使用CoCreateInstance函数创建系统枚举器组件对象,并获得ICreateDevEnum接口;
2.使用接口方法ICreateDevEnum::CreateClassEnumerator为指定的Filter注册类型目录创建一个枚举器,并获得
IEnumMoniker接口;
3.使用IEnumMoniker接口方法枚举指定类型目录下所有设备标识
4.调用IMoniker::BindToStorage之后,可以访问设备标识的属性集,比如得到Display Name,Friendly Name等;
5.调用IMoniker::BindToOject可以将设备标识生成一个DirectShow Filter,随后调用IFilterGraph::AddFilter,
并将之加入到FilterGraph中就可以参与工作了.
下面是实现这个过程的代码:
//创建一个系统枚举组件
HRESULT hr;
ICreateDevEnum *pSysDevEnum=NULL;
hr=CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER,IID_ICreateDevEnum,(void**)&pSysDevEnum);
if(FAILED(hr))
{
 retuen hr;
}
//指定枚举的类型录,获得IEnumMoniker接口
IEnumMoniker *pEnumCat=NULL;
hr=pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEnumCat,0);
if(hr==S_OK)
{
 //使用IEnumMoniker接口枚举所有的设备标识
 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))
  {
   //获得Filter的Friendly Name
   VARIANT varName;
   VariantInit(&varName);
   hr=pPropBag->Read(L"FriendlyName",&varName,0);
   if(SUCCEEDED(hr))
   {
   }
   VariantClear(&varName);
   //创建Filter实例
   IBaseFilter *pFilater;
   hr=pMoniker->BindToObject(NULL,NULL,IID_IBaseFilter,(void**)&pFilter);
   pPropBag->Release();
  }
  pMoniker->Release();
 }
 pEnumCat->Release();
}
pSysDevEnum->Release();

知道了一个硬件的设备标识,我们也可以直接通过IFilterGraph2::AddSourceFilterForMoniker接口方法来
创建Filter,代码如下:
LPOLESTR strName=NULL;
IBaseFilter pSrc=NULL;
hr=pMoniker->GetDisplayName(NULL,NULL,&strName);
if(SUCCEEDED(hr))
{
 //获得IFilterGraph2接口
 IFilterGraph2 *pFG2=NULL;
 hr=pGraph->QueryInterface(IID_IFilterGraph2,(void**)&pFG2);
 if(SUCCEEDED(hr))
 {
  //根据设备标识创建一个Source Filter
  hr=pFG2->AddSourceFilterForMoniker(pMoniker,0,L"Source",&pSrc);
  pFG2->Release();
 }
 CoTaskMemFree(strName);
}
或者给定一个Filter类型目录的Display Name描述,创建一个该类型目录下第一个返回的设备标识对象.
//视频采集设备的类型目录
WCHAR szMon[]=L"@device:*:{86DBB310-5D01-11D0-BD3B-00A0C911CE86}";
IBindCtx *pBindCtx;
hr=CreateBindCtx(0,&pBindCtx);
ULONG chEaten=0;
IMoniker *pMoniker=0;
hr=MkParseDisplayName(pBindCtx,szMon,&chEaten,&pMoniker);
pBindCtx->Release();
if(SUCCEEDED(hr))
{
 pMoniker->Release();
}


 

你可能感兴趣的:(DirectShow系统设备的枚举)