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协议进行设备的发现, ...
随机推荐
- 在exsi6.0中安装debian8.1 64位 无界面服务器版.
之前介绍了exsi6.0的安装. 现在开始应用. 上一篇介绍的exsi6.0是安装在U盘上的系统.U盘为群联芯片,芯片型号为2251-50/30.容量为2G.发现容量足够用.比较节省成本. 现在开始为 ...
- 拦截器springmvc防止表单重复提交【3】3秒后自动跳回首页【重点明白如何跳转到各自需要的页面没有实现 但是有思路】
[1]定义异常类 [重点]:异常类有个多参数的构造函数public CmsException(String s, String... args),可以用来接受多个参数:如(“异常信息”,“几秒跳转”, ...
- (转)spring AOP探索
原文地址:http://www.cnblogs.com/zuoxiaolong/p/spring6.html 自己整理后,供自己学习方便: 目前由AOP联盟给出了AOP的标准,AOP联盟的规范只是提供 ...
- linux vi详解
刚开始学着用linux,对vi命令不是很熟,在网上转接了一篇. vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下它的用法和一小部分指 ...
- flask第十六篇——Response【2】
今天来介绍自定义返回对象: 现在我们假定有一个需求:所有的视图函数都要返回json格式的对象我们先看一下Response的源码: 发现只有一行default_mimetype='text/html', ...
- LeetCode 739. Daily Temperatures
原题链接在这里:https://leetcode.com/problems/daily-temperatures/description/ 题目: Given a list of daily temp ...
- lapis cockroachdb 数据访问试用
备注: cockroachdb 的安装可以参考官方文档,以下实例代码使用的是官方的参考例子 1. 数据库配置 // config.lua 参考: local config = require( ...
- jasmine 使用
1. 下载浏览器运行测试包 https://github.com/jasmine/jasmine/releases 2. 解压,运行包含的测试 SpecRunner.html 3. 测试结果 ...
- qqbot 配置
qqbot 配置 用起来还是挺方便的,使用 pip install qqbot 就可以. 不过找配置文件没注意,以为是在程序目前,原来是在 C:\Users\xxx.qqbot-tmp 目录. 插件可 ...
- Unit01: Servlet基础 、 HTTP协议
Unit01: Servlet基础 . HTTP协议 在页面上输出当前时间 package web; import java.io.IOException; import java.io.PrintW ...