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协议进行设备的发现, ...
随机推荐
- 推荐近乎免费的调试神器——OzCode
当一只断点打在 Visual Studio 的代码编辑器中,程序命中断点的那一刻,调试才刚刚开始……这个时候忙碌的手在键盘和鼠标之间来回跳跃,试图抓住每一次单步执行带来的状态改变. 如果命中断点的那一 ...
- flask第十四篇——重定向
我们都知道京东的url是www.jd.com,但是当你输入www.jingdong.com时候,你会发现地址自动跳转到了www.jd.com,这种技术手段就叫做重定向. 重定向分为永久重定向和临时重定 ...
- yum方式安装的Apache目录详解和配置说明
在对httpd.conf文件进行解读之前,首先了解一下Redhat9中Apache服务器默认配置的一些基本信息:配置文件:/etc/httpd/conf/http.conf1)"/etc/h ...
- xunsearch之php索引维护(四)
1.添加文档 $xs = new XS('njw'); $index = $xs->index; $data = array( 'pid' => 234, // 此字段为主键,必须指定 ' ...
- Unit01: Servlet基础 、 HTTP协议
Unit01: Servlet基础 . HTTP协议 在页面上输出当前时间 package web; import java.io.IOException; import java.io.PrintW ...
- debian下qt4动态编译
一句话不割,版本4.86 ./configure -prefix /home/用户名/Qt/dynamic -opensource -opengl -confirm-license -no-scrip ...
- appium+python自动化40-adb offline(5037端口被占)
前言 adb连手机的时候经常会出现offline的情况,一般杀掉adb,然后重启adb可以解决. 如果发现不管怎么重启adb都连不上,一直出现offlie的情况,这个时候很大可能就是adb的5037端 ...
- Ladder面积
package com.hanqi; import javax.swing.plaf.synth.SynthSeparatorUI; //梯形 public class Ladder { double ...
- 杂项:HTML5-3/3-技术要点
ylbtech-杂项:HTML5-3/3-技术要点 1.返回顶部 1. 重要标记 <video>标记 定义和用法: </video> 标签定义视频,比如电影片段或其他视频流 ...
- Hive使用入门
Hive简介 hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务进行运行. 其优点是学习成 ...