直接上代码吧:
代码是参考网上大神分享的,在原基础上做了些修改(只检测视频设备):
int DeviceIsBusy(char *videoName) { //输入设备的音视频名称 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); std::wstring cs = (LPCTSTR)lpstrMsg; std::string name_; StringConverter::WStringToString(cs, name_); if (SUCCEEDED(hr)) { if (!strcmp(videoName, name_.c_str()))//存在设备 { 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; //视频设备占用 } } //如果找到设备匹配的就直接跳出循环 break; } } pPropBag->Release(); } pMoniker->Release(); } } pSysDevEnum->Release(); CoUninitialize(); return ret; }
上面代码是只检测视频设备,然后稍微改了一点逻辑。
下面是原始代码仅供参考:
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; }
转载地址:http://blog.csdn.net/ren65432/article/details/43086975
时间: 2024-10-11 05:21:28