用DirectShow实现视频采集(二)

3.具体实现


首先我们需要创建几个接口全局变量。


IGraphBuilder *pGraph; //过滤器图表管理器

ICaptureGraphBuilder2 *pBuild; //视频采集过滤器图表


IBaseFilter *pCap; //Video Capture Filter

IBaseFilter *pSmartTee; //Smart Tee Filter

IBaseFilter *pRender; //Video Renderer Filter


IMediaControl *pControl; //用户命令接口,用来控制过滤器图表

IMediaEvent *pEvent; //过滤器图表事件接口


1) 采集设备枚举


在构造Video Capture Filter前,我们必须列举出系统的所有采集设备,然后才能根据列举的设备名称创建Video Capture Filter。列举设备的函数实现如下


bool ListCaptureDevices()

{

ICreateDevEnum *pDevEnum = NULL; //设备枚举器Interface

IEnumMoniker *pEnum = NULL; //名称枚举Interface


// Create the System Device Enumerator.

HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,

CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,

reinterpret_cast(&pDevEnum)); //创建设备枚举COM对象



if (SUCCEEDED(hr))

{

// Create an enumerator for the video capture category.

hr = pDevEnum->CreateClassEnumerator(

CLSID_VideoInputDeviceCategory,

&pEnum, 0); //创建视频采集设备枚举COM对象

}





IMoniker *pMoniker = NULL;


if(pEnum == NULL)

{

return false; //如果没有设备,返回

}


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.

}

// Find the description or friendly name.

VARIANT varName;

VariantInit(&varName);

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

if (FAILED(hr))

{

hr = pPropBag->Read(L"FriendlyName", &varName, 0); //设备友好名称

}

if (SUCCEEDED(hr))

{

// Add it to the application‘s list box.

char displayName[1024];

WideCharToMultiByte(CP_ACP,0,varName.bstrVal,-1,displayName,1024,"",NULL);

m_nList.AddString(displayName); //字符转换,枚举名称均为UNICODE码


VariantClear(&varName);

}

pPropBag->Release();

pMoniker->Release();

}


return true;

}


2)创建Video Capture Filter


根据枚举出来的设备友好名称(FriendlyName)创建Video Capture Filter。


bool CTest_capDlg::CreateHardwareFilter(const char * friendlyName)

{ //将friendlyName与所有的设备名称依次对比,如果相同,则创建Filter

ICreateDevEnum * enumHardware = NULL;

HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_ALL

,IID_ICreateDevEnum,(void **)&enumHardware);


if( FAILED(hr) )

{

return false;

}


IEnumMoniker * enumMoniker = NULL;


hr = enumHardware->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&enumMoniker,0);


if(enumMoniker)

{

enumMoniker->Reset();


ULONG fetched = 0;


IMoniker * moniker = NULL;

char friendlyName[256];


while(!pCap && SUCCEEDED(enumMoniker->Next(1,&moniker,&fetched)) && fetched)

{

if(moniker)

{

IPropertyBag * propertyBag = NULL;

VARIANT name;

friendlyName[0]=0;


hr=moniker->BindToStorage(0,0,IID_IPropertyBag,(void **)&propertyBag);


if(SUCCEEDED(hr))

{


name.vt=VT_BSTR;

hr = propertyBag->Read(L"FriendlyName",&name,NULL);

}

else

return false;


if(SUCCEEDED(hr))

{


WideCharToMultiByte(CP_ACP,0,name.bstrVal,-1,friendlyName,256,NULL,NULL);


moniker->BindToObject(0,0,IID_IBaseFilter,(void **)&pCap);

}

else

return false;


if(propertyBag)

{


propertyBag->Release();

propertyBag=NULL;

}


moniker->Release();

}

}

enumMoniker->Release();

}

enumHardware->Release();


return true;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值