获取系统设备方法---directshow 知识学习备注1

获取系统设备方法---directshow 知识学习备注1(转)

1.采用系统设备枚举器来枚举.
   根据硬件系统种类来枚举系统中注册的filter。
   每一种不同的硬件可能有自己的filter,也可能所有的硬件设备共用filter。

 系统设备枚举器是根据不同的种类来创建的,如,音频压缩,视频捕捉。
  不同种类的枚举器对于每一种设备返回一个独立的名称(moniker)。

下面的步骤是使用设备枚举器来获取设备:

1) 创建枚举器组件,CLSID为CLSID_SystemDeviceEnum
2) 指定某一种类型设备,获取该种类枚举器
    通过ICreateDevEnum::CreateClassEnumerator获取某一种类的枚举器,
    该函数返回一个IEnumMoniker接口指针,
    通过检查返回值是否为S_OK来判断是否获取到该种类枚举器.
3) 用IEnumMoniker::Next枚举每一个moniker。
     这个方法返回一个IMoniker接口指针。
4) 通过IMoniker::BindToStorage获取设备的名称

大致例子如下:
   

HRESULT hr;
ICreateDevEnum 
* pSysDevEnum  =  NULL;
hr 
=  CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
          IID_ICreateDevEnum, (
void   ** ) & pSysDevEnum);
if  (FAILED(hr))  return  hr;

// 获取video compressor 种类枚举器 
IEnumMoniker  * pEnumCat  =  NULL;
hr 
=  pSysDevEnum -> CreateClassEnumerator(CLSID_VideoCompressorCategory,  & pEnumCat, 0 );
if  (hr  ==  S_OK) {

 IMoniker 
*pMoniker = NULL;
 ULONG cFetched;

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

  IPropertyBag 
*pPropBag;
  hr 
= pMoniker->BindToStorage(00, IID_IPropertyBag, (void **)&pPropBag);
  
if (SUCCEEDED(hr))
  
{
   
// 获取设备名称
   VARIANT varName;
   VariantInit(
&varName);
   hr 
= pPropBag->Read(L"FriendlyName"&varName, 0);
   
if (SUCCEEDED(hr)){   
        
//获取设备名称
   }

   VariantClear(
&varName);
  }

  pMoniker
->Release();
 }

 pEnumCat
->Release();
}

pSysDevEnum
-> Release();


2.采用Filer Mapper。
   类似条件查询。

   比系统设备枚举器(System Device Enumerator)的效率要低一些。
   当要枚举某特定种类的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))  {   }

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.
                   
IMoniker 
* pMoniker;
ULONG cFetched; 

// 枚举filter,
while (pEnumCat -> Next( 1 & pMoniker,  & cFetched)  ==  S_OK)
{
  IPropertyBag 
*pPropBag = NULL;
  hr 
= pMoniker->BindToStorage(00, IID_IPropertyBag, (void **)&pPropBag);
  
if (SUCCEEDED(hr))
  
{
            VARIANT varName;
     VariantInit(
&varName);
     hr 
= pPropBag->Read(L"FriendlyName"&varName, 0);
   
if (SUCCEEDED(hr))
   
{
                   
//处理
    }

    VariantClear(
&varName);
 }

 pMoniker
->Release();
}


pMapper
-> Release();
pEnum
-> Release();

注:
 * 有关directshow的api函数,估计只能在网上搜索,至于下载的msdn没有,或者下个dssdk2002版本的help才能有。
 * 在directshow中,关于capture dev,有专门的demo演示如何获取音视设备。这里只是
明了获取设备的方法。以备了解。

你可能感兴趣的:(获取系统设备方法---directshow 知识学习备注1)