视频捕获 之 如何使用系统设备枚举器

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

如何使用系统设备枚举器

 

系统设备枚举器为我们按类型枚举已注册在系统中的Fitler提供了统一的方法。而且它能够区分不同的硬件设备,即便是同一个Filter支持它们。这对那些使用Windows驱动模型和KSProxy Filter的设备来说是非常有用的。系统设备枚举器对它们按不同的设备实例进行对待(译注:虽然它们支持相同Filter)。

当我们利用系统设备枚举器查询设备的时候,系统设备枚举器为特定类型的设备(如,音频捕获和视频压缩)生成了一张枚举表(Enumerator)。类型枚举器(Category enumerator)为每个这种类型的设备返回一个Moniker,类型枚举器自动把每一种即插即用的设备包含在内。

 

按如下的步骤使用系统设备枚举器:

1.    调用方法CoCreateInstance生成系统设备枚举器。类标识(CLSID)为CLSID_SystemDeviceEnum

2.    调用ICreateDevEnum::CreateClassEnumerator方法生成类型枚举器,参数为你想要得到的类型的CLSID,该方法返回一个IEnumMoniker接口指针,如果指定的类型(是空的)或不存在,函数ICreateDevEnum::CreateClassEnumerator将返回S_FALSE而不是错误代码,同时IEnumMoniker指针(译注:通过参数返回)也是空的,这就要求我们在调用CreateClassEnumerator的时候明确用S_OK进行比较而不是使用宏SUCCEEDED

3.    使用IEnumMoniker::Next方法依次得到IEnumMoniker指针中的每个moniker。该方法返回一个IMoniker接口指针。当Next到达枚举的底部,它的返回值仍然是S_FALSE,这里我们仍需要用S_OK来进行检验。

4.    想要得到该设备较为友好的名称(例如想要在用户界面中进行显示),调用IMoniker::BindToStorage方法。

5.    如果想要生成并初始化管理该设备的Filter调用3返回指针的IMonitor::BindToObject方法,接下来调用IFilterGraph::AddFilter把该Filter添加到视图中。

下图说明了上述步骤:

下面的代码示例了如何枚举用户系统中的视频压缩器,为了简化,只给出了很少的错误检查。

//生成系统设备枚举器.
         
HRESULT hr;
        
ICreateDevEnum *pSysDevEnum = NULL;
        
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
        
    IID_ICreateDevEnum, (void **)&pSysDevEnum);
        
if (FAILED(hr))
        
{
        
    return hr;
        
}
        

       
         
       
// 获得视频压缩的类枚举器(Class enumerator.
         
IEnumMoniker *pEnumCat = NULL;
        
hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory, &pEnumCat, 0);
        

       
         
       
if (hr == S_OK) 
        
{
        
    // 枚举其中的 moniker.
         
    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的友好名称:
         
            VARIANT varName;
        
            VariantInit(&varName);
        
            hr = pPropBag->Read(L"FriendlyName", &varName, 0);
        
            if (SUCCEEDED(hr))
        
            {
        
                //在你的用户界面上面显示.
         
            }
        
            VariantClear(&varName);
        

       
         
       
            // 如下,生成该filter的实例:
         
            IBaseFilter *pFilter;
        
            hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,
        
                (void**)&pFilter);
        
            //Filter加入到Graph. 
         
            //后面必须记得释放pFilter.
         
            pPropBag->Release();
        
        }
        
        pMoniker->Release();
        
    }
        
    pEnumCat->Release();
        
}
        
pSysDevEnum->Release();
        

 

设备Moniker

IMoniker::GetDisplayName方法返回moniker的名字。你可以把这个名字传递给IFilterGraph2::AddSourceFilterForMoniker,这样可以生成该设备的捕获Filter

LPOLESTR strName = NULL;
        
IBaseFilter pSrc = NULL;
        
hr = pMoniker->GetDisplayName(NULL, NULL, &strName);
        
if (SUCCEEDED(hr))
        
{
        
    // 得到IFilterGraph2Filter Graph Manager.
         
    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);
        
}
        

       
         
       
// 如果成功,记得释放pSrc.
         

 

虽然,用上述方法得到的名字也有较好的可读性,但是我们一般不把它显示给用户,如前面所示,我们一般用从IPropertyBag得到的名字。

方法IMoniker::ParseDisplayNameMkParseDisplayName可以用来生成指定filter类型的设备的moniker。名字以“@device:*:{category-clsid}”,代表了类型的GUID,默认的moniker是设备枚举器中的第一个moniker

//视频捕获类型
         
WCHAR szMon[] = L"@device:*:{860BB310-5D01-11d0-BD3B
        
        
         -00A
        
        
         0C
        911CE86}";
        
IBindCtx *pBindCtx;
        
hr = CreateBindCtx(0, &pBindCtx);
        

       
         
       
ULONG chEaten = 0;
        
IMoniker *pMoniker = 0;
        
hr = MkParseDisplayName(pBindCtx, szMon, &chEaten, &pMoniker);
        
pBindCtx->Release();
        
if (SUCCEEDED(hr))
        
{
        
    // 得到名字或绑定至DirectShow Filter.
         
    pMoniker->Release();
        
}
        

 

 

如何枚举系统的视音频采集设备     用Directshow SDK很容易实现该功能,但是开发者必须了解Directshow SDK的一些基础知识,对于不了解Directshow的开发员就有点头疼了。为了更方便他们开发,我封装了一个动态库,可以枚举系统的视音频采集设备(仅支持Windows系统),动态库使用非常简单,因为只有一个接口: //枚举指定类型的所有采集设备的名称 ENUMDEVICE_API HRESULT Enu... 阅读详情

相关推荐

视频开发技术 视频设备枚举 C#

由于小编之前使用过BR_Chat的音视频解决方案作视频会议系统开发,所以这里也就以当时的环境和处理机制简单做一个介绍。 1、BR_Chat-枚举本地视频采集设备-方法概述:      DWORD BRAC_EnumVideoCapture(TCHAR** lpDeviceName, DWORD&      dwDeviceNum);      功能:枚举本地视频采集设备      返

little_rui的专栏 1237

如何使用系统设备枚举

系统设备枚举为我们按类型枚举已注册在系统中的Fitler提供了统一的方法。而且它能够区分不同的硬件设备,即便是同一个Filter支持它们。这对那些使用Windows驱动模型和KSProxy Filter设备来说是非常有用的。系统设备枚举对它们按不同的设备实例进行对待(译注:虽然它们支持相同Filter)。   当我们利用系统设备枚举查询设备的时候,系统设备枚举为特定类型的设备(如,音频

技术联盟 2715

如何枚举视频设备for C#

由于小编之前使用过AnyChat的音视频解决方案,开发视频

little_rui的专栏 1834

Flir相机spinnaker库配置缺少directshow

1>VideoInput.obj : error LNK2001: 无法解析的外部符号 IID_ICreateDevEnum 1>VideoInput.obj : error LNK2001: 无法解析的外部符号 IID_IBaseFilter 1>VideoInput.obj : error LNK2001: 无法解析的外部符号 CLSID_SystemDeviceEnum 1>VideoInput.obj : error LNK2001: 无法解析的外部符号 CLSID_Vide

cutemypig的博客 2055

DirectShow中的视频捕捉之二

选择一个视频捕捉设备(Select capture device)如何选择一个视频捕捉设备,可以采用系统设备枚举,详细资料参见Using the System Device Enumerator 。enumerator可以根据filter的种类返回一个设备的monikers。Moniker是一个com对象,可以参见IMoniker的SDK。 对于捕捉设备,下面两种类是相关的。 CLSID_...

镜花水月 467

创建一个类型枚举,指向系统视频设备列表

创建一个类型枚举,指向系统视频设备列表

Y12231819的博客 576

VS2010 C++学习(5):基于DirectShow的视频预览录像程序

VS2010 C++学习(5):基于DirectShow的视频 预览录像程序   学习VC++编制的基于DirectShow视频捕获程序,主要练习基于DirectShow程序的应用。   一、           主要内容:   1.        基于DirectShow视频预览; 2.        基于DirectShow视频录像;   二、           设计实现

dalong10的专栏 1564

如何枚举系统中的各种设备

一、枚举设备 1、系统枚举 2、由系统枚举创建具体类别的设备枚举 3、使用IEnumMoniker枚举指定类型的设备、获得设备名等信息 一、枚举设备 1、系统枚举 使用CoCreateInstance函数创建系统枚举组建对象 CLSID_SystemDeviceEnum ,并获得ICreateDevEnum接口。 ICreateDevEnum *pSysDevEnum = NULL; // initialize COM CoInitialize(NULL); CoCr...

目前打算换一个工作,有招聘windows c++方向的也欢迎联系,北京、济南 最好 1083

如何列举你系统已经安装的设备视频压缩设备视频捕获设备...)!

<!--google_ad_client = "pub-8303851053100251";google_ad_width = 468;google_ad_height = 60;google_ad_format = "468x60_as";google_ad_type = "text_image";google_ad_channel ="";//--><script

孙涛的专栏 6626

【转】如何使用系统设备枚举

<br /> 如何使用系统设备枚举<br /><br />  系统设备枚举为我们按类型枚举已注册在系统中的Fitler提供了统一的方法。而且它能够区分不同的硬件设备,即便是同一个Filter支持它们。这对那些使用Windows驱动模型和KSProxy Filter设备来说是非常有用的。系统设备枚举对它们按不同的设备实例进行对待(译注:虽然它们支持相同Filter)。<br />  当我们利用系统设备枚举查询设备的时候,系统设备枚举为特定类型的设备(如,音频捕获视频压缩)生成了一张枚举表(Enu

ding_net的专栏 1651

如何列举你系统已经安装的设备视频压缩设备视频捕获设备...)

 系统设备调查提供了一个统一的方法去列举出系统中用户所有按类型注册的过滤系统设备调查通过创建一个指定类型调查(比如音频捕获类型或者视频压缩类型) (enumerator)来工作,这个调查会返回系统中所有该类设备的唯一名称。按一下步骤操作去使用设备调查: 1.         调用CoCreateInstance 创建系统设备调查。类标识(CLSID)参数是CLSID_S

believefym的专栏 1920

系统设备枚举(DirectShow)

DirectShow 对系统中不可预知性硬件提供了良好的支持,其方法是使用系统枚举系统枚举的一般过程如下所示:(1)使用CoCreateInstance函数创建系统枚举组建对象(CLSID为CLSID_SystemDeviceEnum),并获得ICreateDevEnum接口;(2)使用接口方法ICreateDevEnum::CreateClassEnumerator为指定的Filter注册类

Welcom to zougangx's blog 2857

创建一个系统设备枚举接口

创建一个系统设备枚举接口

Y12231819的博客 526

DirectShow之设备枚举

//本机环境:vs2013+编译好的:BaseClasses 一.新建项目---配置 新建Win32项目->Unicode配置->删除_tWinMain自动生成代码即可! 二.引入头文件目录 三.引入库文件目录 四.导入头文件 五.枚举音频设备友好名(视频同理) // DirectShowEnumDevice.cpp : 定义应用程序的入口点。 // #include "stdafx.h" #include "DirectShowEnumDevice.h" #i

qq_32667685的博客 646

DirectShow之枚举设备和过滤

Using the System Device Enumerator     System Device Enumerator提供了一种统一的方法来枚举按类别枚举在用户系统上注册的过滤。 而且,它可以区分单个硬件设备,即使同一个过滤支持它们。 这对于使用Windows驱动程序模型(WDM)和KSProxy过滤设备特别有用。 例如,用户可能有几个WDM视频捕捉设备,全部由相同的过滤支持。...

冷月醉雪的博客 1368

libuvc实战解析:从设备枚举视频捕获的完整流程

本文详细解析了libuvc库在USB摄像头开发中的实战应用,从设备枚举视频捕获的完整流程。通过UVC标准协议,libuvc实现了跨平台兼容性,支持多种USB摄像头设备,并提供了高效的视频流控制方法。文章还分享了环境搭建、性能调优和高级功能挖掘的实用技巧,帮助开发者快速掌握libuvc的核心功能。

weixin_30363981的博客 450

枚举系统设备

#include #include #include #include #include #include #pragma comment(lib, "setupapi.lib")#define BUFSIZE    1024#define SM_SERVERR    289int main(){    HDEVINFO hDevInfo;    SP_DEVINFO_DATA De

4155

基于VFW的视频捕获技术实践教程

本文还有配套的精品资源,点击获取 简介:本项目通过Video for Windows(VFW)框架使用Visual C++开发,旨在教授如何利用VFW API进行实时视频流的捕获。项目内容涵盖了从打开摄像头、设置捕获参数到预览视频及处理捕获帧的全过程。开发者可以学习到如何访问系统硬件,编写高效、灵活的代码,并对视频数据进行实时处理。通过本教程,学习者将深入了解视频流处理、多...

weixin_30633869的博客 900
上一篇: 在中Visual Studio .NET 2003利用DirectShow播放媒体文件(五)
sunjin007
博客等级 码龄22年 1粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值