Directshow 如何获取摄像头音视频设备,并判断摄像头是否占用。

来源:互联网 发布:淘宝保健品店 编辑:程序博客网 时间:2024/05/21 02:19

Directshow 能很方便的获取连接的 视频和音频设备的名称。本篇文章同时介绍如何判断获取的摄像头是否正在占用。


代码如下:


(1) 获取摄像头音视频设备名称

void CDeviceTree::EnumDevices(){hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pSysDevEnum);hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0);//将CLSID_VideoInputDeviceCategory 改成 CLSID_AudioInputDeviceCategory 即能获取音频设备if (FAILED(hr)){return;}if(hr == S_OK){ULONG cFetched;while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK){IPropertyBag* pPropBag;hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPropBag);if(SUCCEEDED(hr)){VARIANT varName;varName.vt=VT_BSTR;VariantInit(&varName);hr = pPropBag->Read(L"FriendlyName", &varName, 0);USES_CONVERSION;LPTSTR lpstrMsg = W2T(varName.bstrVal);if(SUCCEEDED(hr)){//videoDev[videoIndex]=lpstrMsg;//videoIndex++;//此处即得到获得的视频设备名称  你可以将它打印出来 或者存入队列}pPropBag->Release();}pMoniker->Release();}}}


(2) 判断摄像头是否占用。

int DeviceIsBusy(char *videoName,char *audioName){//输入设备的音视频名称HRESULT hr;HRESULT hhr;int ret=0;int videoBusy=1;int audioBusy=1;CoInitialize(NULL);ICreateDevEnum* pSysDevEnum = NULL;hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pSysDevEnum);IEnumMoniker* pEnumCat ;hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0);if(hr == S_OK){IMoniker* pMoniker = NULL;IMoniker* pm1=NULL;ULONG cFetched;while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK){IPropertyBag* pPropBag;hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPropBag);if(SUCCEEDED(hr)){VARIANT varName;varName.vt=VT_BSTR;VariantInit(&varName);hr = pPropBag->Read(L"FriendlyName", &varName, 0);USES_CONVERSION;LPTSTR lpstrMsg = W2T(varName.bstrVal);if(SUCCEEDED(hr)){if (!strcmp(videoName,lpstrMsg))//存在设备{LPBC *pbc=NULL;IBaseFilter *P_VCamTrans=NULL;IBaseFilter *pCap=NULL;CreateBindCtx(0,pbc);hr=pMoniker->BindToObject((IBindCtx *)pbc,0,IID_IBaseFilter,(void **)&pCap); ICaptureGraphBuilder2 *m_pCapGB;    IGraphBuilder *m_pGB;   IMediaControl *m_pMC;   IVideoWindow   *m_pVW;hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&m_pGB);  if (FAILED(hr)) return hr;  m_pGB->AddFilter(pCap,NULL);hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void **)&m_pCapGB);  if (FAILED(hr)) return hr;  m_pCapGB->SetFiltergraph(m_pGB);IAMCrossbar *pXBar1 = NULL;hr=m_pCapGB->FindInterface(&LOOK_UPSTREAM_ONLY,NULL,pCap,IID_IAMCrossbar,(void **)&pXBar1);if (SUCCEEDED(hr)){long OutputPinCount;long InputPinCount;long PinIndexRelated;long PhysicalType;long inPort = 0;long outPort = 0;pXBar1->get_PinCounts(&OutputPinCount,&InputPinCount);//对于存在输入输出引脚的摄像头。此处采用轮询所有的引脚 for(int i =0;i<InputPinCount;i++){pXBar1->get_CrossbarPinInfo(TRUE,i,&PinIndexRelated,&PhysicalType);if(PhysConn_Video_Composite==PhysicalType){inPort = i;break;}}for(int i =0;i<OutputPinCount;i++){pXBar1->get_CrossbarPinInfo(FALSE,i,&PinIndexRelated,&PhysicalType);if(PhysConn_Video_VideoDecoder==PhysicalType){outPort = i;break;}}for (int i=0;i<InputPinCount;i++){for (int j=0;j<OutputPinCount;j++){if(S_OK==pXBar1->CanRoute(j,i)){pXBar1->Route(j,i);m_pGB->AddFilter(pCap, L"Capture Filter");m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);hr = m_pGB->QueryInterface(IID_IVideoWindow,(LPVOID*)&m_pVW);hr = m_pCapGB->RenderStream(NULL, NULL, pCap, NULL, P_VCamTrans);hr = m_pVW->put_Owner((OAHWND)NULL); hr = m_pVW->put_WindowStyle( WS_CHILD | WS_CLIPCHILDREN);hr = m_pVW->put_Visible(OAFALSE);   hr=m_pVW->put_AutoShow(OAFALSE);hhr=m_pMC->StopWhenReady();if (SUCCEEDED(hhr)){videoBusy=0;}}}}if (videoBusy == 1){ret=-1; //视频设备占用}}else{m_pGB->AddFilter(pCap, L"Capture Filter");m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);hr = m_pGB->QueryInterface(IID_IVideoWindow,(LPVOID*)&m_pVW);hr = m_pCapGB->RenderStream(NULL, NULL, pCap, NULL, P_VCamTrans);hr = m_pVW->put_Owner((OAHWND)NULL); hr = m_pVW->put_WindowStyle( WS_CHILD | WS_CLIPCHILDREN);hr = m_pVW->put_Visible(OAFALSE);   hr=m_pVW->put_AutoShow(OAFALSE);hhr=m_pMC->StopWhenReady();if (FAILED(hhr)){ret=-1;  //视频设备占用}}}}pPropBag->Release();}pMoniker->Release();}}//判断音频的方法和上面的一样 重复。hr = pSysDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory, &pEnumCat, 0);if(hr == S_OK){IMoniker* pMoniker = NULL;IMoniker* pm1=NULL;ULONG cFetched;while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK){IPropertyBag* pPropBag;hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPropBag);if(SUCCEEDED(hr)){VARIANT varName;varName.vt=VT_BSTR;VariantInit(&varName);hr = pPropBag->Read(L"FriendlyName", &varName, 0);USES_CONVERSION;LPTSTR lpstrMsg = W2T(varName.bstrVal);if(SUCCEEDED(hr)){if (!strcmp(videoName,lpstrMsg))//存在设备{LPBC *pbc=NULL;IBaseFilter *P_VCamTrans=NULL;IBaseFilter *pCap=NULL;CreateBindCtx(0,pbc);hr=pMoniker->BindToObject((IBindCtx *)pbc,0,IID_IBaseFilter,(void **)&pCap); ICaptureGraphBuilder2 *m_pCapGB;    IGraphBuilder *m_pGB;   IMediaControl *m_pMC;   IVideoWindow   *m_pVW;hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&m_pGB);  if (FAILED(hr)) return hr;  m_pGB->AddFilter(pCap,NULL);hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void **)&m_pCapGB);  if (FAILED(hr)) return hr;  m_pCapGB->SetFiltergraph(m_pGB);IAMCrossbar *pXBar1 = NULL;hr=m_pCapGB->FindInterface(&LOOK_UPSTREAM_ONLY,NULL,pCap,IID_IAMCrossbar,(void **)&pXBar1);if (SUCCEEDED(hr)){long OutputPinCount;long InputPinCount;long PinIndexRelated;long PhysicalType;long inPort = 0;long outPort = 0;pXBar1->get_PinCounts(&OutputPinCount,&InputPinCount);for(int i =0;i<InputPinCount;i++){pXBar1->get_CrossbarPinInfo(TRUE,i,&PinIndexRelated,&PhysicalType);if(PhysConn_Video_Composite==PhysicalType){inPort = i;break;}}for(int i =0;i<OutputPinCount;i++){pXBar1->get_CrossbarPinInfo(FALSE,i,&PinIndexRelated,&PhysicalType);if(PhysConn_Video_VideoDecoder==PhysicalType){outPort = i;break;}}for (int i=0;i<InputPinCount;i++){for (int j=0;j<OutputPinCount;j++){if(S_OK==pXBar1->CanRoute(j,i)){pXBar1->Route(j,i);m_pGB->AddFilter(pCap, L"Capture Filter");m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);hr = m_pGB->QueryInterface(IID_IVideoWindow,(LPVOID*)&m_pVW);hr = m_pCapGB->RenderStream(NULL, NULL, pCap, NULL, P_VCamTrans);hr = m_pVW->put_Owner((OAHWND)NULL); hr = m_pVW->put_WindowStyle( WS_CHILD | WS_CLIPCHILDREN);hr = m_pVW->put_Visible(OAFALSE);   hr=m_pVW->put_AutoShow(OAFALSE);hhr=m_pMC->StopWhenReady();if (SUCCEEDED(hhr)){audioBusy=0;}}}}if (audioBusy == 1){ret=-1; //音频设备占用}}else{m_pGB->AddFilter(pCap, L"Capture Filter");m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);hr = m_pGB->QueryInterface(IID_IVideoWindow,(LPVOID*)&m_pVW);hr = m_pCapGB->RenderStream(NULL, NULL, pCap, NULL, P_VCamTrans);hr = m_pVW->put_Owner((OAHWND)NULL); hr = m_pVW->put_WindowStyle( WS_CHILD | WS_CLIPCHILDREN);hr = m_pVW->put_Visible(OAFALSE);   hr=m_pVW->put_AutoShow(OAFALSE);hhr=m_pMC->StopWhenReady();if (FAILED(hhr)){ret=-1;  //音频设备占用}}}}pPropBag->Release();}pMoniker->Release();}}pSysDevEnum->Release();CoUninitialize();return ret;}



(3)头文件

#include "windows.h"#include "stdio.h"#include "string.h"#include <string>#include "Dshow.h"#include "atlconv.h"#pragma   comment(lib,"Strmiids.lib")   #pragma   comment(lib,"Quartz.lib")

1 0
原创粉丝点击