directshow的中文资料之设备列举和捕捉接口

VC通过DirectShow进行视频预览和捕获 立即下载

 

这篇解释和示例如何通过DirectShow的接口去初始化和访问系统的硬件设备。代表性的,DirectShow应用程序使用下面类型的硬件。

音/视频捕捉卡
音频或视频回放卡
音频或视频压缩或解压卡(象MPEG解码器)
下面将以AV设备作参考。


如何列举设备

包括在DirectShow SDK中的接口,类,和例子提供了音/视频捕捉和回放的功能。因为文件源过滤器和filter graph manager处理了内在的工作,所有,添加捕捉功能到一个应用程序中,只需添加很少的代码。你可以通过列举系统硬件设备和得到设备列表完成特别的任务(例如:所有的视频捕捉卡的列表)。DirectShow自动为win32和Video for Windows 设备实例化过滤器。

要AV设备工作,首先,你必须检测当前系统存在的设备。ICreateDevEnum接口建立指定类型的列表。提供你需要的检测和设置硬件的功能。访问一个指定的设备有三步,详细的说明和代码如下:

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

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


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

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

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

    ULONG cFetched = 0;
    IMoniker *pMon ;

    if (S_OK == (pEnumMon->Next(1, &pMon, &cFetched))  &&  (1 == cFetched))
    {
        pMon->BindToObject(0, 0, IID_IBaseFilter, (void **)&[desired interface here]) ;

好,现在你有了一个IMoniker指针,你可以添加设备的filter到filter graph。一旦你添加了filter,你就不需要IMoniker指针,设备列表,或系统设备列表。

     pGraph->AddFilter([desired interface here], L"[filter name here]") ;
     pMon->Release() ;  // Release moniker
 }
 pEnumMon->Release() ; // Release the class enumerator
    }
    pCreateDevEnum->Release();

 

实例:AMCap中的设备列表代码

AMCap例子中,把所有的接口指针和一些成员变量保存在一个全局结构gcap中了。
定义如下:
struct _capstuff {
    char szCaptureFile[_MAX_PATH];
    WORD wCapFileSize;  // size in Meg
    ICaptureGraphBuilder *pBuilder;
    IVideoWindow *pVW;
    IMediaEventEx *pME;
    IAMDroppedFrames *pDF;
    IAMVideoCompression *pVC;
    IAMVfwCaptureDialogs *pDlg;
    IAMStreamConfig *pASC;      // for audio cap
    IAMStreamConfig *pVSC;      // for video cap
    IBaseFilter *pRender;
    IBaseFilter *pVCap, *pACap;
    IGraphBuilder *pFg;
    IFileSinkFilter *pSink;
    IConfigAviMux *pConfigAviMux;
    int  iMasterStream;
    BOOL fCaptureGraphBuilt;
    BOOL fPreviewGraphBuilt;
    BOOL fCapturing;
    BOOL fPreviewing;
    BOOL fCapAudio;
    int  iVideoDevice;
    int  iAudioDevice;
    double FrameRate;
    BOOL fWantPreview;
    long lCapStartTime;
    long lCapStopTime;
    char achFriendlyName[120];
    BOOL fUseTimeLimit;
    DWORD dwTimeLimit;
} gcap;


例子用uIndex变量循环列举系统的硬件设备。
BOOL InitCapFilters()
{
    HRESULT hr;
    BOOL f;
    UINT uIndex = 0;

MakeBuilder函数建立了一个filter graph builder(参考建立一个捕捉程序)。

    f = MakeBuilder();

建立设备列表对象,得到ICreateDevEnum接口

    ICreateDevEnum *pCreateDevEnum;
    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
                          IID_ICreateDevEnum, (void**)&pCreateDevEnum);

建立一个特别类型的硬件设备的列表,类的ID是CLSID_VideoInputDeviceCategory。现在有了一个IEnumMoniker指针,可以访问捕捉设备的列表了。

    IEnumMoniker *pEm;
    hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0);
    pCreateDevEnum->Release();   // We don't need the device enumerator anymore
    pEm->Reset();      // Go to the start of the
                                                         enumerated list 


现在需要实际的设备了,调用IEnumMoniker::Next ,然后用得到的指针pM调用IMoniker::BindToObject,绑定filter到设备。如果你不想建立联合的filter,使用IMoniker::BindToStorage 代替IMoniker::BindToObject。
 

    ULONG cFetched;
    IMoniker *pM;     // This will access the actual devices
    gcap.pVCap = NULL;
    while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
    {
if ((int)uIndex == gcap.iVideoDevice) { // This is the one we want.  Instantiate it.
     hr = pM->BindToObject(0, 0, IID_IBaseFilter, (void**)&gcap.pVCap);
                    pM->Release();   // We don't need the moniker pointer anymore
     break;
 }
                pM->Release();
 uIndex++;
    }
    pEm->Release();    // We've got the device; don't need the
                                           enumerator anymore


当有了设备后,通过接口指针去测量帧数,得到driver的名字,得到捕捉的尺寸(size)。在例子中,把每个指针都存储才gcap全局结构中了。
, and get the capture size. AMCap stores each pointer in the gcap global structure.

    // We use this interface to get the number of captured and dropped frames
    gcap.pBuilder->FindCaptureInterface(gcap.pVCap,
    IID_IAMDroppedFrames, (void **)&gcap.pDF);

    // We use this interface to get the name of the driver
    gcap.pBuilder->FindCaptureInterface(gcap.pVCap,
    IID_IAMVideoCompression, (void **)&gcap.pVC);

    // We use this interface to set the frame rate and get the capture size
    gcap.pBuilder->FindCaptureInterface(gcap.pVCap,
    IID_IAMVideoStreamConfig, (void **)&gcap.pVSC);

然后得到媒体的类型和显示窗口的大小去匹配视频格式的尺寸。

  AM_MEDIA_TYPE *pmt;
    gcap.pVSC->GetFormat(&pmt);   // Current capture format

    ResizeWindow(HEADER(pmt->pbFormat)->biWidth,
    HEADER(pmt->pbFormat)->biHeight);
    DeleteMediaType(pmt);


现在,已经有了视频设备和他的相关信息,重复这个过程,得到音频设和他的信息并存储到全局机构中去。注意,这次是用参数CLSID_AudioInputDeviceCategory 调用ICreateDevEnum::CreateClassEnumerator 。

    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
                          IID_ICreateDevEnum, (void**)&pCreateDevEnum);
    uIndex = 0;
    hr = pCreateDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory,
        &pEm, 0);
    pCreateDevEnum->Release();

    pEm->Reset();
    gcap.pACap = NULL;
    while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
    {
 if ((int)uIndex == gcap.iAudioDevice) {          // this is the one we want
     hr = pM->BindToObject(0, 0, IID_IBaseFilter, (void**)&gcap.pACap);
                    pM->Release();
     break;
 }
                pM->Release();
 uIndex++;
    }
    pEm->Release();

AMCap also repeats the process of retrieving the format interface, this time for the audio device.

    hr = gcap.pBuilder->FindCaptureInterface(gcap.pACap,
    IID_IAMAudioStreamConfig, (void **)&gcap.pASC);
}

 

如何保持DirectShow Filter (Properties) 道具

IPropertyBag 和 IPersistPropertyBag 接口存储和返回Properties的"bags"组。通过这些接口存储的Properties是可以持久保持的。同一个对象在不同的实例之间,他们保持一致。Filter可以存储他们的Properties(CLSID, FriendlyName, and DevicePath)。当一个filter存储完他的Properties之后,实例一个filter时,DirectShow会自动得到他们。添加功能到你的filter中,执行IPersistPropertyBag接口和他的方法。你可以用IPropertyBag::Read 方法装载filter Properties 到Win32 VARIANT 变量中,然后初始化输入输出pin。


下面的代码演示DirectShow的VfWCapture filter如何执行IPersistPropertyBag::Load方法的。记住:在执行期间,你的filter必须提供一个有效的IPropertyBag指针。


STDMETHODIMP CVfwCapture::Load(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog)
{
    HRESULT hr;
    CAutoLock cObjectLock(m_pLock);  // Locks the object; automatically unlocks it in the destructor.

    if (m_pStream)    // If the filter already exists for this stream
 return E_UNEXPECTED;

    VARIANT var;    // VARIANT from Platform SDK
    var.vt = VT_I4;    // four-byte integer (long)
    hr = pPropBag->Read(L"VFWIndex", &var, 0); // VFWIndex is the private name used by the Vidcap Class Manager to refer to the VFW Capture filter
    if(SUCCEEDED(hr))    // If it read the properties successfully
    {
        hr = S_OK;    // Defaults return value to S_OK
        m_iVideoId = var.lVal;   // Stores the specified hardware device number
        CreatePins(&hr);    // Inits the pins, replacing the return value if necessary
    }
    return hr;     // Returns S_OK or an error value, if CreatePins failed

告别SendKeys!用DD驱动级模拟在Windows 10/11上实现真·后台键鼠操作(Python实战) 本文详细介绍了如何使用DD驱动级模拟技术在Windows 10/11上实现真后台键鼠操作,解决传统方法如pyautogui和SendKeys的局限性。通过Python实战案例,展示了驱动级模拟在游戏自动化、RPA等场景中的高效应用,包括环境配置、核心API解析及高级优化技巧。 阅读详情

相关推荐

实战解析:利用Python requests库高效抓取京东商品评论并构建结构化数据集

本文详细介绍了如何利用Python requests库高效抓取京东商品评论并构建结构化数据集。通过分析京东评论接口、处理反爬机制以及数据解析存储,帮助开发者快速获取电商数据,适用于竞品监控、用户画像构建等商业场景。

weixin_42526415的博客 837

系统设备枚举

hali999的专栏 805

手把手教你用CubeMX给GD32F103点灯、调串口(附完整工程)

本文详细介绍了如何使用CubeMX为GD32F103开发板配置GPIO点灯和串口通信,包含完整的工程创建、代码构建和测试流程。特别强调了GD32与STM32的差异点及常见避坑技巧,帮助开发者快速上手GD32开发。

weixin_42566424的博客 313

系统设备的枚举(DirectShow)

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

Welcom to zougangx's blog 2859

VulnHub系列之BadStore_123渗透测试

BADSTORE: 1.2.3 早期网商系统漏洞鉴赏(2004)

Flynn的博客 1629

别再手动算频谱了!用这个在线FFT工具,5分钟搞定JSON/CSV数据分析

本文介绍了一款高效的在线FFT工具,帮助用户快速分析JSON/CSV格式的时域数据,5分钟内完成频谱分析。通过傅里叶变换(FFT)算法,大幅提升计算效率,解决传统手动计算的痛点,适用于工业振动分析、设备故障诊断等场景。

weixin_29172201的博客 258

error LNK2001: 无法解析的外部符号 _IID_ICreateDevEnum

最近使用directshow,编译遇到如下的问题: 解决办法: 在头文件加入以下代码 #pragma comment(lib, “Strmiids.lib”)

qq_38883139的博客 2669

GEE:哨兵时间序列遥感数据和动态阈值方法计算物候时期EOS/SOS(2)

本文将分享和解释论文《Improved Estimates of Arctic Land Surface Phenology Using Sentinel-2 Time Series》中使用到的基于阈值估算北极地区的植被物候,特别是北极地区的植被季节开始和结束的日期(SoS和EoS)的方法和代码。该方法使用的是使用哨兵2数据,并实现了两种阈值方法( 无平滑的阈值方法、平滑后的阈值方法)。

养乐多的博客 2971

ICreateDevEnum Interface

ICreateDevEnum 接口,创建特定的类(如视频捕获设备,音频捕获设备,视频压缩等)的一个枚举器 ,可以使用CLSID_SystemDeviceEnum来得到该指针。ICreateDevEnum::CreateClassEnumerator(REFCLSID clsidDeviceClass, //设备类别IEnumMoniker **ppEnumMoniker, //输出参数,IEnum...

wmnmtm的专栏 2008

作为一名爬虫人如何实现千万级数据爬取?

爬虫门槛不高,高就高在往后余生的每一次实操都随时会让你崩溃!Bro

吴秋霖的博客 1万+

前端使用二开Thingsboard一、二、三事(三)-规则链

以项目实战为基础,逐步介绍前端在thingsboard系统二次开发中的一些注意事项以及一些thingsboard一些页面功能讲解,为前端人员开发使用thingsboard提供一种可靠思路,打造一个完美的物联网系统。

weixin_43163457的博客 863

设备枚举

设备枚举的过程大致如下: (1)创建一个系统枚举组件(CLSID_SystemDeviceEnum),并获得ICreateDevEnum接口。使用CoCreateInstance函数。 (2)使用接口方法ICreateDevEnum::CreateClassEnumerator为指定目录创建一个枚举器,即IEnumMoniker对象,同时获得IEnumMoniker接口。 (3)使用接口方法

Narvik的专栏 1660

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

DirectShow的中文资料之设备列举和捕捉接口

DirectShow的中文资料之设备列举和捕捉接口 http://dev.gameres.com/Program/Visual/Other/DirectShow_1.htm 这篇解释和示例如何通过DirectShow的接口去初始化和访问系统的硬件设备。代表性的,DirectShow应用程序使用下面类型的

... 990

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

directshow的中文资料之建立一个捕捉程序

 DirectShow 提供了用应用程序从适当的硬件中捕捉和预览音/视频的能力。数据源包括:VCR,camera,TV tuner,microphone,或其他的数据源。一个应用程序可以立刻显示捕捉的数据(预览),或是保存到一个文件中。在这个例子中,ICaptureGraphBuilder 接口是处理捕捉工作的主要接口。你可以在你自己的捕捉程序中使用同样的方法和接口。在这里主要讨论ICap

capboy的专栏 2605

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

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

列举视频设备: 1、建立系统硬件设备的列表首先,申明一个列表指针,然后通过 CoCreateInstance 建立。CLSID_SystemDeviceEnum是我们想建立对象的类型,IID_ICreateDevEnum是接口的GUID。 ICreateDevEnum *pCreateDevEnum; CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum..

翻肚鱼儿的博客 621

DirectShow的中文资料之建立一个捕捉程序

在看DXSDK/Samples/C++/DirectShow/Capture/AMCap工程时,发现了这个,于是把它转载过来了    DirectShow 提供了用应用程序从适当的硬件中捕捉和预览音/视频的能力。数据源包括:VCR,camera,TV tuner,microphone,或其他的数据源。一个应用程序可以立刻显示捕捉的数据(预览),或是保存到一个文件中。 在这个例子中,ICaptu

guanshangming的专栏 860

DirectShow建立一个视频捕捉程序

DirectShow提供了用应用程序从适当的硬件中捕捉和预览音/视频的能力。数据源包括:VCR,camera,TVtuner,microphone,或其他的数据源。一个应用程序可以立刻显示捕捉的数据(预览),或是保存到一个文件中。在这个例子中,ICaptureGraphBuilder接口是处理捕捉工作的主要接口。你可以在你自己的捕捉程序中使用同样的方法和接口。在这里主要讨论ICaptur...

SurpassLi的专栏 81

directshow的中文资料之综述&配置篇

综述篇DirectShow的出现,给windows下的多媒体编程提供了强大的支持.他提供了多媒体应用程序的最新技术和工具.为广大的程序员提供了一整套的应用程序接口API,使程序员能够设计高性能实时的应用程序。最新的DirectMedia SDK,提供于DirectX8.0中.其中DirectShow加入了许多新的特性.DirectShow就是原来的Microsoft ActiveMovie SDK

capboy的专栏 1961
上一篇: directshow的中文资料之建立一个捕捉程序
下一篇: 网络播放器的补充
capboy
博客等级 码龄26年 15粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值