Chinaunix首页 | 论坛 | 博客
  • 博客访问: 14523433
  • 博文数量: 5645
  • 博客积分: 9880
  • 博客等级: 中将
  • 技术积分: 68081
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-28 13:35
文章分类

全部博文(5645)

文章存档

2008年(5645)

我的朋友

分类:

2008-04-28 21:29:14

下载本文示例代码
  DirectShow是微软公司提供的一套在Windows平台上进行流媒体处理的开发包,与DirectX开发包一起发布。DirectShow为多媒体流的捕捉和回放提供了强有力的支持。用DirectShow开发应用程序,我们可以很方便地从支持WDM驱动模型的采集卡上捕获数据,并且进行相应的后期处理乃至存储到文件中。  DirectShow是基于COM的,为了编写DirectShow应用程序,需要了解COM客户程序编写的基础知识。DirectShow提供了大量的接口,但在编程中发现还是不够方便,如果能构建一个视频捕捉类把常用的一些动作封装起来,那么就更方便了。  编程思路  为了更加容易建立视频捕捉应用程序,DirectShow提供了一个叫做Capture Graph Builder的对象,Capture Graph Builder提供IcaptureGraphBuilder2接口,该接口可以建立和控制Capture Graph。  建立视频捕捉程序,必须首先获取并初始化IcaptureGraphBuilder2接口,然后选择一个适当的视频捕捉设备。选择好设备后,为该设备创建Capture filter,然后调用AddFilter把Capture filter添加到Filter Graph。  如果仅仅希望用摄像头来进行实时监控的话,只需要在上面的基础上调用ICaptureGraphBuilder2::RenderStream就可以了: ICaptureGraphBuilder2 *pBuild; // Capture Graph Builder//省略初始化部分代码IBaseFilter *pCap; // Video capture filter.//省略初始化和添加到Filter Graph部分代码pBuild->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pCap, NULL, NULL);  DirectShow提供了一个捕捉静态图像的方法:使用Sample Grabber filter。依次按照以下三个步骤就可以了:  第一步, 定义一个类实现Sample Grabber的回调接口IsampleGrabberCB: class CSampleGrabberCB : public ISampleGrabberCB{  //在后面提供的类中具体完成}CSampleGrabberCB mCB;  第二步、调用RenderStream依次把Still pin、Sample Grabber和系统默认Renderer Filter连接起来。  第三步、配置Sample Grabber以捕获数据。  视频捕捉类CCaptureVideo的具体实现 // CCaptureVideo视频捕捉类头文件/////////////////////////////////////////////////////////////////////#if !defined(AFX_CAPTUREVIDEO_H__F5345AA4_A39F_4B07_B843_3D87C4287AA0__INCLUDED_)#define AFX_CAPTUREVIDEO_H__F5345AA4_A39F_4B07_B843_3D87C4287AA0__INCLUDED_/////////////////////////////////////////////////////////////////////// CaptureVideo.h : header file/////////////////////////////////////////////////////////////////////#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#include #include #include #ifndef SAFE_RELEASE#define SAFE_RELEASE( x ) \if ( NULL != x ) \{ \ x->Release( ); \ x = NULL; \}#endifclass CSampleGrabberCB;class CCaptureVideo : public CWnd { friend class CSampleGrabberCB; public:  void GrabOneFrame(BOOL bGrab);  HRESULT Init(int iDeviceID,HWND hWnd);  int EnumDevices(HWND hList);  CCaptureVideo();  virtual ~CCaptureVideo(); private:  HWND m_hWnd;  IGraphBuilder *m_pGB;  ICaptureGraphBuilder2* m_pCapture;  IBaseFilter* m_pBF;  IMediaControl* m_pMC;  IVideoWindow* m_pVW;  CComPtr m_pGrabber; protected:  void FreeMediaType(AM_MEDIA_TYPE& mt);  bool BindFilter(int deviceId, IBaseFilter **pFilter);  void ResizeVideoWindow();  HRESULT SetupVideoWindow();  HRESULT InitCaptureGraphBuilder();};#endif // !defined(AFX_CAPTUREVIDEO_H__F5345AA4_A39F_4B07_B843_3D87C4287AA0__INCLUDED_)//-------------------------------------------------------------------// CCaptureVideo视频捕捉类实现文件CaptureVideo.cpp//-------------------------------------------------------------------// CaptureVideo.cpp: implementation of the CCaptureVideo class.///////////////////////////////////////////////////////////////////////#include "stdafx.h"#include "CaptureVideo.h"#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endifBOOL bOneShot=FALSE;//全局变量class CSampleGrabberCB : public ISampleGrabberCB { public:  long lWidth;  long lHeight;  TCHAR m_szFileName[MAX_PATH];// 位图文件名称  CSampleGrabberCB( ){   strcpy(m_szFileName, "c:\\donaldo.bmp");  }   STDMETHODIMP_(ULONG) AddRef() { return 2; }  STDMETHODIMP_(ULONG) Release() { return 1; }  STDMETHODIMP QueryInterface(REFIID riid, void ** ppv){  if( riid == IID_ISampleGrabberCB || riid == IID_IUnknown ){    *ppv = (void *) static_cast ( this );   return NOERROR;  }   return E_NOINTERFACE; } STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample ){ return 0;}STDMETHODIMP BufferCB( double dblSampleTime, BYTE * pBuffer, long lBufferSize ){ if( !bOneShot )return 0;  if (!pBuffer)return E_POINTER; SaveBitmap(pBuffer, lBufferSize); bOneShot = FALSE; return 0;}//创建位图文件BOOL SaveBitmap(BYTE * pBuffer, long lBufferSize ){ HANDLE hf = CreateFile( m_szFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, NULL, NULL ); if( hf == INVALID_HANDLE_VALUE )return 0;  // 写文件头   BITMAPFILEHEADER bfh;  memset( &bfh, 0, sizeof( bfh ) );  bfh.bfType = ’MB’;  bfh.bfSize = sizeof( bfh ) lBufferSize sizeof( BITMAPINFOHEADER );  bfh.bfOffBits = sizeof( BITMAPINFOHEADER ) sizeof( BITMAPFILEHEADER );  DWORD dwWritten = 0;  WriteFile( hf, &bfh, sizeof( bfh ), &dwWritten, NULL );  // 写位图格式  BITMAPINFOHEADER bih;  memset( &bih, 0, sizeof( bih ) );  bih.biSize = sizeof( bih );  bih.biWidth = lWidth;  bih.biHeight = lHeight;  bih.biPlanes = 1;  bih.biBitCount = 24;  WriteFile( hf, &bih, sizeof( bih ), &dwWritten, NULL );  // 写位图数据  WriteFile( hf, pBuffer, lBufferSize, &dwWritten, NULL );  CloseHandle( hf );  return 0; }};CSampleGrabberCB mCB;//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////CCaptureVideo::CCaptureVideo(){ //COM Library Intialization if(FAILED(CoInitialize(NULL))) /*, COINIT_APARTMENTTHREADED)))*/ {  AfxMessageBox("CoInitialize Failed!\r\n");   return; } m_hWnd = NULL; m_pVW = NULL; m_pMC = NULL; m_pGB = NULL; m_pCapture = NULL; }CCaptureVideo::~CCaptureVideo(){ // Stop media playback if(m_pMC)m_pMC->Stop(); if(m_pVW){  m_pVW->put_Visible(OAFALSE);  m_pVW->put_Owner(NULL); } SAFE_RELEASE(m_pCapture); SAFE_RELEASE(m_pMC); SAFE_RELEASE(m_pGB); SAFE_RELEASE(m_pBF); CoUninitialize( );}int CCaptureVideo::EnumDevices(HWND hList){ if (!hList)  return -1; int id = 0; //枚举视频扑捉设备 ICreateDevEnum *pCreateDevEnum; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void**)&pCreateDevEnum); if (hr != NOERROR)return -1; CComPtr pEm; hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0); if (hr != NOERROR)return -1; pEm->Reset(); ULONG cFetched; IMoniker *pM; while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK) {  IPropertyBag *pBag;  hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);  if(SUCCEEDED(hr))   {   VARIANT var;   var.vt = VT_BSTR;   hr = pBag->Read(L"FriendlyName", &var, NULL);   if (hr == NOERROR)    {    TCHAR str[2048];     id ;    WideCharToMultiByte(CP_ACP,0,var.bstrVal, -1, str, 2048, NULL, NULL);    ::SendMessage(hList, CB_ADDSTRING, 0,(LPARAM)str);    SysFreeString(var.bstrVal);   }   pBag->Release();  }  pM->Release(); } return id;}HRESULT CCaptureVideo::Init(int iDeviceID, HWND hWnd){ HRESULT hr; hr = InitCaptureGraphBuilder(); if (FAILED(hr)){  AfxMessageBox("Failed to get video interfaces!");  return hr; } // Bind Device Filter. We know the device because the id was passed in if(!BindFilter(iDeviceID, &m_pBF))return S_FALSE; hr = m_pGB->AddFilter(m_pBF, L"Capture Filter"); // hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,  // m_pBF, NULL, NULL); // create a sample grabber hr = m_pGrabber.CoCreateInstance( CLSID_SampleGrabber ); if( !m_pGrabber ){  AfxMessageBox("Fail to create SampleGrabber, maybe qedit.dll is not registered?");  return hr; } CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabBase( m_pGrabber ); //设置视频格式 AM_MEDIA_TYPE mt;  ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE)); mt.majortype = MEDIATYPE_Video; mt.subtype = MEDIASUBTYPE_RGB24; hr = m_pGrabber->SetMediaType(&mt); if( FAILED( hr ) ){  AfxMessageBox("Fail to set media type!");  return hr; } hr = m_pGB->AddFilter( pGrabBase, L"Grabber" ); if( FAILED( hr ) ){  AfxMessageBox("Fail to put sample grabber in graph");  return hr; } // try to render preview/capture pin hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL); if( FAILED( hr ) )  hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL);  if( FAILED( hr ) ){   AfxMessageBox("Can’t build the graph");   return hr;  }  hr = m_pGrabber->GetConnectedMediaType( &mt ); if ( FAILED( hr) ){  AfxMessageBox("Failt to read the connected media type");  return hr; } VIDEOINFOHEADER * vih = (VIDEOINFOHEADER*) mt.pbFormat; mCB.lWidth = vih->bmiHeader.biWidth; mCB.lHeight = vih->bmiHeader.biHeight; FreeMediaType(mt); hr = m_pGrabber->SetBufferSamples( FALSE ); hr = m_pGrabber->SetOneShot( FALSE ); hr = m_pGrabber->SetCallback( &mCB, 1 ); //设置视频捕捉窗口 m_hWnd = hWnd ;  SetupVideoWindow(); hr = m_pMC->Run();//开始视频捕捉 if(FAILED(hr)){AfxMessageBox("Couldn’t run the graph!");return hr;} return S_OK;}bool CCaptureVideo::BindFilter(int deviceId, IBaseFilter **pFilter){ if (deviceId < 0) return false; // enumerate all video capture devices CComPtr pCreateDevEnum; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void**)&pCreateDevEnum); if (hr != NOERROR) {  return false; } CComPtr pEm; hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0); if (hr != NOERROR)  {  return false; } pEm->Reset(); ULONG cFetched; IMoniker *pM; int index = 0; while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK, index <= deviceId) {  IPropertyBag *pBag;  hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);  if(SUCCEEDED(hr))   {   VARIANT var;   var.vt = VT_BSTR;   hr = pBag->Read(L"FriendlyName", &var, NULL);   if (hr == NOERROR)    {    if (index == deviceId)    {     pM->BindToObject(0, 0, IID_IBaseFilter, (void**)pFilter);    }    SysFreeString(var.bstrVal);   }   pBag->Release();  }  pM->Release();  index ; } return true;}HRESULT CCaptureVideo::InitCaptureGraphBuilder(){ HRESULT hr; // 创建IGraphBuilder接口 hr=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&m_pGB); // 创建ICaptureGraphBuilder2接口 hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,IID_ICaptureGraphBuilder2, (void **) &m_pCapture); if (FAILED(hr))return hr; m_pCapture->SetFiltergraph(m_pGB); hr = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC); if (FAILED(hr))return hr; hr = m_pGB->QueryInterface(IID_IVideoWindow, (LPVOID *) &m_pVW); if (FAILED(hr))return hr; return hr;}HRESULT CCaptureVideo::SetupVideoWindow(){ HRESULT hr; hr = m_pVW->put_Owner((OAHWND)m_hWnd); if (FAILED(hr))return hr; hr = m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN); if (FAILED(hr))return hr; ResizeVideoWindow(); hr = m_pVW->put_Visible(OATRUE); return hr;}void CCaptureVideo::ResizeVideoWindow(){ if (m_pVW){  //让图像充满整个窗口  CRect rc;  ::GetClientRect(m_hWnd,&rc);  m_pVW->SetWindowPosition(0, 0, rc.right, rc.bottom); } }void CCaptureVideo::GrabOneFrame(BOOL bGrab){ bOneShot = bGrab;}void CCaptureVideo::FreeMediaType(AM_MEDIA_TYPE& mt){ if (mt.cbFormat != 0) {  CoTaskMemFree((PVOID)mt.pbFormat);  // Strictly unnecessary but tidier  mt.cbFormat = 0;  mt.pbFormat = NULL; } if (mt.pUnk != NULL) {  mt.pUnk->Release();  mt.pUnk = NULL; }}共2页。 1 2 :   DirectShow是微软公司提供的一套在Windows平台上进行流媒体处理的开发包,与DirectX开发包一起发布。DirectShow为多媒体流的捕捉和回放提供了强有力的支持。用DirectShow开发应用程序,我们可以很方便地从支持WDM驱动模型的采集卡上捕获数据,并且进行相应的后期处理乃至存储到文件中。  DirectShow是基于COM的,为了编写DirectShow应用程序,需要了解COM客户程序编写的基础知识。DirectShow提供了大量的接口,但在编程中发现还是不够方便,如果能构建一个视频捕捉类把常用的一些动作封装起来,那么就更方便了。  编程思路  为了更加容易建立视频捕捉应用程序,DirectShow提供了一个叫做Capture Graph Builder的对象,Capture Graph Builder提供IcaptureGraphBuilder2接口,该接口可以建立和控制Capture Graph。  建立视频捕捉程序,必须首先获取并初始化IcaptureGraphBuilder2接口,然后选择一个适当的视频捕捉设备。选择好设备后,为该设备创建Capture filter,然后调用AddFilter把Capture filter添加到Filter Graph。  如果仅仅希望用摄像头来进行实时监控的话,只需要在上面的基础上调用ICaptureGraphBuilder2::RenderStream就可以了: ICaptureGraphBuilder2 *pBuild; // Capture Graph Builder//省略初始化部分代码IBaseFilter *pCap; // Video capture filter.//省略初始化和添加到Filter Graph部分代码pBuild->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pCap, NULL, NULL);  DirectShow提供了一个捕捉静态图像的方法:使用Sample Grabber filter。依次按照以下三个步骤就可以了:  第一步, 定义一个类实现Sample Grabber的回调接口IsampleGrabberCB: class CSampleGrabberCB : public ISampleGrabberCB{  //在后面提供的类中具体完成}CSampleGrabberCB mCB;  第二步、调用RenderStream依次把Still pin、Sample Grabber和系统默认Renderer Filter连接起来。  第三步、配置Sample Grabber以捕获数据。  视频捕捉类CCaptureVideo的具体实现 // CCaptureVideo视频捕捉类头文件/////////////////////////////////////////////////////////////////////#if !defined(AFX_CAPTUREVIDEO_H__F5345AA4_A39F_4B07_B843_3D87C4287AA0__INCLUDED_)#define AFX_CAPTUREVIDEO_H__F5345AA4_A39F_4B07_B843_3D87C4287AA0__INCLUDED_/////////////////////////////////////////////////////////////////////// CaptureVideo.h : header file/////////////////////////////////////////////////////////////////////#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#include #include #include #ifndef SAFE_RELEASE#define SAFE_RELEASE( x ) \if ( NULL != x ) \{ \ x->Release( ); \ x = NULL; \}#endifclass CSampleGrabberCB;class CCaptureVideo : public CWnd { friend class CSampleGrabberCB; public:  void GrabOneFrame(BOOL bGrab);  HRESULT Init(int iDeviceID,HWND hWnd);  int EnumDevices(HWND hList);  CCaptureVideo();  virtual ~CCaptureVideo(); private:  HWND m_hWnd;  IGraphBuilder *m_pGB;  ICaptureGraphBuilder2* m_pCapture;  IBaseFilter* m_pBF;  IMediaControl* m_pMC;  IVideoWindow* m_pVW;  CComPtr m_pGrabber; protected:  void FreeMediaType(AM_MEDIA_TYPE& mt);  bool BindFilter(int deviceId, IBaseFilter **pFilter);  void ResizeVideoWindow();  HRESULT SetupVideoWindow();  HRESULT InitCaptureGraphBuilder();};#endif // !defined(AFX_CAPTUREVIDEO_H__F5345AA4_A39F_4B07_B843_3D87C4287AA0__INCLUDED_)//-------------------------------------------------------------------// CCaptureVideo视频捕捉类实现文件CaptureVideo.cpp//-------------------------------------------------------------------// CaptureVideo.cpp: implementation of the CCaptureVideo class.///////////////////////////////////////////////////////////////////////#include "stdafx.h"#include "CaptureVideo.h"#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endifBOOL bOneShot=FALSE;//全局变量class CSampleGrabberCB : public ISampleGrabberCB { public:  long lWidth;  long lHeight;  TCHAR m_szFileName[MAX_PATH];// 位图文件名称  CSampleGrabberCB( ){   strcpy(m_szFileName, "c:\\donaldo.bmp");  }   STDMETHODIMP_(ULONG) AddRef() { return 2; }  STDMETHODIMP_(ULONG) Release() { return 1; }  STDMETHODIMP QueryInterface(REFIID riid, void ** ppv){  if( riid == IID_ISampleGrabberCB || riid == IID_IUnknown ){    *ppv = (void *) static_cast ( this );   return NOERROR;  }   return E_NOINTERFACE; } STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample ){ return 0;}STDMETHODIMP BufferCB( double dblSampleTime, BYTE * pBuffer, long lBufferSize ){ if( !bOneShot )return 0;  if (!pBuffer)return E_POINTER; SaveBitmap(pBuffer, lBufferSize); bOneShot = FALSE; return 0;}//创建位图文件BOOL SaveBitmap(BYTE * pBuffer, long lBufferSize ){ HANDLE hf = CreateFile( m_szFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, NULL, NULL ); if( hf == INVALID_HANDLE_VALUE )return 0;  // 写文件头   BITMAPFILEHEADER bfh;  memset( &bfh, 0, sizeof( bfh ) );  bfh.bfType = ’MB’;  bfh.bfSize = sizeof( bfh ) lBufferSize sizeof( BITMAPINFOHEADER );  bfh.bfOffBits = sizeof( BITMAPINFOHEADER ) sizeof( BITMAPFILEHEADER );  DWORD dwWritten = 0;  WriteFile( hf, &bfh, sizeof( bfh ), &dwWritten, NULL );  // 写位图格式  BITMAPINFOHEADER bih;  memset( &bih, 0, sizeof( bih ) );  bih.biSize = sizeof( bih );  bih.biWidth = lWidth;  bih.biHeight = lHeight;  bih.biPlanes = 1;  bih.biBitCount = 24;  WriteFile( hf, &bih, sizeof( bih ), &dwWritten, NULL );  // 写位图数据  WriteFile( hf, pBuffer, lBufferSize, &dwWritten, NULL );  CloseHandle( hf );  return 0; }};CSampleGrabberCB mCB;//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////CCaptureVideo::CCaptureVideo(){ //COM Library Intialization if(FAILED(CoInitialize(NULL))) /*, COINIT_APARTMENTTHREADED)))*/ {  AfxMessageBox("CoInitialize Failed!\r\n");   return; } m_hWnd = NULL; m_pVW = NULL; m_pMC = NULL; m_pGB = NULL; m_pCapture = NULL; }CCaptureVideo::~CCaptureVideo(){ // Stop media playback if(m_pMC)m_pMC->Stop(); if(m_pVW){  m_pVW->put_Visible(OAFALSE);  m_pVW->put_Owner(NULL); } SAFE_RELEASE(m_pCapture); SAFE_RELEASE(m_pMC); SAFE_RELEASE(m_pGB); SAFE_RELEASE(m_pBF); CoUninitialize( );}int CCaptureVideo::EnumDevices(HWND hList){ if (!hList)  return -1; int id = 0; //枚举视频扑捉设备 ICreateDevEnum *pCreateDevEnum; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void**)&pCreateDevEnum); if (hr != NOERROR)return -1; CComPtr pEm; hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0); if (hr != NOERROR)return -1; pEm->Reset(); ULONG cFetched; IMoniker *pM; while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK) {  IPropertyBag *pBag;  hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);  if(SUCCEEDED(hr))   {   VARIANT var;   var.vt = VT_BSTR;   hr = pBag->Read(L"FriendlyName", &var, NULL);   if (hr == NOERROR)    {    TCHAR str[2048];     id ;    WideCharToMultiByte(CP_ACP,0,var.bstrVal, -1, str, 2048, NULL, NULL);    ::SendMessage(hList, CB_ADDSTRING, 0,(LPARAM)str);    SysFreeString(var.bstrVal);   }   pBag->Release();  }  pM->Release(); } return id;}HRESULT CCaptureVideo::Init(int iDeviceID, HWND hWnd){ HRESULT hr; hr = InitCaptureGraphBuilder(); if (FAILED(hr)){  AfxMessageBox("Failed to get video interfaces!");  return hr; } // Bind Device Filter. We know the device because the id was passed in if(!BindFilter(iDeviceID, &m_pBF))return S_FALSE; hr = m_pGB->AddFilter(m_pBF, L"Capture Filter"); // hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,  // m_pBF, NULL, NULL); // create a sample grabber hr = m_pGrabber.CoCreateInstance( CLSID_SampleGrabber ); if( !m_pGrabber ){  AfxMessageBox("Fail to create SampleGrabber, maybe qedit.dll is not registered?");  return hr; } CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabBase( m_pGrabber ); //设置视频格式 AM_MEDIA_TYPE mt;  ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE)); mt.majortype = MEDIATYPE_Video; mt.subtype = MEDIASUBTYPE_RGB24; hr = m_pGrabber->SetMediaType(&mt); if( FAILED( hr ) ){  AfxMessageBox("Fail to set media type!");  return hr; } hr = m_pGB->AddFilter( pGrabBase, L"Grabber" ); if( FAILED( hr ) ){  AfxMessageBox("Fail to put sample grabber in graph");  return hr; } // try to render preview/capture pin hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL); if( FAILED( hr ) )  hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL);  if( FAILED( hr ) ){   AfxMessageBox("Can’t build the graph");   return hr;  }  hr = m_pGrabber->GetConnectedMediaType( &mt ); if ( FAILED( hr) ){  AfxMessageBox("Failt to read the connected media type");  return hr; } VIDEOINFOHEADER * vih = (VIDEOINFOHEADER*) mt.pbFormat; mCB.lWidth = vih->bmiHeader.biWidth; mCB.lHeight = vih->bmiHeader.biHeight; FreeMediaType(mt); hr = m_pGrabber->SetBufferSamples( FALSE ); hr = m_pGrabber->SetOneShot( FALSE ); hr = m_pGrabber->SetCallback( &mCB, 1 ); //设置视频捕捉窗口 m_hWnd = hWnd ;  SetupVideoWindow(); hr = m_pMC->Run();//开始视频捕捉 if(FAILED(hr)){AfxMessageBox("Couldn’t run the graph!");return hr;} return S_OK;}bool CCaptureVideo::BindFilter(int deviceId, IBaseFilter **pFilter){ if (deviceId < 0) return false; // enumerate all video capture devices CComPtr pCreateDevEnum; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void**)&pCreateDevEnum); if (hr != NOERROR) {  return false; } CComPtr pEm; hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0); if (hr != NOERROR)  {  return false; } pEm->Reset(); ULONG cFetched; IMoniker *pM; int index = 0; while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK, index <= deviceId) {  IPropertyBag *pBag;  hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);  if(SUCCEEDED(hr))   {   VARIANT var;   var.vt = VT_BSTR;   hr = pBag->Read(L"FriendlyName", &var, NULL);   if (hr == NOERROR)    {    if (index == deviceId)    {     pM->BindToObject(0, 0, IID_IBaseFilter, (void**)pFilter);    }    SysFreeString(var.bstrVal);   }   pBag->Release();  }  pM->Release();  index ; } return true;}HRESULT CCaptureVideo::InitCaptureGraphBuilder(){ HRESULT hr; // 创建IGraphBuilder接口 hr=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&m_pGB); // 创建ICaptureGraphBuilder2接口 hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,IID_ICaptureGraphBuilder2, (void **) &m_pCapture); if (FAILED(hr))return hr; m_pCapture->SetFiltergraph(m_pGB); hr = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC); if (FAILED(hr))return hr; hr = m_pGB->QueryInterface(IID_IVideoWindow, (LPVOID *) &m_pVW); if (FAILED(hr))return hr; return hr;}HRESULT CCaptureVideo::SetupVideoWindow(){ HRESULT hr; hr = m_pVW->put_Owner((OAHWND)m_hWnd); if (FAILED(hr))return hr; hr = m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN); if (FAILED(hr))return hr; ResizeVideoWindow(); hr = m_pVW->put_Visible(OATRUE); return hr;}void CCaptureVideo::ResizeVideoWindow(){ if (m_pVW){  //让图像充满整个窗口  CRect rc;  ::GetClientRect(m_hWnd,&rc);  m_pVW->SetWindowPosition(0, 0, rc.right, rc.bottom); } }void CCaptureVideo::GrabOneFrame(BOOL bGrab){ bOneShot = bGrab;}void CCaptureVideo::FreeMediaType(AM_MEDIA_TYPE& mt){ if (mt.cbFormat != 0) {  CoTaskMemFree((PVOID)mt.pbFormat);  // Strictly unnecessary but tidier  mt.cbFormat = 0;  mt.pbFormat = NULL; } if (mt.pUnk != NULL) {  mt.pUnk->Release();  mt.pUnk = NULL; }}共2页。 1 2 : 下载本文示例代码


Visual C 编程实现摄像头视频捕捉Visual C 编程实现摄像头视频捕捉Visual C 编程实现摄像头视频捕捉Visual C 编程实现摄像头视频捕捉Visual C 编程实现摄像头视频捕捉Visual C 编程实现摄像头视频捕捉Visual C 编程实现摄像头视频捕捉Visual C 编程实现摄像头视频捕捉Visual C 编程实现摄像头视频捕捉Visual C 编程实现摄像头视频捕捉Visual C 编程实现摄像头视频捕捉Visual C 编程实现摄像头视频捕捉Visual C 编程实现摄像头视频捕捉Visual C 编程实现摄像头视频捕捉Visual C 编程实现摄像头视频捕捉
阅读(278) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~