利用directshow进行摄像头的开发

     首先,我的系统是win7的,据说win7自带directX 所以不用再另外下载directX。

在头文件中添加 #pragma comment (lib,"Strmiids") #pragma comment (lib,"quartz") #include <Dshow.h>//// 所有DirectShow应用程序必备

首先:查找视频设备列表

void CCameraDlg::GetAllCapDevices() { UINT uIndex=0; //释放视频设备列表 for(int i=0;i<NUMELMS(m_rgpmVideoMenu);i++){ IMonRelease(m_rgpmVideoMenu[i]); } //枚举所有的视频捕捉设备 ICreateDevEnum *pCreateDevEnum=0; HRESULT hr=CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,(void**)&pCreateDevEnum);//创建所有系统设备枚举 if (hr!=NOERROR) { Error(TEXT("Error Creatint Device Enumerator")); return; } IEnumMoniker *pEm=0; hr=pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm,0);//筛选出视频输入设备 if (hr!=NOERROR) { Error(TEXT("Sorry, you have no video capture hardware./r/n/r/n")); } pEm->Reset(); ULONG cFetched; IMoniker *pM; while ((hr=pEm->Next(1,&pM,&cFetched))==S_OK)//循环直到最后一个设备为止 { IPropertyBag *pBag=0; 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) { CString strDeviceName=var.bstrVal; //CString strMenuItem; //strMenuItem.Format("%d)%s",(uIndex+1),strDeviceName); SysFreeString(var.bstrVal); m_rgpmVideoMenu[uIndex]=pM; pM->AddRef(); } pBag->Release(); } pM->Release(); uIndex++; } pEm->Release(); } void CCameraDlg::IMonRelease(IMoniker *&pm) { if (pm) { pm->Release(); pm=0; } }

 

错误函数是:

 

void CCameraDlg::Error( TCHAR *pText ) { ::MessageBox(NULL,pText,TEXT("Error!"),MB_OK|MB_TASKMODAL|MB_SETFOREGROUND); }

在就是进行进行视频的连接与显示:

 HRESULT CCameraDlg::InitAndStartPreview() { if (NUMELMS(m_rgpmVideoMenu)>0) { HRESULT hr=m_rgpmVideoMenu[0]->BindToObject(0,0,IID_IBaseFilter,(void**)&m_pVcap);//将选择的设备绑定到源滤镜 if (!m_pVcap) { Error(TEXT("There is NO USB/Web Camera for video capture!Please check!")); return E_FAIL; } hr=m_pCaptureGraph.CoCreateInstance(CLSID_FilterGraph); if (!m_pCaptureGraph) { Error( TEXT("Could not create filter graph")); return E_FAIL; } hr=m_pCaptureGraph->AddFilter(m_pVcap,L"VideoPreview"); if( FAILED( hr ) ) { Error( TEXT("Could not put capture device in graph")); return E_FAIL; } hr = m_pBuilder.CoCreateInstance( CLSID_CaptureGraphBuilder2 ); if( !m_pBuilder ) { Error( TEXT("Could not create capture graph builder2")); return hr; } hr = m_pBuilder->SetFiltergraph(m_pCaptureGraph); // if(hr != NOERROR) { Error(TEXT("Cannot give graph to builder")); return E_FAIL; } //连接视频捕捉图像的Filters hr=m_pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Interleaved,m_pVcap,NULL,NULL); if (FAILED(hr)) { hr=m_pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video,m_pVcap,NULL,NULL); if (FAILED(hr)) { hr=m_pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,m_pVcap,NULL,NULL); } } // find the video window and stuff it in our window CComQIPtr< IVideoWindow, &IID_IVideoWindow > pWindow = m_pCaptureGraph; //VideoWindow接口 if( !pWindow ) { Error( TEXT("Could not get video window interface")); return E_FAIL; } // set up the preview window to be in our dialog instead of floating popup HWND hwndPreview=NULL; GetDlgItem(IDC_PREVIEW_AVI,&hwndPreview);//获得预览窗口控件的Hwnd RECT rc; ::GetWindowRect(hwndPreview,&rc); hr=pWindow->put_Owner((OAHWND)hwndPreview); hr=pWindow->put_Left(0); hr=pWindow->put_Top(0); hr=pWindow->put_Width(rc.right-rc.left); hr=pWindow->put_Height(rc.bottom-rc.top); hr=pWindow->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS); hr=pWindow->put_Visible(OATRUE); // run the filter graph,IMediaControl接口提供了数据在Filer Graph中的流向 CComQIPtr< IMediaControl, &IID_IMediaControl > pControl = m_pCaptureGraph; hr = pControl->Run( ); if( FAILED( hr ) ) { Error( TEXT("Could not run graph")); return hr; } } }

 

最好在CCameraDlg::OnInitDialog()函数中加入

CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);//初始化COM环境 ZeroMemory(m_rgpmVideoMenu, sizeof(m_rgpmVideoMenu)); GetAllCapDevices(); InitAndStartPreview();

这样就能够简单的显示了。

你可能感兴趣的:(quartz,video,filter,null,Graph,interface)