XP下採用DirectShow採集摄像头
转载请标明是引用于 http://blog.csdn.net/chenyujing1234
欢迎大家提出意见,一起讨论!
须要演示样例源代码的请独自联系我.
前提: 摄像头能正常工作、摄像头有创建directshow filter
即
大家能够对照我的还有一篇文章学习: wince系统下DirectShow採集摄像头
一、初始化工作
1、DirctShow环境初始化
bool uEye_DirectShow_Demo_Dlg::DirectShow_Init() { // initialize the COM library on the current thread HRESULT err= CoInitialize(NULL); if( FAILED(err)) { MessageBoxEx( NULL, "Initializing COM library failed!", __FUNCTION__, MB_ICONERROR, 0); } return err == S_OK; }
2、搜索Video源
假设没有设备接入,那么CreateClassEnumerator会返回失败
bool uEye_DirectShow_Demo_Dlg::VideoSourcesList_Fill() { HRESULT status= S_OK; // create System Device Enumerator ICreateDevEnum *pSystemDeviceEnumerator= NULL; status= CoCreateInstance( CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, IID_ICreateDevEnum, (void**)&pSystemDeviceEnumerator); if( FAILED(status)) { MessageBoxEx( NULL, "Creating System Device Enumerator failed!", __FUNCTION__, MB_ICONERROR, 0); return false; } // create Class Enumerator that lists alls video input devices among the system devices IEnumMoniker *pVideoInputDeviceEnumerator= NULL; status= pSystemDeviceEnumerator->CreateClassEnumerator( CLSID_VideoInputDeviceCategory, &pVideoInputDeviceEnumerator, 0); // release the System Device Enumerator which is not needed anymore pSystemDeviceEnumerator->Release(); pSystemDeviceEnumerator= NULL; if( status != S_OK) { MessageBoxEx( NULL, "Creating Class Enumerator failed!", __FUNCTION__, MB_ICONERROR, 0); return false; } // add entry '[no device selected]' to list m_comboVideoSources.AddString( "[no device selected]"); m_comboVideoSources.SetItemDataPtr( 0, NULL); // for each enumerated video input device: add it to the list IMoniker *pMoniker= NULL; while( pVideoInputDeviceEnumerator->Next( 1, &pMoniker, NULL) == S_OK ) { VARIANT var; VariantInit(&var); // make filters properties accessible IPropertyBag *pPropBag= NULL; status= pMoniker->BindToStorage( 0, 0, IID_IPropertyBag, (void**)&pPropBag); if( FAILED(status)) { pPropBag= NULL; MessageBoxEx( NULL, "Accessing filter properties failed!", __FUNCTION__, MB_ICONERROR, 0); // continue with the next filter } else { // add a reference to the storage object pPropBag->AddRef(); // get the name of this filter status= pPropBag->Read( L"FriendlyName", &var, 0); if( FAILED(status)) { MessageBoxEx( NULL, "Reading filter name failed!", __FUNCTION__, MB_ICONERROR, 0); // continue with the next filter } else { // if uEye Capture Device: // add filtername to the list and link the moniker pointer to the list entry CString sTemp(var.bstrVal); #if (0) /* jma [04/08/2010] add devices named UI... too */ if( sTemp.Find( "uEye Capture Device", 0) != -1) #endif if ((sTemp.Find( "uEye Capture Device", 0) != -1) || (sTemp.Find( "UI", 0) != -1)) { int index = m_comboVideoSources.AddString( sTemp); // dont forget to release the moniker later! m_comboVideoSources.SetItemDataPtr( index, pMoniker); } else { pMoniker->Release(); pMoniker= NULL; } } // release the reference to the storage object pPropBag->Release(); pPropBag= NULL; } VariantClear(&var); } // release the class enumerator pVideoInputDeviceEnumerator->Release(); pVideoInputDeviceEnumerator= NULL; // select first list entry m_comboVideoSources.SetCurSel( 0); return false; }
二、选择某个摄像设备
1、先停止原有的Media
bool uEye_DirectShow_Demo_Dlg::FilterGraph_Stop() { Invalidate(); // proceed only if filter graph manager object present if( m_pActiveFilterGraphManager == NULL) { return true; } HRESULT status= S_OK; // get the MediaControl interface of the graph IMediaControl* pMediaControl= NULL; status= m_pActiveFilterGraphManager->QueryInterface( IID_IMediaControl, (void**)&pMediaControl); if( FAILED(status) || pMediaControl == NULL) { MessageBoxEx( NULL, "Querying MediaControl interface of the filter graph manager failed!", __FUNCTION__, MB_ICONERROR, 0); return false; } //// check for graph to be executing before allowing to stop //OAFilterState filterState= 0; // OAFilterState is actually a long //status= pMediaControl->GetState( 100, &filterState); //if( FAILED(status)) //{ // // cleanup // // release the MediaControl interface object // pMediaControl->Release(); // pMediaControl= NULL; // MessageBoxEx( NULL, "Querying graph state failed!", __FUNCTION__, MB_ICONERROR, 0); // return false; //} //if( filterState != State_Stopped) { // stop the execution of the graph status= pMediaControl->Stop(); if( FAILED(status)) { // cleanup // release the MediaControl interface object pMediaControl->Release(); pMediaControl= NULL; MessageBoxEx( NULL, "Stopping the graph failed!", __FUNCTION__, MB_ICONERROR, 0); return false; } // update the graph state view UpdateGraphState( State_Stopped); } // release the MediaControl interface object pMediaControl->Release(); pMediaControl= NULL; return true; }
2、删除Graph
bool uEye_DirectShow_Demo_Dlg::FilterGraph_Destroy() { // proceed only if filter graph manager object present if( m_pActiveFilterGraphManager == NULL) { return true; } if( !FilterGraph_Stop()) { return false; } // disable 'dump graph' button as long as no graph present m_bnDumpGraph.EnableWindow( FALSE); // delete the capture filter m_pActiveVideoSource->Release(); m_pActiveVideoSource= NULL; // delete the graph m_pActiveFilterGraphManager->Release(); m_pActiveFilterGraphManager= NULL; // update the graph state view UpdateGraphState( -1); return true; }
3、依据选择的设备的moniker来创建Graph
分为:
(1)为选择的设备创建capture filter
status= pMoniker->BindToObject( 0, 0, IID_IBaseFilter, (void**)&m_pActiveVideoSource);
(2) 创建一个capture Graph Builder对象
ICaptureGraphBuilder2* pCaptureGraphBuilder= NULL;
status= CoCreateInstance( CLSID_CaptureGraphBuilder2,
NULL,
CLSCTX_INPROC,
IID_ICaptureGraphBuilder2,
(void**)&pCaptureGraphBuilder);
(3) 创建 Filter Graph Manager
// create the Filter Graph Manager
status= CoCreateInstance( CLSID_FilterGraph,
NULL,
CLSCTX_INPROC,
IID_IGraphBuilder,
(void **)&m_pActiveFilterGraphManager);
(4) 初始化Capture Graph Builder 对象,把graph和builder 连接起来
status= pCaptureGraphBuilder->SetFiltergraph( m_pActiveFilterGraphManager);
(5) 添加Capture到graph中
status= m_pActiveFilterGraphManager->AddFilter( m_pActiveVideoSource, L"Video Capture");
(6) render 视频的capture pin, 把caputre filter和render连接起来
status= pCaptureGraphBuilder->RenderStream( &PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video,
m_pActiveVideoSource,
NULL,
NULL);
(7) 查询filter graph manager的VideoWindow接口
IVideoWindow* pVideoWindow= NULL;
status= m_pActiveFilterGraphManager->QueryInterface( IID_IVideoWindow, (void**)&pVideoWindow);
(8) 把video view连接到graph
// connect the dialogs video view to the graph
CWnd* pwnd= GetDlgItem( IDC_STATIC_VIDEOVIEW);
pVideoWindow->put_Owner( (OAHWND)pwnd->m_hWnd); // put_Owner always returns NOERROR
// we dont want a title bar on our video view
long pWindowStyle = 0;
pVideoWindow->get_WindowStyle(&pWindowStyle);
pWindowStyle &= ~WS_CAPTION;
pVideoWindow->put_WindowStyle(pWindowStyle);
// adjust graphs video geometry
CRect rc( 0, 0, 0, 0);
pwnd->GetClientRect( &rc);
pVideoWindow->SetWindowPosition( rc.left, rc.top, rc.Width(), rc.Height());
// release the VideoWindow interface object, we do not need it anymore
pVideoWindow->Release();
四、 開始播放
bool uEye_DirectShow_Demo_Dlg::FilterGraph_Start() { // proceed only if filter graph manager object present if( m_pActiveFilterGraphManager == NULL) { return true; } HRESULT status= S_OK; // get the MediaControl interface of the graph IMediaControl* pMediaControl= NULL; status= m_pActiveFilterGraphManager->QueryInterface( IID_IMediaControl, (void**)&pMediaControl); if( FAILED(status) || pMediaControl == NULL) { MessageBoxEx( NULL, "Querying MediaControl interface of the filter graph manager failed!", __FUNCTION__, MB_ICONERROR, 0); return false; } //// check for graph to be stopped before allowing to start //OAFilterState filterState= 0; // OAFilterState is actually a long //status= pMediaControl->GetState( 100, &filterState); //if( FAILED(status)) //{ // // cleanup // // release the MediaControl interface object // pMediaControl->Release(); // pMediaControl= NULL; // MessageBoxEx( NULL, "Querying graph state failed!", __FUNCTION__, MB_ICONERROR, 0); // return false; //} //if( filterState == State_Stopped) { // start the execution of the graph status= pMediaControl->Run(); if( FAILED(status)) { // cleanup // release the MediaControl interface object pMediaControl->Release(); pMediaControl= NULL; MessageBoxEx( NULL, "Starting the graph failed!", __FUNCTION__, MB_ICONERROR, 0); return false; } // update the graph state view UpdateGraphState( State_Running); } // release the MediaControl interface object pMediaControl->Release(); pMediaControl= NULL; return true; }
五、 pin 特征的查看
假设pin里有自己的查看特征接口, 那么就直接调用接口
bool uEye_DirectShow_Demo_Dlg::ShowPinProperties() { // proceed only if video source object present if( m_pActiveVideoSource == NULL) { return true; } HRESULT status= S_OK; IPin* pPin= GetPin( m_pActiveVideoSource, PINDIR_OUTPUT, &MEDIATYPE_Video, &PIN_CATEGORY_CAPTURE); if( pPin == NULL) { MessageBoxEx( NULL, "Pin not available!", __FUNCTION__, MB_ICONERROR, 0); return false; } IUnknown* pFilterUnk= NULL; status= pPin->QueryInterface( IID_IUnknown, (void**)&pFilterUnk); if( FAILED(status)) { // cleanup pPin->Release(); pPin= NULL; MessageBoxEx( NULL, "Querying pin's IAMStreamConfig interface failed!", __FUNCTION__, MB_ICONERROR, 0); return false; } ISpecifyPropertyPages* pSpecifyPropertyPages= NULL; status= pFilterUnk->QueryInterface( IID_ISpecifyPropertyPages, (void**)&pSpecifyPropertyPages); if( FAILED(status)) { // cleanup pFilterUnk->Release(); pFilterUnk= NULL; pPin->Release(); pPin= NULL; MessageBoxEx( NULL, "Querying pin's ISpecifyPropertyPages interface failed!", __FUNCTION__, MB_ICONERROR, 0); return false; } CAUUID cauuid= { 0, NULL}; status= pSpecifyPropertyPages->GetPages( &cauuid); if( FAILED(status)) { // cleanup pSpecifyPropertyPages->Release(); pSpecifyPropertyPages->Release(); pSpecifyPropertyPages= NULL; pFilterUnk->Release(); pFilterUnk= NULL; pPin->Release(); pPin= NULL; MessageBoxEx( NULL, "Querying pin's ISpecifyPropertyPages interface failed!", __FUNCTION__, MB_ICONERROR, 0); return false; } pSpecifyPropertyPages->Release(); pSpecifyPropertyPages->Release(); pSpecifyPropertyPages= NULL; status= OleCreatePropertyFrame( GetSafeHwnd(),//*this, 0, 0, OLESTR("uEye Capture Device Pin"), 1, (IUnknown**)&pFilterUnk, cauuid.cElems, (GUID*)cauuid.pElems, 0, 0, NULL); if( FAILED(status)) { // cleanup CoTaskMemFree( cauuid.pElems); cauuid.pElems= NULL; cauuid.cElems= 0; pFilterUnk->Release(); pFilterUnk= NULL; pPin->Release(); pPin= NULL; MessageBoxEx( NULL, "OleCreatePropertyFrame failed!", __FUNCTION__, MB_ICONERROR, 0); return false; } // cleanup CoTaskMemFree( cauuid.pElems); cauuid.pElems= NULL; cauuid.cElems= 0; pFilterUnk->Release(); pFilterUnk= NULL; pPin->Release(); pPin= NULL; return true; }
六、 查询包括的 filter信息
bool uEye_DirectShow_Demo_Dlg::EnumerateFilters() { // proceed only if filter graph builder object present if( m_pActiveFilterGraphManager == NULL) { return false; } IEnumFilters *pEnum = NULL; IBaseFilter *pFilter; ULONG cFetched; HRESULT hr = m_pActiveFilterGraphManager->EnumFilters(&pEnum); if (FAILED(hr)) { MessageBoxEx( NULL, "Enumerating filters failed!", __FUNCTION__, MB_ICONERROR, 0); return false; } CString sInfo( "Filters in the Graph:\n\n"); int i= 0; while(pEnum->Next(1, &pFilter, &cFetched) == S_OK) { i++; FILTER_INFO FilterInfo; hr = pFilter->QueryFilterInfo(&FilterInfo); if (FAILED(hr)) { MessageBoxEx( NULL, "Could not get the filter info", __FUNCTION__, MB_ICONERROR, 0); continue; // Maybe the next one will work. } LPWSTR pVendorInfo= NULL; hr= pFilter->QueryVendorInfo( &pVendorInfo); if( FAILED(hr)) { pVendorInfo= NULL; } if( pVendorInfo != NULL) { sInfo.AppendFormat( "%d: %S (by %S)\n", i, FilterInfo.achName, pVendorInfo); CoTaskMemFree( pVendorInfo); pVendorInfo= NULL; } else { sInfo.AppendFormat( "%d: %S\n", i, FilterInfo.achName); } // The FILTER_INFO structure holds a pointer to the Filter Graph // Manager, with a reference count that must be released. if (FilterInfo.pGraph != NULL) { FilterInfo.pGraph->Release(); } pFilter->Release(); } pEnum->Release(); MessageBoxEx( NULL, sInfo.GetBuffer(), __FUNCTION__, MB_OK, 0); return true; }