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协议进行设备的发现, ...
随机推荐
- 安装hadoop 2.2.0
安装环境为 CentOS 64位系统, 大概分下面几个步奏, 0. 安装JDK1. 配置SSH2. 配置/etc/hosts3. 拷贝hadoop包到没台机器上4. 修改hadoop配置文件5. 关闭 ...
- BZOJ1563 NOI2009 诗人小G【决策单调性优化DP】
LINK 因为是图片题就懒得挂了 简要题意:有n个串,拼接两个串需要加一个空格,给你l和p,问你拼接后每个串的总长减l的绝对值的p次方的最小值 首先打表发现一下这题是决策单调的对于所有数据都成立就当他 ...
- 51nod 1244 莫比乌斯函数之和 【杜教筛】
51nod 1244 莫比乌斯函数之和 莫比乌斯函数,由德国数学家和天文学家莫比乌斯提出.梅滕斯(Mertens)首先使用μ(n)(miu(n))作为莫比乌斯函数的记号.具体定义如下: 如果一个数包含 ...
- 如何使用 MSBuild Target(Exec)中的控制台输出
我曾经写过一篇文章 如何创建一个基于命令行工具的跨平台的 NuGet 工具包,通过编写一个控制台程序来参与编译过程.但是,相比于 基于 Task 的方式,可控制的因素还是太少了. 有没有什么办法能够让 ...
- Django之tag标签和filter标签
1.Django的tag常见的标签,可以做一些简单的功能 {%if%} 的使用主要用于做判断,还可以包含{%elif%} 这样的用法,最后要跟上{% endif %}.可以使用你的and,or,not ...
- 实例-系数可配置的fir滤波器
- BZOJ1725,POJ3254 [Usaco2006 Nov]Corn Fields牧场的安排
题意 Farmer John新买了一块长方形的牧场,这块牧场被划分成M列N行\((1 \leq M \leq 12, 1 \leq N \leq 12)\),每一格都是一块正方形的土地.FJ打算在牧场 ...
- docker windows 2016 安装测试
1. 安装方式 powershell Install-Module-NameDockerMsftProvider-RepositoryPSGallery-Force Install-Pack ...
- 使用AWK分析Oracle系统锁定、Hang状态
在早期Oracle版本中,由于技术不成熟等原因,数据库锁定和僵死状态还是时有发生的.对待这些问题,老先生们的处理策略无外乎是“重启”和“考究”两种策略.所谓“重启”,通过强制的重启服务器或者数据库,将 ...
- mysql binlog_format row and Statement 比较
两种模式的对比: Statement 优点 历史悠久,技术成熟: 产生的 binlog 文件较小: binlog 中包含了所有数据库修改信息,可以据此来审核数据库的安全等情况: binlog 可以用于 ...