您的位置:首页 > 其它

Directshow 判断音视频设备是否被占用<转>

2017-08-31 14:27 471 查看
直接上代码吧:

代码是参考网上大神分享的,在原基础上做了些修改(只检测视频设备):

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: