您的位置:首页 > 编程语言 > C语言/C++

Directshow 视频捕捉入门篇 二

2014-01-24 11:25 567 查看
下面的代码来结束如何选择一个视频捕捉设备,就是我们平常说的摄像头

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

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

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

CLSID_AudioInputDeviceCategory 音频设备

CLSID_VideoInputDeviceCategory 视频设备

 

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

Cpp代码  



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 这个属性是不可读的,但是每个设备都有一个独一无二的。你可以用这个属性来区别同一个设备的不同实例

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

Cpp代码  



HWND hList;         //Handle to the list box  

IMoniker *pMoniker = NULL;  

while(pEnum->Next(1, &pMoniker, NULL) == S_OK)  

{  

    IPropertyBag *pPropBag;  

    hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)(&pPropBag));  

    if(FAILED(hr))  

    {  

        pMoniker->Release();  

        continue;       //Skip this one, maybe the next one will work  

    }  

    VARIANT varName;  

    hr = pPropBag->Read(L"Description", &varName, 0);  

    if(FAILED(hr))  

    {  

        hr = pPropBag->Read(L"FriendlyName", &varName, 0);  

    }  

    if(SECCEEDED(hr))  

    {  

        //Add it to the application's list box  

        USES_CONVERSION;  

        (long)SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)OLE2T(varName.bstrVal));  

        VariantClear(&varName);  

    }  

  

    pPropBag->Release();  

    pMoniker->Release();  

}  

 

如果用户选中了一个设备调用IMoniker::BindToObject为设备生成filter,然后将filter加入到graph中。

Cpp代码  



IBaseFilter *pCap = NULL;  

hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap);  

if(SECCEEDED(hr))  

{  

    hr = m_pGraph->AddFilter(pCap, L"Capture Filter");  

}  

为了创建可以预览视频的graph,可以调用下面的代码:

Cpp代码  



ICaptureGraphBuilder2 *pBuild;      //Capture Graph Builder  

//Initialize pBuild(not shown)  

...  

IBaseFilter *pCap;                                  //Video capture filter  

hr = pBuild->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,  

                                                pCap, NULL, NULL);  

未完,待续。。。。。哈哈,如有问题可以联系我:QQ:1906733710,我是从事电子签到软件、电子白板、互动投影软件、查询软件开发的,现在要开发视频录制的功能,在对Directshow 研究的过程当中。希望一起研究提高。有需要软件的也可以联系我。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息