DirectShow系统设备的枚举

 
  1. 步骤:

  2. 1.使用CoCreateInstance函数创建系统枚举器组件对象,并获得ICreateDevEnum接口;

  3. 2.使用接口方法ICreateDevEnum::CreateClassEnumerator为指定的Filter注册类型目录创建一个枚举器,并获得

  4. IEnumMoniker接口;

  5. 3.使用IEnumMoniker接口方法枚举指定类型目录下所有设备标识

  6. 4.调用IMoniker::BindToStorage之后,可以访问设备标识的属性集,比如得到Display Name,Friendly Name等;

  7. 5.调用IMoniker::BindToOject可以将设备标识生成一个DirectShow Filter,随后调用IFilterGraph::AddFilter,

  8. 并将之加入到FilterGraph中就可以参与工作了.

  9. 下面是实现这个过程的代码:

  10. //创建一个系统枚举组件

  11. HRESULT hr;

  12. ICreateDevEnum *pSysDevEnum=NULL;

  13. hr=CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER,IID_ICreateDevEnum,(void**)&pSysDevEnum);

  14. if(FAILED(hr))

  15. {

  16.  retuen hr;

  17. }

  18. //指定枚举的类型录,获得IEnumMoniker接口

  19. IEnumMoniker *pEnumCat=NULL;

  20. hr=pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEnumCat,0);

  21. if(hr==S_OK)

  22. {

  23.  //使用IEnumMoniker接口枚举所有的设备标识

  24.  IMoniker *pMoniker=NULL;

  25.  ULONG cFetched;

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

  27.  {

  28.   IPropertyBag *pPropBag;

  29.   hr=pMoniker->BindToStorage(0,0,IID_IPropertyBag,(void**)&pPropBag);

  30.   if(SUCCEEDED(hr))

  31.   {

  32.    //获得Filter的Friendly Name

  33.    VARIANT varName;

  34.    VariantInit(&varName);

  35.    hr=pPropBag->Read(L"FriendlyName",&varName,0);

  36.    if(SUCCEEDED(hr))

  37.    {

  38.    }

  39.    VariantClear(&varName);

  40.    //创建Filter实例

  41.    IBaseFilter *pFilater;

  42.    hr=pMoniker->BindToObject(NULL,NULL,IID_IBaseFilter,(void**)&pFilter);

  43.    pPropBag->Release();

  44.   }

  45.   pMoniker->Release();

  46.  }

  47.  pEnumCat->Release();

  48. }

  49. pSysDevEnum->Release();

  50.  
  51. 知道了一个硬件的设备标识,我们也可以直接通过IFilterGraph2::AddSourceFilterForMoniker接口方法来

  52. 创建Filter,代码如下:

  53. LPOLESTR strName=NULL;

  54. IBaseFilter pSrc=NULL;

  55. hr=pMoniker->GetDisplayName(NULL,NULL,&strName);

  56. if(SUCCEEDED(hr))

  57. {

  58.  //获得IFilterGraph2接口

  59.  IFilterGraph2 *pFG2=NULL;

  60.  hr=pGraph->QueryInterface(IID_IFilterGraph2,(void**)&pFG2);

  61.  if(SUCCEEDED(hr))

  62.  {

  63.   //根据设备标识创建一个Source Filter

  64.   hr=pFG2->AddSourceFilterForMoniker(pMoniker,0,L"Source",&pSrc);

  65.   pFG2->Release();

  66.  }

  67.  CoTaskMemFree(strName);

  68. }

  69. 或者给定一个Filter类型目录的Display Name描述,创建一个该类型目录下第一个返回的设备标识对象.

  70. //视频采集设备的类型目录

  71. WCHAR szMon[]=L"@device:*:{86DBB310-5D01-11D0-BD3B-00A0C911CE86}";

  72. IBindCtx *pBindCtx;

  73. hr=CreateBindCtx(0,&pBindCtx);

  74. ULONG chEaten=0;

  75. IMoniker *pMoniker=0;

  76. hr=MkParseDisplayName(pBindCtx,szMon,&chEaten,&pMoniker);

  77. pBindCtx->Release();

  78. if(SUCCEEDED(hr))

  79. {

  80.  pMoniker->Release();

  81. }

 

//指定视频采集设备的友好名字,为它创建一个Filter IBaseFilter * CTestPreviewDlg::CreateVideoDevice(const char * inFriendlyName) { return CreateHardwareFilter(CLSID_VideoInputDeviceCategory,inFriendlyName); } //根据设备的友好名字,创建一个代表该设备的Filter IBaseFilter * CTestPreviewDlg::CreateHardwareFilter(GUID inCategory,const char * inFriendlyName) { //创建一个系统枚举组件对象 ICreateDevEnum * enumHardware = NULL; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_ALL, IID_ICreateDevEnum,(void**)&enumHardware); if(FAILED(hr)) { return NULL; } IBaseFilter * hardwareFilter = NULL; IEnumMoniker * enumMoniker = NULL; //为指定的目录创建枚举器 hr = enumHardware->CreateClassEnumerator(inCategory,&enumMoniker,0); if(enumMoniker) { enumMoniker->Reset(); ULONG fetched = 0; IMoniker * moniker = NULL; char friendlyName[256]; //枚举得到该目录下所有的设备,逐个进行名字匹配 while(!hardwareFilter && SUCCEEDED(enumMoniker->Next(1,&moniker, &fetched)) && fetched) { if(moniker) { IPropertyBag * propertyBag = NULL; VARIANT name; friendlyName[0] = 0; hr = moniker->BindToStorage(0,0,IID_IPropertyBag,(void**)&propertyBag); //读取设备的友好名字 if(SUCCEEDED(hr)) { name.vt = VT_BSTR; hr = propertyBag->Read(L"Friendlyname",&name,NULL); } if(SUCCEEDED(hr)) { WideCharToMultiByte(CP_ACP,0,name.bstrVal,-1, friendlyName,256,NULL,NULL); //如果当前设备的友好名字与用户指定的设备名字相同, //则将当前设备标识绑定为Filter形式 if(strcmp(friendlyName,inFriendlyName) == 0) { moniker->BindToObject(0,0,IID_IBaseFilter, (void**)&hardwareFilter); } } //释放使用过的接口 if(propertyBag) { propertyBag->Release(); propertyBag = NULL; } moniker->Release(); } } enumMoniker->Release(); } enumHardware->Release(); return hardwareFilter; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值