directshow学习笔记二-----获取视频设备列表

如何列举设备

 

   在DirectShow SDK中的接口,类,和例子提供了音/视频捕捉和回放的功能。因为文件源过滤器和filter graph manager处理了内在的工作,所有,添加捕捉功能到一个应用程序中,只需添加很少的代码。你可以通过列举系统硬件设备和得到设备列表完成特别的任务(例如:所有的视频捕捉卡的列表)DirectShow自动为win32Video 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指针,你可以添加设备的filterfilter graph。一旦你添加了filter,你就不需要IMoniker指针,设备列表,或系统设备列表。

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




实例代码

void CTestDeviceDlg::GetDisplayName()
{
// Create the System Device Enumerator.

HRESULT hr = CoInitialize(NULL);
ICreateDevEnum *pSysDevEnum = NULL;

// 初始化COM  
    //hr = CoInitialize(); 

hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_ALL,
IID_ICreateDevEnum,(void**)&pSysDevEnum);
if(FAILED(hr))
{
//return NULL;
}
// Obtain a class enumerator for the video compressor category.
//创建一个枚举器,枚举视频设备
IEnumMoniker *pEnumCat = NULL;
//CLSID
hr=pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
&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;


varName.vt = VT_BSTR;


VariantInit(&varName);
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
if (SUCCEEDED(hr))
{
// Display the name in your UI somehow.
WCHAR * wzDisplayName = NULL;
//获得设备的显示名字
hr = pMoniker->GetDisplayName( NULL, NULL, &wzDisplayName ); 
m_combo.AddString(CString(varName.bstrVal));
}
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();
}


以上仅供参考。


猜你喜欢

转载自blog.csdn.net/afu1972715000/article/details/42486877