directshow的中文资料之设备列举和捕捉接口

转载 2015年01月27日 16:40:43


这篇解释和示例如何通过DirectShow的接口去初始化和访问系统的硬件设备。代表性的,DirectShow应用程序使用下面类型的硬件。
  音/视频捕捉卡
  音频或视频回放卡
  音频或视频压缩或解压卡(MPEG解码器)
  下面将以AV设备作参考。
  如何列举设备
  包括在DirectShowSDK中的接口,类,和例子提供了音/视频捕捉和回放的功能。因为文件源过滤器和filtergraph manager处理了内在的工作,所有,添加捕捉功能到一个应用程序中,只需添加很少的代码。你可以通过列举系统硬件设备和得到设备列表完成特别的任务(例如:所有的视频捕捉卡的列表)DirectShow自动为win32Video forWindows 设备实例化过滤器。
  要AV设备工作,首先,你必须检测当前系统存在的设备。ICreateDevEnum接口建立指定类型的列表。提供你需要的检测和设置硬件的功能。访问一个指定的设备有三步,详细的说明和代码如下:
  建立系统硬件设备的列表
  首先,申明一个列表指针,然后通过CoCreateInstance 建立。CLSID_SystemDeviceEnum是我们想建立对象的类型,IID_ICreateDevEnum是接口的GUID
ICreateDevEnum *pCreateDevEnum ;
CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void**)&pCreateDevEnum) ;
  其次,建立一个特别类型的硬件设备的列表(例如视频捕捉卡)
  申明一个IEnumMoniker接口,并把他传给ICreateDevEnum::CreateClassEnumerator方法。你就可以使用他访问新得到的列表了。
IEnumMoniker *pEnumMon ;
pCreateDevEnum->CreateClassEnumerator(
[specifydevice GUID here]
&pEnumMon, 0);
  最后,列举列表直到你得到你想要的设备为止。
  如果先前的CreateClassEnumerator调用成功了,你可以用IEnumMoniker::Next得到设备。调用IMoniker::BindToObject建立一个和选择的device联合的filter,并且装载filter的属性(CLSID,FriendlyName,and DevicePath)。不需要为if语句的(1 ==cFetched) 困惑,在测试合法性之前,pEnumMon->Next(1,&pMon, &cFetched)方法会设置他为返回对象的数字(如果成功了为1)
ULONGcFetched = 0;
IMoniker*pMon ;
if (S_OK ==(pEnumMon->Next(1, &pMon, &cFetched)) && (1 == cFetched))
{
pMon->BindToObject(0, 0, IID_IBaseFilter, (void **)&[desired interfacehere]) ;
  好,现在你有了一个IMoniker指针,你可以添加设备的filterfilter graph。一旦你添加了filter,你就不需要IMoniker指针,设备列表,或系统设备列表。
pGraph->AddFilter([desiredinterface here], L"[filter name here]") ;
pMon->Release() ; // Release moniker
}
pEnumMon->Release(); // Release the class enumerator
}
pCreateDevEnum->Release();
  实例:AMCap中的设备列表代码
AMCap例子中,把所有的接口指针和一些成员变量保存在一个全局结构gcap中了。
  定义如下:
struct_capstuff {
charszCaptureFile[_MAX_PATH];
WORDwCapFileSize; // size in Meg
ICaptureGraphBuilder *pBuilder;
IVideoWindow *pVW;
IMediaEventEx *pME;
IAMDroppedFrames *pDF;
IAMVideoCompression *pVC;
IAMVfwCaptureDialogs*pDlg;
IAMStreamConfig *pASC; // for audio cap
IAMStreamConfig *pVSC; // for video cap
IBaseFilter*pRender;
IBaseFilter*pVCap, *pACap;
IGraphBuilder *pFg;
IFileSinkFilter *pSink;
IConfigAviMux *pConfigAviMux;
intiMasterStream;
BOOLfCaptureGraphBuilt;
BOOLfPreviewGraphBuilt;
BOOLfCapturing;
BOOLfPreviewing;
BOOLfCapAudio;
intiVideoDevice;
intiAudioDevice;
doubleFrameRate;
BOOLfWantPreview;
longlCapStartTime;
long lCapStopTime;
charachFriendlyName[120];
BOOLfUseTimeLimit;
DWORDdwTimeLimit;
} gcap;
  例子用uIndex变量循环列举系统的硬件设备。
BOOLInitCapFilters()
{
HRESULT hr;
BOOL f;
UINT uIndex= 0;
MakeBuilder函数建立了一个filter graphbuilder(参考建立一个捕捉程序)
f = MakeBuilder();
  建立设备列表对象,得到ICreateDevEnum接口
ICreateDevEnum *pCreateDevEnum;
hr =CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void**)&pCreateDevEnum);
  建立一个特别类型的硬件设备的列表,类的IDCLSID_VideoInputDeviceCategory。现在有了一个IEnumMoniker指针,可以访问捕捉设备的列表了。
IEnumMoniker *pEm;
hr =pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0);
pCreateDevEnum->Release(); // We don't need the device enumerator anymore
pEm->Reset(); // Go to the start of the
enumeratedlist
  现在需要实际的设备了,调用IEnumMoniker::Next,然后用得到的指针pM调用IMoniker::BindToObject,绑定filter到设备。如果你不想建立联合的filter,使用IMoniker::BindToStorage代替IMoniker::BindToObject
ULONGcFetched;
IMoniker*pM; // This will access the actual devices
gcap.pVCap= NULL;
while(hr =pEm->Next(1, &pM, &cFetched), hr==S_OK)
{
if((int)uIndex == gcap.iVideoDevice) { // This is the one we want. Instantiateit.
hr =pM->BindToObject(0, 0, IID_IBaseFilter, (void**)&gcap.pVCap);
pM->Release(); // We don't need the moniker pointer anymore
break;
}
pM->Release();
uIndex++;
}
pEm->Release(); // We've got the device; don't need the
enumeratoranymore
  当有了设备后,通过接口指针去测量帧数,得到driver的名字,得到捕捉的尺寸(size)。在例子中,把每个指针都存储才gcap全局结构中了。
, and getthe capture size. AMCap stores each pointer in the gcap global structure.
// We usethis interface to get the number of captured and dropped frames
gcap.pBuilder->FindCaptureInterface(gcap.pVCap,
IID_IAMDroppedFrames, (void **)&gcap.pDF);
// We usethis interface to get the name of the driver
gcap.pBuilder->FindCaptureInterface(gcap.pVCap,
IID_IAMVideoCompression, (void **)&gcap.pVC);
// We usethis interface to set the frame rate and get the capture size
gcap.pBuilder->FindCaptureInterface(gcap.pVCap,
IID_IAMVideoStreamConfig, (void **)&gcap.pVSC);
  然后得到媒体的类型和显示窗口的大小去匹配视频格式的尺寸。
AM_MEDIA_TYPE *pmt;
gcap.pVSC->GetFormat(&pmt); // Current capture format
ResizeWindow(HEADER(pmt->pbFormat)->biWidth,
HEADER(pmt->pbFormat)->biHeight);
DeleteMediaType(pmt);
  现在,已经有了视频设备和他的相关信息,重复这个过程,得到音频设和他的信息并存储到全局机构中去。注意,这次是用参数CLSID_AudioInputDeviceCategory调用ICreateDevEnum::CreateClassEnumerator
hr =CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void**)&pCreateDevEnum);
uIndex = 0;
hr =pCreateDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory,
&pEm,0);
pCreateDevEnum->Release();
pEm->Reset();
gcap.pACap= NULL;
while(hr =pEm->Next(1, &pM, &cFetched), hr==S_OK)
{
if((int)uIndex == gcap.iAudioDevice) { // this is the one we want
hr =pM->BindToObject(0, 0, IID_IBaseFilter, (void**)&gcap.pACap);
pM->Release();
break;
}
pM->Release();
uIndex++;
}
pEm->Release();
AMCap alsorepeats the process of retrieving the format interface, this time for the audiodevice.
hr =gcap.pBuilder->FindCaptureInterface(gcap.pACap,
IID_IAMAudioStreamConfig, (void **)&gcap.pASC);
}
  如何保持DirectShowFilter Properties道具
IPropertyBagIPersistPropertyBag 接口存储和返回Properties"bags"组。通过这些接口存储的Properties是可以持久保持的。同一个对象在不同的实例之间,他们保持一致。Filter可以存储他们的Properties(CLSID,FriendlyName, and DevicePath)。当一个filter存储完他的Properties之后,实例一个filter时,DirectShow会自动得到他们。添加功能到你的filter中,执行IPersistPropertyBag接口和他的方法。你可以用IPropertyBag::Read方法装载filterProperties Win32VARIANT 变量中,然后初始化输入输出pin
  下面的代码演示DirectShowVfWCapturefilter如何执行IPersistPropertyBag::Load方法的。记住:在执行期间,你的filter必须提供一个有效的IPropertyBag指针。
STDMETHODIMPCVfwCapture::Load(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog)
{
HRESULT hr;
CAutoLockcObjectLock(m_pLock); // Locks the object; automatically unlocks it in thedestructor.
if(m_pStream) // If the filter already exists for this stream
returnE_UNEXPECTED;
VARIANTvar; // VARIANT from Platform SDK
var.vt =VT_I4; // four-byte integer (long)
hr =pPropBag->Read(L"VFWIndex", &var, 0); // VFWIndex is theprivate name used by the Vidcap Class Manager to refer to the VFW Capturefilter
if(SUCCEEDED(hr)) // If it read the properties successfully
{
hr = S_OK;// Defaults return value to S_OK
m_iVideoId= var.lVal; // Stores the specified hardware device number
CreatePins(&hr); // Inits the pins, replacing the return value if necessary
}
return hr;// Returns S_OK or an error value, if CreatePins failed(王朝网络wangchao.net.cn)

directshow的中文资料之设备列举和捕捉接口

这篇解释和示例如何通过DirectShow的接口去初始化和访问系统的硬件设备。代表性的,DirectShow应用程序使用下面类型的硬件。音/视频捕捉卡音频或视频回放卡音频或视频压缩或解压卡(象MPEG...
  • gyskyll
  • gyskyll
  • 2006年11月29日 16:30
  • 673

DirectShow的中文资料之设备列举和捕捉接口

DirectShow的中文资料之设备列举和捕捉接口 http://dev.gameres.com/Program/Visual/Other/DirectShow_1.htm ...
  • yulinxx
  • yulinxx
  • 2015年11月11日 11:12
  • 488

DirectShow 方式列举和捕捉设备接口

DirectShow 方式列举和捕捉设备接口
  • Dopamy_BusyMonkey
  • Dopamy_BusyMonkey
  • 2015年08月06日 16:33
  • 1175

利用DirectShow列举系统已安装的摄像头设备

原文地址:http://blog.sina.com.cn/s/blog_469ff3450102voy3.html 系统设备调查器提供了一个统一的方法去列举出系统中用户所有按类型注册的过滤器...
  • hepeiworks
  • hepeiworks
  • 2016年04月18日 10:42
  • 508

系统设备的枚举(DirectShow)

DirectShow 对系统中不可预知性硬件提供了良好的支持,其方法是使用系统枚举,系统枚举的一般过程如下所示: (1)使用CoCreateInstance函数创建系统枚举器组建对象(CLSID...
  • yuanweihuayan
  • yuanweihuayan
  • 2013年12月09日 19:34
  • 1526

DirectShow的中文资料之建立一个捕捉程序

在看DXSDK/Samples/C++/DirectShow/Capture/AMCap工程时,发现了这个,于是把它转载过来了    DirectShow 提供了用应用程序从适当的硬件中捕捉和预览音/...
  • guanshangming
  • guanshangming
  • 2010年02月08日 17:42
  • 514

directshow的中文资料之建立一个捕捉程序

 DirectShow 提供了用应用程序从适当的硬件中捕捉和预览音/视频的能力。数据源包括:VCR,camera,TV tuner,microphone,或其他的数据源。一个应用程序可以立刻显示捕捉的...
  • capboy
  • capboy
  • 2001年06月12日 20:15
  • 2176

什么是DirectX,DirectShow与DirectX有什么区别?

在介绍同三维万能高清视频采集卡和全能音视频解码编码器软件等多媒体软件时,我们多次提到DirectShow、DirectX,那么什么是DirectShow?什么是DirectX,DirectShow与D...
  • wishfly
  • wishfly
  • 2015年10月17日 23:44
  • 1040

DirectShow应用——音频捕捉

现在的所谓多媒体电脑一般都会有声卡(软声卡或硬声卡),有声卡就能进行音频的捕捉。大家一定熟悉Windows自带的附件“录音机”程序,可以通过麦克风进行录音,最终生成一个Wave文件。读完本文之后,你就...
  • markman101
  • markman101
  • 2010年06月30日 10:55
  • 2703

Directshow获取系统默认设备

下面函数为通过Directshow API 获取设备列表的函数,pEnumCat->Next的第0个设备为系统默认设备 REFGUID guidValue : CLSID_AudioInputD...
  • cffishappy
  • cffishappy
  • 2016年04月07日 10:46
  • 933
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:directshow的中文资料之设备列举和捕捉接口
举报原因:
原因补充:

(最多只允许输入30个字)