wangchao.org
注册 | 登录 | 添加收藏 | 订阅该频道
 
商城汽车珠宝健康家饰女性王朝网络游戏互联网探索下载娱乐学院
 
数码 | 旅游 | 美容 | 母婴 | 家电 | 美食 | 景区 | 养生 | 手机 | 购车 | 首饰 | 美妆 | 装修 | 厨房 | 科普 | 动物 | 植物 |  | 百态 | 编程 | 商品 | 财经 | 信息 | 军事
  
 
当前位置: 王朝网络 >> vc >> directshow的中文资料之设备列举和捕捉接口
 

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

字体: ||
  这篇解释和示例如何通过DirectShow的接口去初始化和访问系统的硬件设备。代表性的,DirectShow应用程序使用下面类型的硬件。
  音/视频捕捉卡
  音频或视频回放卡
  音频或视频压缩或解压卡(象MPEG解码器)
  下面将以AV设备作参考。
  如何列举设备
  包括在DirectShow SDK中的接口,类,和例子提供了音/视频捕捉和回放的功能。因为文件源过滤器和filter graph manager处理了内在的工作,所有,添加捕捉功能到一个应用程序中,只需添加很少的代码。你可以通过列举系统硬件设备和得到设备列表完成特别的任务(例如:所有的视频捕捉卡的列表)。DirectShow自动为win32和Video for Windows 设备实例化过滤器。
  要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(
   [specify device 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)。
   ULONG cFetched = 0;
   IMoniker *pMon ;
   if (S_OK == (pEnumMon->Next(1, &pMon, &cFetched)) && (1 == cFetched))
   {
   pMon->BindToObject(0, 0, IID_IBaseFilter, (void **)&[desired interface here]) ;
  好,现在你有了一个IMoniker指针,你可以添加设备的filter到filter graph。一旦你添加了filter,你就不需要IMoniker指针,设备列表,或系统设备列表。
   pGraph->AddFilter([desired interface here], L"[filter name here]") ;
   pMon->Release() ; // Release moniker
  }
  pEnumMon->Release() ; // Release the class enumerator
   }
   pCreateDevEnum->Release();
  实例:AMCap中的设备列表代码
  AMCap例子中,把所有的接口指针和一些成员变量保存在一个全局结构gcap中了。
  定义如下:
  struct _capstuff {
   char szCaptureFile[_MAX_PATH];
   WORD wCapFileSize; // 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;
   int iMasterStream;
   BOOL fCaptureGraphBuilt;
   BOOL fPreviewGraphBuilt;
   BOOL fCapturing;
   BOOL fPreviewing;
   BOOL fCapAudio;
   int iVideoDevice;
   int iAudioDevice;
   double FrameRate;
   BOOL fWantPreview;
   long lCapStartTime;
   long lCapStopTime;
   char achFriendlyName[120];
   BOOL fUseTimeLimit;
   DWORD dwTimeLimit;
  } gcap;
  例子用uIndex变量循环列举系统的硬件设备。
  BOOL InitCapFilters()
  {
   HRESULT hr;
   BOOL f;
   UINT uIndex = 0;
  MakeBuilder函数建立了一个filter graph builder(参考建立一个捕捉程序)。
   f = MakeBuilder();
  建立设备列表对象,得到ICreateDevEnum接口
   ICreateDevEnum *pCreateDevEnum;
   hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
   IID_ICreateDevEnum, (void**)&pCreateDevEnum);
  建立一个特别类型的硬件设备的列表,类的ID是CLSID_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
   enumerated list
  现在需要实际的设备了,调用IEnumMoniker::Next ,然后用得到的指针pM调用IMoniker::BindToObject,绑定filter到设备。如果你不想建立联合的filter,使用IMoniker::BindToStorage 代替IMoniker::BindToObject。
   ULONG cFetched;
   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. Instantiate it.
   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
   enumerator anymore
  当有了设备后,通过接口指针去测量帧数,得到driver的名字,得到捕捉的尺寸(size)。在例子中,把每个指针都存储才gcap全局结构中了。
  , and get the capture size. AMCap stores each pointer in the gcap global structure.
   // We use this interface to get the number of captured and dropped frames
   gcap.pBuilder->FindCaptureInterface(gcap.pVCap,
   IID_IAMDroppedFrames, (void **)&gcap.pDF);
   // We use this interface to get the name of the driver
   gcap.pBuilder->FindCaptureInterface(gcap.pVCap,
   IID_IAMVideoCompression, (void **)&gcap.pVC);
   // We use this 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 also repeats the process of retrieving the format interface, this time for the audio device.
   hr = gcap.pBuilder->FindCaptureInterface(gcap.pACap,
   IID_IAMAudioStreamConfig, (void **)&gcap.pASC);
  }
  如何保持DirectShow Filter (Properties) 道具
  IPropertyBag 和 IPersistPropertyBag 接口存储和返回Properties的"bags"组。通过这些接口存储的Properties是可以持久保持的。同一个对象在不同的实例之间,他们保持一致。Filter可以存储他们的Properties(CLSID, FriendlyName, and DevicePath)。当一个filter存储完他的Properties之后,实例一个filter时,DirectShow会自动得到他们。添加功能到你的filter中,执行IPersistPropertyBag接口和他的方法。你可以用IPropertyBag::Read 方法装载filter Properties 到Win32 VARIANT 变量中,然后初始化输入输出pin。
  下面的代码演示DirectShow的VfWCapture filter如何执行IPersistPropertyBag::Load方法的。记住:在执行期间,你的filter必须提供一个有效的IPropertyBag指针。
  STDMETHODIMP CVfwCapture::Load(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog)
  {
   HRESULT hr;
   CAutoLock cObjectLock(m_pLock); // Locks the object; automatically unlocks it in the destructor.
   if (m_pStream) // If the filter already exists for this stream
  return E_UNEXPECTED;
   VARIANT var; // VARIANT from Platform SDK
   var.vt = VT_I4; // four-byte integer (long)
   hr = pPropBag->Read(L"VFWIndex", &var, 0); // VFWIndex is the private name used by the Vidcap Class Manager to refer to the VFW Capture filter
   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解码器) 下面将以AV设备作参考。 如何列举设备 包括在DirectShow SDK中的接口,类,和例子提供了音/视频捕捉和回放的功能。因为文件源过滤器和filter graph manager处理了内在的工作,所有,添加捕捉功能到一个应用程序中,只需添加很少的代码。你可以通过列举系统硬件设备和得到设备列表完成特别的任务(例如:所有的视频捕捉卡的列表)。DirectShow自动为win32和Video for Windows 设备实例化过滤器。 要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( [specify device 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)。 ULONG cFetched = 0; IMoniker *pMon ; if (S_OK == (pEnumMon->Next(1, &pMon, &cFetched)) && (1 == cFetched)) { pMon->BindToObject(0, 0, IID_IBaseFilter, (void **)&[desired interface here]) ; 好,现在你有了一个IMoniker指针,你可以添加设备的filter到filter graph。一旦你添加了filter,你就不需要IMoniker指针,设备列表,或系统设备列表。 pGraph->AddFilter([desired interface here], L"[filter name here]") ; pMon->Release() ; // Release moniker } pEnumMon->Release() ; // Release the class enumerator } pCreateDevEnum->Release(); 实例:AMCap中的设备列表代码 AMCap例子中,把所有的接口指针和一些成员变量保存在一个全局结构gcap中了。 定义如下: struct _capstuff { char szCaptureFile[_MAX_PATH]; WORD wCapFileSize; // 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; int iMasterStream; BOOL fCaptureGraphBuilt; BOOL fPreviewGraphBuilt; BOOL fCapturing; BOOL fPreviewing; BOOL fCapAudio; int iVideoDevice; int iAudioDevice; double FrameRate; BOOL fWantPreview; long lCapStartTime; long lCapStopTime; char achFriendlyName[120]; BOOL fUseTimeLimit; DWORD dwTimeLimit; } gcap; 例子用uIndex变量循环列举系统的硬件设备。 BOOL InitCapFilters() { HRESULT hr; BOOL f; UINT uIndex = 0; MakeBuilder函数建立了一个filter graph builder(参考建立一个捕捉程序)。 f = MakeBuilder(); 建立设备列表对象,得到ICreateDevEnum接口 ICreateDevEnum *pCreateDevEnum; hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum); 建立一个特别类型的硬件设备的列表,类的ID是CLSID_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 enumerated list 现在需要实际的设备了,调用IEnumMoniker::Next ,然后用得到的指针pM调用IMoniker::BindToObject,绑定filter到设备。如果你不想建立联合的filter,使用IMoniker::BindToStorage 代替IMoniker::BindToObject。 ULONG cFetched; 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. Instantiate it. 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 enumerator anymore 当有了设备后,通过接口指针去测量帧数,得到driver的名字,得到捕捉的尺寸(size)。在例子中,把每个指针都存储才gcap全局结构中了。 , and get the capture size. AMCap stores each pointer in the gcap global structure. // We use this interface to get the number of captured and dropped frames gcap.pBuilder->FindCaptureInterface(gcap.pVCap, IID_IAMDroppedFrames, (void **)&gcap.pDF); // We use this interface to get the name of the driver gcap.pBuilder->FindCaptureInterface(gcap.pVCap, IID_IAMVideoCompression, (void **)&gcap.pVC); // We use this 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 also repeats the process of retrieving the format interface, this time for the audio device. hr = gcap.pBuilder->FindCaptureInterface(gcap.pACap, IID_IAMAudioStreamConfig, (void **)&gcap.pASC); } 如何保持DirectShow Filter (Properties) 道具 IPropertyBag 和 IPersistPropertyBag 接口存储和返回Properties的"bags"组。通过这些接口存储的Properties是可以持久保持的。同一个对象在不同的实例之间,他们保持一致。Filter可以存储他们的Properties(CLSID, FriendlyName, and DevicePath)。当一个filter存储完他的Properties之后,实例一个filter时,DirectShow会自动得到他们。添加功能到你的filter中,执行IPersistPropertyBag接口和他的方法。你可以用IPropertyBag::Read 方法装载filter Properties 到Win32 VARIANT 变量中,然后初始化输入输出pin。 下面的代码演示DirectShow的VfWCapture filter如何执行IPersistPropertyBag::Load方法的。记住:在执行期间,你的filter必须提供一个有效的IPropertyBag指针。 STDMETHODIMP CVfwCapture::Load(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog) { HRESULT hr; CAutoLock cObjectLock(m_pLock); // Locks the object; automatically unlocks it in the destructor. if (m_pStream) // If the filter already exists for this stream return E_UNEXPECTED; VARIANT var; // VARIANT from Platform SDK var.vt = VT_I4; // four-byte integer (long) hr = pPropBag->Read(L"VFWIndex", &var, 0); // VFWIndex is the private name used by the Vidcap Class Manager to refer to the VFW Capture filter 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
 
声明:王朝网络登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,文章内容仅供参考。
 
网友评论 查看所有评论
 
 218.241.173.* 发表于2010-06-12 15:50:50
  经典有效 Directshow资料 PDF文档 免费下载
  driectshow 开发笔记
  http://www.docin.com/p-55654886.html
  directshow实务精选
  http://www.docin.com/p-55657436.html
 
 
验证码:  
2006-01-08 14:53:45 繁體版 编辑
 
 
转载本文
UBB代码HTML代码
复制到剪贴板...
 
 最新文章
 ·印度暂缓封锁黑莓 紧盯网密服务密钥- ·黑客借钓鱼网站设陷阱-安全资讯 ·黄海波女友周诗雅性感写真-美女明星 ·一起来看看那些天雷滚滚的广告-搞笑
 ·微软推便携式触摸式鼠标Arc Tou ·图说那些世界上最美丽的地方-风景壁纸 ·快递“先签字后验货”被指违法-业内资 ·QQ.CN成为黑龙江联通IDC业务新
 ·拒绝50万美元奖金 跳槽Facebo ·网络管理员工作错误处理常见十宗罪-安 ·李彦宏百度大会 门票遭黄牛热炒-业内 ·李彦宏坦克大战 搜索可在线玩游戏-业
 ·步步追踪 破译远程控制失效之谜-应用 ·2010年度上半年全国病毒传播趋势  ·网络知识:OSPF路由协议基础-应用 ·林志颖娇妻陈若仪照片大曝光-美女明星
 ·十分钟完全体验Maxthon3.0- ·《庄园物语》8月风靡金山游戏世界 - ·表现满意 快车3.7新版下载能力测试 ·学生开学换手机 专家提醒先安全扫描-
 ·卡巴安全部队震撼发布保护网银安全-业 ·360安全:600万网民电脑龟速开机 ·卡巴斯基全力打造交易安全软件-安全资 ·搜狗“五级加速”引领高速浏览时代-网
 
 
© 2005- 王朝网络 版权所有