Directshow 判断音视频设备是否被占用<转>
直接上代码吧:
代码是参考网上大神分享的,在原基础上做了些修改(只检测视频设备):
int DeviceIsBusy(char *videoName)
{
//输入设备的音视频名称
HRESULT hr;
HRESULT hhr;
int ret = ;
int videoBusy = ;
int audioBusy = ; 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, ); if (hr == S_OK)
{
IMoniker* pMoniker = NULL;
IMoniker* pm1 = NULL;
ULONG cFetched; while (pEnumCat->Next(, &pMoniker, &cFetched) == S_OK)
{
IPropertyBag* pPropBag;
hr = pMoniker->BindToStorage(, , IID_IPropertyBag, (void**)&pPropBag); if (SUCCEEDED(hr))
{ VARIANT varName;
varName.vt = VT_BSTR; VariantInit(&varName); hr = pPropBag->Read(L"FriendlyName", &varName, ); 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(, pbc); hr = pMoniker->BindToObject((IBindCtx *)pbc, , 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 = ;
long outPort = ; pXBar1->get_PinCounts(&OutputPinCount, &InputPinCount); //对于存在输入输出引脚的摄像头。此处采用轮询所有的引脚
for (int i = ; i < InputPinCount; i++)
{
pXBar1->get_CrossbarPinInfo(TRUE, i, &PinIndexRelated, &PhysicalType); if (PhysConn_Video_Composite == PhysicalType)
{
inPort = i;
break;
} } for (int i = ; i < OutputPinCount; i++)
{
pXBar1->get_CrossbarPinInfo(FALSE, i, &PinIndexRelated, &PhysicalType); if (PhysConn_Video_VideoDecoder == PhysicalType)
{
outPort = i;
break;
}
} for (int i = ; i < InputPinCount; i++)
{
for (int j = ; 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 = ;
} }
}
} if (videoBusy == )
{
ret = -; //视频设备占用
}
}
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 = -; //视频设备占用
} }
//如果找到设备匹配的就直接跳出循环
break;
} } pPropBag->Release(); }
pMoniker->Release();
} }
pSysDevEnum->Release(); CoUninitialize(); return ret;
}
上面代码是只检测视频设备,然后稍微改了一点逻辑。
下面是原始代码仅供参考:
int DeviceIsBusy(char *videoName,char *audioName)
{
//输入设备的音视频名称
HRESULT hr;
HRESULT hhr;
int ret=;
int videoBusy=;
int audioBusy=; 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, ); if(hr == S_OK)
{
IMoniker* pMoniker = NULL;
IMoniker* pm1=NULL;
ULONG cFetched; while(pEnumCat->Next(, &pMoniker, &cFetched) == S_OK)
{
IPropertyBag* pPropBag;
hr = pMoniker->BindToStorage(, , IID_IPropertyBag, (void**)&pPropBag); if(SUCCEEDED(hr))
{ VARIANT varName;
varName.vt=VT_BSTR; VariantInit(&varName); hr = pPropBag->Read(L"FriendlyName", &varName, ); 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(,pbc); hr=pMoniker->BindToObject((IBindCtx *)pbc,,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 = ;
long outPort = ; pXBar1->get_PinCounts(&OutputPinCount,&InputPinCount); //对于存在输入输出引脚的摄像头。此处采用轮询所有的引脚
for(int i =;i<InputPinCount;i++)
{
pXBar1->get_CrossbarPinInfo(TRUE,i,&PinIndexRelated,&PhysicalType); if(PhysConn_Video_Composite==PhysicalType)
{
inPort = i;
break;
} } for(int i =;i<OutputPinCount;i++)
{
pXBar1->get_CrossbarPinInfo(FALSE,i,&PinIndexRelated,&PhysicalType); if(PhysConn_Video_VideoDecoder==PhysicalType)
{
outPort = i;
break;
}
} for (int i=;i<InputPinCount;i++)
{
for (int j=;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=;
} }
}
} if (videoBusy == )
{
ret=-; //视频设备占用
}
}
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=-; //视频设备占用
} } } } pPropBag->Release(); }
pMoniker->Release();
} } //判断音频的方法和上面的一样 重复。
hr = pSysDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory, &pEnumCat, ); if(hr == S_OK)
{
IMoniker* pMoniker = NULL;
IMoniker* pm1=NULL;
ULONG cFetched; while(pEnumCat->Next(, &pMoniker, &cFetched) == S_OK)
{
IPropertyBag* pPropBag;
hr = pMoniker->BindToStorage(, , IID_IPropertyBag, (void**)&pPropBag); if(SUCCEEDED(hr))
{ VARIANT varName;
varName.vt=VT_BSTR; VariantInit(&varName); hr = pPropBag->Read(L"FriendlyName", &varName, ); 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(,pbc); hr=pMoniker->BindToObject((IBindCtx *)pbc,,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 = ;
long outPort = ; pXBar1->get_PinCounts(&OutputPinCount,&InputPinCount); for(int i =;i<InputPinCount;i++)
{
pXBar1->get_CrossbarPinInfo(TRUE,i,&PinIndexRelated,&PhysicalType); if(PhysConn_Video_Composite==PhysicalType)
{
inPort = i;
break;
} } for(int i =;i<OutputPinCount;i++)
{
pXBar1->get_CrossbarPinInfo(FALSE,i,&PinIndexRelated,&PhysicalType); if(PhysConn_Video_VideoDecoder==PhysicalType)
{
outPort = i;
break;
}
} for (int i=;i<InputPinCount;i++)
{
for (int j=;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=;
} }
}
} if (audioBusy == )
{
ret=-; //音频设备占用
}
}
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=-; //音频设备占用
} } } } pPropBag->Release(); }
pMoniker->Release();
} } pSysDevEnum->Release(); CoUninitialize(); return ret;
}
转载地址:http://blog.csdn.net/ren65432/article/details/43086975
Directshow 判断音视频设备是否被占用<转>的更多相关文章
- DirectShow .Net 实现视频
DirectShow .Net 实现视频 .获取视频采集设备IBaseFilter接口对象的方法 //获取所有视频设备名称 public ArrayList GetVideoInputDevice() ...
- DirectShow 获取音视频输入设备列表
开发环境:Win10 + VS2015 本文介绍一个 "获取音频视频输入设备列表" 的示例代码. 效果图 代码下载 代码下载(VC2015):Github - DShow_simp ...
- Linux 视频设备驱动V4L2最常用的控制命令
http://blog.csdn.net/shaolyh/article/details/6583226 Linux 视频设备驱动V4L2最常用的控制命令使用说明(1.02) 命令 功能 VIDIOC ...
- DirectShow控制台输出和保存视频设备名称
#include "windows.h" #include "TCHAR.h" #include <dshow.h> #include <ve ...
- DirectShow建立一个视频捕捉程序
DirectShow 提供了用应用程序从适当的硬件中捕捉和预览音/视频的能力.数据源包括:VCR,camera,TV tuner,microphone,或其他的数据源.一个应用程序可以立刻显示捕捉的数 ...
- 基于DirectShow的MPEG-4视频传输系统的研究与实现
1 引言 近年来,随着国民经济的发展,社会各个部门对于视频监视系统的需求越来越多.但目前的很多监视系统都跟具体的硬件相关,必须要具体的采集卡的支持才能实现.所以有必要开发一种具有通用性的视频监 ...
- 摘录DirectShow数据,视频采集
DirectShow在,数据流(Data Flow)它们是依次流过每Filter的.管理其数据具有其自己的方法,并且并没有向用户提供一个统一的接口,供用户操作数据流.这里以提取视频採集在的每帧为位图数 ...
- [lsof]lsof查看哪些设备/文件被占用或者打开
转自:http://blog.csdn.net/yuzhihui_no1/article/details/51767516 最近在查一个Bug,应用程序kill之后重启,总是会出现adc的设备open ...
- EasyNVR网页摄像机无插件H5、谷歌Chrome直播方案中使用Onvif协议控制视频设备预置位转动
EasyNVR支持预置位控制,包括转到指定预置位,设置指定预置位,删除指定预置位.预置位在安防领域有较为普遍的应用,可以进行很多既定位置的跳转,很方便.之前我们说过如何用Onvif协议进行设备的发现, ...
随机推荐
- Ubuntu 12.04 LTS 安裝无线网卡驱动
1,当然,首先下载得到驱动的源代码: 2,解压缩到指定位置,我就是用鼠标拖到 home 里面: 3,进入驱动所在目录 CD ~/mt7610u,(我将解压缩出来的驱动目录改名为 mt7610u 这个了 ...
- ubuntu查看进程端口号及运行的程序
查看进程端口号及运行的程序:netstat -atunp 根据端口号来查看进程号:lsof -i:16031
- 微软 Windows 系统检测网络连通性(用于显示感叹号)竟然是通过访问一个特殊网址来实现的
一次我走到了弱网环境中,意外地发现浏览器打开了 http://www.msftconnecttest.com/redirect 网址,随后右下角的网络图标出现了一枚“感叹号”. 吹水的推断 从直观 ...
- 如何将常规的web 应用程序转化为云上多租户 SaaS 解决方案
如何将web 应用程序转化为多租户 SaaS 解决方案 https://www.ibm.com/developerworks/cn/cloud/library/cl-multitenantsaas/i ...
- eclipse添加propedit插件
1.propedit插件 这个插件基本上可以支持各种语言的转换. 2.方法如下: “help”--“Install new software”--“add” name:propedit Locatio ...
- 《DSP using MATLAB》示例Example 8.26
代码: %% ------------------------------------------------------------------------ %% Output Info about ...
- 《DSP using MATLAB》示例Example 8.14
%% ------------------------------------------------------------------------ %% Output Info about thi ...
- python 客户端点对点通信小案例
点对点通讯分为客户端和服务器,多个客户端通过服务器进行信息的交流 服务器端代码 service端 #!/usr/bin/env python # -*- coding:utf-8 -*- impor ...
- h5移动端flexible源码适配终端解读以及常用sass函数
;(function(win, lib) { var doc = win.document;// win = window,lib = window.lib; var docEl = doc.docu ...
- 顺丰品牌研究http://www.kiees.cn/sf/express/brand.htm
顺丰控股股份有限公司,顺丰速运SF,始于1993年,国内速递行业中民族品牌的佼佼者,以其速度快/安全性能高蜚声业界,现已开通海外快递服务,2017年2月完成借壳上市 1993年,顺丰诞生于广东顺德.自 ...