有时,应用程序需要查看系统中所有的filter。例如,视频应用程序需要列出系统中可用的捕捉设备。因为dshow基于com结构的,你在设计程序的时候是没法知道系统中正在使用的过滤器。Directshow提供了两种方法来枚举系统中注册的过虑器。

1 系统设备枚举器

系统设备枚举器提供了一个很好的方法根据种类来枚举系统中注册的过虑器。也许枚一种不同的硬件都会有自己的过虑器,或许所有的硬件设备共用同一个filter。这个对于采用WDM驱动程序的硬件很有用。

系统设备枚举器根据不同的种类创建了一个枚举器,例如,音频压缩,视频捕捉。不同种类的枚举器对于每一种设备返回一个独立的名称(moniker)。种类枚举器自动将相关的即插即用,演播设备包括进来。

按照下面的步骤使用设备枚举器

1 创建枚举器组件,CLSID为CLSID_SystemDeviceEnum

2 指定某一种类型设备,参数CLSID,通过ICreateDevEnum::CreateClassEnumerator获取某一种类的枚举器,这个函数返回一个IEnumMoniker接口指针,如果该种类的空或者不存在,这个方法就返回S_FALSE。因此,当你调用这个函数时一定要检查返回值是否为S_OK,而不要用SUCCEEDED宏。

3 然后IEnumMoniker::Next枚举每一个moniker。这个方法返回一个IMoniker接口指针。

4 要想知道设备的名称,可以通过下面的函数IMoniker::BindToStorage

5 然后利用IMoniker::BindToObject生成绑定道设备上的filter。调用IFilterGraph::AddFilter将filter添加到Graph图中。

// Create the System Device Enumerator.

HRESULT hr;

ICreateDevEnum *pSysDevEnum = NULL;

hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,

    IID_ICreateDevEnum, (void **)&pSysDevEnum);

if (FAILED(hr))

{

return hr;

}

// Obtain a class enumerator for the video compressor category.

IEnumMoniker *pEnumCat = NULL;

hr=pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory, &pEnumCat, 0);

if (hr == S_OK)

{

// Enumerate the monikers.

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))

{

// To retrieve the filter's friendly name, do the following:

VARIANT varName;

VariantInit(&varName);

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

if (SUCCEEDED(hr))

{

// Display the name in your UI somehow.

}

VariantClear(&varName);

// To create an instance of the filter, do the following:

IBaseFilter *pFilter;

hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,

                (void**)&pFilter); //生成一个filter绑定到设备上。

// Now add the filter to the graph.

//Remember to release pFilter later.

pPropBag->Release();

}

pMoniker->Release();

}

pEnumCat->Release();

}

pSysDevEnum->Release();

在上面我们用IMoniker::BindToObject生成绑定道设备上的filter,当然我们还可以用另外的一种方法来生成绑定到设备上的filter

利用IMoniker::GetDisplayName得到moniker的名字。然后你把moniker的名字做参数传递给IFilterGraph2::AddSourceFilterForMoniker,就可以创建一个绑定到设备的filter了。在上面我们是调用IMoniker::BindToObject生成filter的,还是上面的简单些。看看代码吧。

LPOLESTR strName = NULL;

IBaseFilter pSrc = NULL;

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

if (SUCCEEDED(hr))

{

// Query the Filter Graph Manager for IFilterGraph2.

IFilterGraph2 *pFG2 = NULL;

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

if (SUCCEEDED(hr))

{

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

pFG2->Release();

}

CoTaskMemFree(strName);

}

// If successful, remember to release pSrc.

2 Filter Mapper

搜索系统中的filter的另一个方法就是采用Filer Mapper。Filter mapper是一个com对象,它按照一定的条件来搜索系统的filer,它比系统设备枚举器(System Device Enumerator)的效率要低一些。所以当你要枚举某特定种类的filter时,你应该使用系统设备枚举器,但是当你搜索支持某种媒体类型的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))

{

// Error handling omitted for clarity.

}

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.

// Enumerate the monikers.

IMoniker *pMoniker;

ULONG cFetched;

//下面就是枚举filter了,就是系统枚举设备filter

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

{

IPropertyBag *pPropBag = NULL;

hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,

(void **)&pPropBag);

if (SUCCEEDED(hr))

{

// To retrieve the friendly name of the filter, do the following:

VARIANT varName;

VariantInit(&varName);

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

if (SUCCEEDED(hr))

{

// Display the name in your UI somehow.

}

VariantClear(&varName);

// To create an instance of the filter, do the following:

IBaseFilter *pFilter;

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

// Now add the filter to the graph. Remember to release pFilter later.

// Clean up.

pPropBag->Release();

}

pMoniker->Release();

}

// Clean up.

pMapper->Release();

pEnum->Release();

转载于:https://blog.51cto.com/kingmoon/409341

DirectShow--A.枚举设备相关推荐

  1. c#使用WPD读取便携式设备信息一(枚举设备、连接设备及读取设备信息)

    手机或其他电子设备通过USB插入电脑上,并且以MTP(媒体传输协议)方式连接时,可在"计算机"中看到类似计算机盘符的便携式设备文件夹显示,但是这并不是一个计算机盘符,并不能通过常规 ...

  2. FFMPEG列出DirectShow支持的设备

    FFMPEG列出dshow支持的设备: ffmpeg -list_devices true -f dshow -idummy 举例: 采集摄像头和麦克风 ffmpeg -f dshow -i vide ...

  3. C#枚举硬件设备(升级版)

    先取设备类型: /// <summary>/// 设备类型/// </summary> class DeviceClasses {public static Guid Clas ...

  4. 波形捕捉:(1)枚举捕捉设备

    枚举"捕捉设备" 后在网上找到类似翻译:DirectSound学习笔记(1):枚举声音设备  作者:pyundeng 而且作者是在06年发表的,哎~~~ 犹豫了半天是否有必要继续翻 ...

  5. Qt实现设备管理器——枚举系统所有设备

    本文Jungle将用vs2013+Qt5.6.0来实现设备管理器.什么是设备管理器?使用过Windows系统的人应该不陌生,它用来管理计算机上的设备.可以使用"设备管理器"查看和更 ...

  6. PCI/PCIE之总线、设备枚举

    先思考一个问题,系统配置PCI设备的时候,需要指明Bus Device Function Register构成的地址,但是系统如何知道主板上有多少总线,设备呢?整个系统的PCI拓扑需要系统去枚举遍历, ...

  7. CoreAudioApi-音频端点设备-检测耳机插拔

    术语"端点设备"是指位于数据路径一端的硬件设备,该数据路径源自或终止于应用程序.音频终端设备的例子有扬声器.耳机.麦克风和CD播放器.沿着数据路径移动的音频数据可能在应用程序和端点 ...

  8. Directshow完整介绍

    最近一段时间,在编写DirectShow应用程序时常常遇到一些问题,原因是对DirectShow技术没有较全面地掌握,对各个接口间的关系以及filter与filter之间连接的内部过程等都只是一知半解 ...

  9. DirectShow编程

    3. 关于DirectShow 3.1. DirectShow体系概述     多媒体的难题     处理多媒体有几个主要的难题:     *多媒体流包含了巨大的数据量,而这些数据都必须非常快地被处理 ...

最新文章

  1. 四川大学计算机学院2020推免公示,四川大学2020年推免生录取情况分析
  2. 怎么归档老日志的shell脚本
  3. postgresql主从备份_基于PG12.2实现主从异步流复制及主从切换教程(下)
  4. c#获取文件夹路径(转载)
  5. POJ 1113 Wall 求凸包
  6. python 解析命令行
  7. HelloWorld Windows Live Writer
  8. linux uuid挂载磁盘_Linux磁盘设备磁盘设备的UUID标识代码(sda,sdb,sdc…)变化的解决办法...
  9. c语言皮尔森系数程序,【R语言编程】---根据表达量计算mRNA与lncRNA的皮尔森相关系数...
  10. 刷新网页定位到特定位置
  11. 西瓜书之误差逆传播公式推导、源码解读及各种易混淆概念
  12. Verilog学习笔记(7)Modelsim仿真_三角波发生器
  13. unity渲染篇:画面亮度、饱和度、对比度调整
  14. 网站打开速度过慢时该怎么提高?
  15. 失眠睡不着觉怎么办?这些助眠好物帮助你走出失眠
  16. getContextPath方法
  17. win10安装opcenum_Win10安装会遇到的问题汇总及解决方法
  18. Linux环境安装unzip
  19. atom开发java_Atom简明用法
  20. Invalid character (CR or LF) found in method name

热门文章

  1. Macbook Pro 光驱坏 安装windows
  2. react新生命周期
  3. django自定义模板标签,通过键获取字典的值,屏蔽姓名等隐蔽信息并调用展示到页面上
  4. Kerberos加密级别不支持的问题
  5. Kafka如何更新元数据到各broker节点
  6. Kafka万亿级消息实战解决方案干货
  7. SpringBoot集成Shiro进行权限控制和管理
  8. 带有下标的赋值维度不匹配是什么意思_三言两语说清TensorFlow是什么?拿来干嘛的?...
  9. 确定不进来看看?分享一个插件,让敲代码不再枯燥,activate-power-mode
  10. 自己动手构造编译系统:编译、汇编与链接2.1.4 语义分析