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

列举视频设备:

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

 

[cpp] view plain copy

    ICreateDevEnum *pCreateDevEnum;  
    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枚举器中预定义的值。

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

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

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

 

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

 

[cpp] view plain copy

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

 

 

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

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

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

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

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

 

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

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

 

[cpp] view plain copy

    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]) ;    
        pGraph->AddFilter([desired interface here], L”[filter name here]”) ;    
        pMon->Release() ;  // Release moniker    
    }    
    pEnumMon->Release() ; // Release the class enumerator  
    pCreateDevEnum->Release();  

 

 

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

 

[cpp] view plain copy

    IEnumMoniker* _dsMonikerDevEnum;  
    _dsMonikerDevEnum->Reset();  
    ULONG cFetched;  
    IMoniker *pM;  
      
    IBaseFilter *captureFilter = NULL;  
    bool deviceFound = false;  
    while (S_OK == _dsMonikerDevEnum->Next(1, &pM, &cFetched) && !deviceFound)  
    {  
        IPropertyBag *pBag;  
        hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **) &pBag);  
        if (S_OK == hr)  
        {  
            // Find the description or friendly name.  
            VARIANT varName;  
            VariantInit(&varName);  
            if (deviceUniqueIdUTF8Length > 0)  
            {  
                hr = pBag->Read(L”DevicePath”, &varName, 0);  
                if (FAILED(hr))  
                {  
                    hr = pBag->Read(L”Description”, &varName, 0);  
                    if (FAILED(hr))  
                    {  
                        hr = pBag->Read(L”FriendlyName”, &varName, 0);  
                    }  
                }  
                if (SUCCEEDED(hr))  
                {  
                    char tempDevicePathUTF8[256];  
                    tempDevicePathUTF8[0] = 0;  
                    WideCharToMultiByte(CP_UTF8, 0, varName.bstrVal, -1,  
                                        tempDevicePathUTF8,  
                                        sizeof(tempDevicePathUTF8), NULL,  
                                        NULL);  
                    if (strncmp(tempDevicePathUTF8,  
                                (const char*) deviceUniqueIdUTF8,  
                                deviceUniqueIdUTF8Length) == 0)  
                    {  
                        // We have found the requested device  
                        deviceFound = true;  
                        hr = pM->BindToObject(0, 0, IID_IBaseFilter,  
                                              (void**) &captureFilter);  
                        if FAILED(hr)  
                        {  
                            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture,  
                                         _id, “Failed to bind to the selected capture device %d”,hr);  
                        }  
                        if (productUniqueIdUTF8  
                            && productUniqueIdUTF8Length > 0) // Get the device name  
                        {  
                            GetProductId(deviceUniqueIdUTF8,  
                                         productUniqueIdUTF8,  
                                         productUniqueIdUTF8Length);  
                        }  
                    }  
                }  
            }  
            VariantClear(&varName);  
            pBag->Release();  
            pM->Release();  
        } }  

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

原创:https://www.panoramacn.com
源码网提供WordPress源码,帝国CMS源码discuz源码,微信小程序,小说源码,杰奇源码,thinkphp源码,ecshop模板源码,微擎模板源码,dede源码,织梦源码等。

专业搭建小说网站,小说程序,杰奇系列,微信小说系列,app系列小说

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

免责声明,若由于商用引起版权纠纷,一切责任均由使用者承担。

您必须遵守我们的协议,如果您下载了该资源行为将被视为对《免责声明》全部内容的认可-> 联系客服 投诉资源
www.panoramacn.com资源全部来自互联网收集,仅供用于学习和交流,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。 敬请谅解! 侵权删帖/违法举报/投稿等事物联系邮箱:2640602276@qq.com
未经允许不得转载:书荒源码源码网每日更新网站源码模板! » DirectShow 方式列举和捕捉设备接口
关注我们小说电影免费看
关注我们,获取更多的全网素材资源,有趣有料!
120000+人已关注
分享到:
赞(0) 打赏

评论抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

您的打赏就是我分享的动力!

支付宝扫一扫打赏

微信扫一扫打赏