kenlistian

厚积薄发. 勤为桨,思为帆

   :: 首页 :: 新随笔 ::  :: 聚合  :: 管理 ::
  73 随笔 :: 4 文章 :: 22 评论 :: 0 Trackbacks

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演示如何获取音视设备。这里只是
明了获取设备的方法。以备了解。

posted on 2008-12-09 11:43 kenlistian 阅读(1401) 评论(0)  编辑 收藏 引用 所属分类: directx

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理