123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- #include "StdAfx.h"
- #include "CaptureVideo.h"
- 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_pBF = NULL;
- m_pGrabber = 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);
- SAFE_RELEASE(m_pVW);
- SAFE_RELEASE(m_pGrabber);
- CoUninitialize( );
- }
- int CCaptureVideo::EnumDevices(CMFCRibbonComboBox *pCombobox)
- {
- if (!pCombobox)
- return -1;
- int id = 0;
- // 建立系统设备枚举实例;
- ICreateDevEnum *pCreateDevEnum;
- HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void**)&pCreateDevEnum);
- if (hr != NOERROR)
- {
- //CoUninitialize();
- return -1;
- }
- // 获取设备类枚举器;
- IEnumMoniker *pEnum;
- hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEnum, 0);
- if (hr != NOERROR)
- {
- //CoUninitialize();
- return -1;
- }
- CString strCurName;
- int nIndex = pCombobox->GetCurSel();
- if ( nIndex != -1 )
- strCurName = pCombobox->GetItem(nIndex);
- // 枚举设备名称;
- pEnum->Reset();
- ULONG cFetched;
- IMoniker *pM;
- pCombobox->RemoveAllItems();
- while(hr = pEnum->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);
- pCombobox->AddItem(str);
- SysFreeString(var.bstrVal);
- }
- pBag->Release();
- }
- pM->Release();
- }
- pEnum->Release();
- pEnum = NULL;
- // 如果之前有选择,恢复;
- if ( nIndex != -1 )
- pCombobox->SelectItem(strCurName);
- 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 );
- hr = CoCreateInstance( CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_ISampleGrabber, (void**)&m_pGrabber );
- 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;
- IAMStreamConfig *pSC = NULL;
- m_pCapture->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pBF, IID_IAMStreamConfig, (void **)&pSC);
- ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
- mt.majortype = MEDIATYPE_Video;
- mt.subtype = MEDIASUBTYPE_RGB32;
- mt.bTemporalCompression = FALSE;
- 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;
- // 单位为100ns,所以每帧(10^7/p3)*100ns
- vih->AvgTimePerFrame = 10000000 / 50;
- 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
- ICreateDevEnum* pCreateDevEnum;
- HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum);
- if (hr != NOERROR)
- {
- return false;
- }
- IEnumMoniker* 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++;
- }
- pEm->Release();
- pEm = NULL;
- 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;
- }
- }
|