您当前的位置: 首页 > 

鱼儿-1226

暂无认证

  • 0浏览

    0关注

    1100博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

DirectShow 方式列举和捕捉设备接口

鱼儿-1226 发布时间:2020-08-12 10:23:16 ,浏览量:0

列举视频设备:

1、建立系统硬件设备的列表首先,申明一个列表指针,然后通过 CoCreateInstance 建立。CLSID_SystemDeviceEnum是我们想建立对象的类型,IID_ICreateDevEnum是接口的GUID。

 

 
  1. ICreateDevEnum *pCreateDevEnum;

  2. CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pCreateDevEnum);

        CoCreateInstance 函数用来创建一个Com对象:

 

        第一个参数用来创建的Com对象的类标识符(CLSID),CLSID是指windows系统对于不同的应用程序,文件类型,OLE对象,特殊文件夹以及各种系统组件分配一个唯一表示它的ID代码,用于对其身份的标示和与其他对象进行区分。先得说下GUID,它是Globally Unique Identifier的简称,中文翻译为“全局唯一标示符”,在Windows系统中也称之为Class ID,缩写为CLSID。

        第二个参数,如果为NULL,,表明此对象不是聚合式对象一部分。如果不是NULL, 则指针指向一个聚合式对象的IUnknown接口。

        第三个参数,组件类别.,可使用CLSCTX枚举器中预定义的值。

        第四个参数,引用接口标识符,用来与对象通信。

        第五个参数,用来接收指向Com对象接口地址的指针变量。

 

2、其次,建立一个特别类型的硬件设备的列表(例如视频捕捉卡)申明一个IEnumMoniker接口,并把他传给ICreateDevEnum::CreateClassEnumerator 方法。你就可以使用他访问新得到的列表了。

 

 
  1. IEnumMoniker *pEnumMon;

  2. pCreateDevEnum->CreateClassEnumerator( [specify device GUID here], &pEnumMon, 0);

 

 

第一个参数,任然是CLSID标识符:

第二个参数,用来接收指向 IEnumMoniker 接口地址的指针变量。

第三个参数,位标识符,若为0,则列举所有的过滤器目录,其他的标识符如下:

 

3、最后,列举列表直到你得到你想要的设备为止。

如果先前的CreateClassEnumerator调用成功了,你可以用IEnumMoniker::Next得到设备。调用IMoniker::BindToObject建立一个和选择的device联合的filter,并且装载filter的属性(CLSID,FriendlyName, and DevicePath)。不需要为if语句的(1 == cFetched) 困惑,在测试合法性之前,pEnumMon->Next(1, &pMon, &cFetched)方法会设置他为返回对象的数字(如果成功了为1)。

 

 
  1. ULONG cFetched = 0;

  2. IMoniker *pMon ;

  3.  
  4. if (S_OK == (pEnumMon->Next(1, &pMon, &cFetched)) && (1 == cFetched))

  5. {

  6. pMon->BindToObject(0, 0, IID_IBaseFilter, (void **)&[desired interface here]) ;

  7. pGraph->AddFilter([desired interface here], L"[filter name here]") ;

  8. pMon->Release() ; // Release moniker

  9. }

  10. pEnumMon->Release() ; // Release the class enumerator

  11. pCreateDevEnum->Release();

 

 

好,现在你有了一个IMoniker指针,你可以添加设备的filter到filter graph。一旦你添加了filter,你就不需要IMoniker指针,设备列表,或系统设备列表。现在需要实际的设备了,调用IEnumMoniker::Next ,然后用得到的指针pM调用IMoniker::BindToObject,绑定filter到设备。如果你不想建立联合的filter,使用IMoniker::BindToStorage 代替IMoniker::BindToObject。例如以下这段代码是 WebTRC 的视频捕捉模块中的一段(GetDeviceFilter):

 

 
  1. IEnumMoniker* _dsMonikerDevEnum;

  2. _dsMonikerDevEnum->Reset();

  3. ULONG cFetched;

  4. IMoniker *pM;

  5.  
  6. IBaseFilter *captureFilter = NULL;

  7. bool deviceFound = false;

  8. while (S_OK == _dsMonikerDevEnum->Next(1, &pM, &cFetched) && !deviceFound)

  9. {

  10. IPropertyBag *pBag;

  11. hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **) &pBag);

  12. if (S_OK == hr)

  13. {

  14. // Find the description or friendly name.

  15. VARIANT varName;

  16. VariantInit(&varName);

  17. if (deviceUniqueIdUTF8Length > 0)

  18. {

  19. hr = pBag->Read(L"DevicePath", &varName, 0);

  20. if (FAILED(hr))

  21. {

  22. hr = pBag->Read(L"Description", &varName, 0);

  23. if (FAILED(hr))

  24. {

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

  26. }

  27. }

  28. if (SUCCEEDED(hr))

  29. {

  30. char tempDevicePathUTF8[256];

  31. tempDevicePathUTF8[0] = 0;

  32. WideCharToMultiByte(CP_UTF8, 0, varName.bstrVal, -1,

  33. tempDevicePathUTF8,

  34. sizeof(tempDevicePathUTF8), NULL,

  35. NULL);

  36. if (strncmp(tempDevicePathUTF8,

  37. (const char*) deviceUniqueIdUTF8,

  38. deviceUniqueIdUTF8Length) == 0)

  39. {

  40. // We have found the requested device

  41. deviceFound = true;

  42. hr = pM->BindToObject(0, 0, IID_IBaseFilter,

  43. (void**) &captureFilter);

  44. if FAILED(hr)

  45. {

  46. WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture,

  47. _id, "Failed to bind to the selected capture device %d",hr);

  48. }

  49. if (productUniqueIdUTF8

  50. && productUniqueIdUTF8Length > 0) // Get the device name

  51. {

  52. GetProductId(deviceUniqueIdUTF8,

  53. productUniqueIdUTF8,

  54. productUniqueIdUTF8Length);

  55. }

  56. }

  57. }

  58. }

  59. VariantClear(&varName);

  60. pBag->Release();

  61. pM->Release();

  62. } }

先用BindToStorage 绑定 IPropertyBag,找到匹配的设备友好名之后,再用 BindToObject 来绑定 IBaseFilter,并且建立联合的 filter。

关注
打赏
1604459285
查看更多评论
立即登录/注册

微信扫码登录

0.0409s