登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

面包会有的

... ...

 
 
 

日志

 
 

用DirectShow实现视频采集(二)  

2010-09-21 15:55:37|  分类: DirectShow |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
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;

}
  评论这张
 
阅读(1395)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018