编写C++程序使DirectShow进行视频捕捉

2020-01-06 14:51:47于海丽

尽管这些都是一些独立的filter,但是他们可能代表的是同一个硬件设备,每个filter都控制设备的不同函数,这些filter通过pin连接起来,但是在pin中没有数据流动。因此,这些pin 的连接和媒体类型无关。他们使用一个GUID值来定义一个给定设备的minidriver,例如:TV tuner Filter 和video capture filter都支持同一种medium。

在实际应用中,如果你使用ICaptureGraphBuilder2来创建你的capture graphs,这些filters就会自动被添加到你的graph中。更多的详细资料,可以参考WDM Class Driver Filters。

选择一个视频捕捉设备(Select capture device)

如何选择一个视频捕捉设备,可以采用系统设备枚举,详细资料参见Using the System Device Enumerator 。enumerator可以根据filter的种类返回一个设备的monikers。Moniker是一个com对象,可以参见IMoniker的SDK。

对于捕捉设备,下面两种类是相关的。

  • CLSID_AudioInputDeviceCategory 音频设备
  • CLSID_VideoInputDeviceCategory 视频设备

    下面的代码演示了如何枚举一个视频捕捉设备

    
    ICreateDevEnum *pDevEnum = NULL; 
    IEnumMoniker *pEnum = NULL; 
     
    //Create the system device enumerator 
    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, 
                   CLSCT_INPROC_SERVER, IID_ICreateDevEnum,  
                   reinterpret_cast<void**>(&pDevEnum)); 
     
    if(SUCCEEDED(hr)) 
    { 
      //创建一个枚举器,枚举视频设备 
      hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,  
                        &pEnum, 0); 
    } 
    

     
    IEnumMoniker接口pEnum返回一个IMoniker接口的列表,代表一系列的moniker,你可以显示所有的设备,然后让用户选择一个。
    采用IMoniker::BindToStorage方法,返回一个IPropertyBag接口指针。然后调用IPropertyBag::Read读取moniker的属性。下面看看都包含什么属性:

    1 FriendlyName 是设备的名字
    2 Description 属性仅仅适用于DV和D-VHS/MPEG摄象机,如果这个属性可用,这个属性更详细的描述了设备的资料
    3DevicePath 这个属性是不可读的,但是每个设备都有一个独一无二的。你可以用这个属性来区别同一个设备的不同实例

    下面的代码演示了如何显示遍历设备的名称 ,接上面的代码