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

直接上代码吧:

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

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

时间: 2024-10-11 05:21:28

Directshow 判断音视频设备是否被占用<转>的相关文章

Directshow中的视频捕捉(转)感觉这个非常全,但真的不知道出处了...

本篇文档主要描述关于用Directshow进行视频开发的一些技术主要包括下面内容 1关于视频捕捉(About Video Capture in Dshow) 2选择一个视频捕捉设备(Select capture device) 3预览视频(Previewing Video) 4如何捕捉视频流并保存到文件(Capture video to File) 5将设备从系统中移走时的事件通知(Device remove Notify) 6如何控制Capture Graph(Controlling Capt

DirectShow .Net 实现视频

1 1.获取视频采集设备IBaseFilter接口对象的方法 2 3 //获取所有视频设备名称 4 public ArrayList GetVideoInputDevice() 5 { return GetDeviceCollection(FilterCategory.VideoInputDevice);} 6 private ArrayList GetDeviceCollection(Guid DeviceType) 7 { 8 ArrayList returnString = new Arr

Win7摄像头软件ECap(创建XP风格视频设备)

下载地址: Win7摄像头软件安装后,可以创建XP风格视频设备,可以在"我的计算机"-其它-增加"视频设备" 项.由于Win7下装好摄像头驱动后并不像XP一样可以在我的电脑里找到视频设备,不方便控制摄像头,所以使用第三方软件Ecap来作为控制视频设备的软件.

视频开发技术 视频设备枚举 C#

由于小编之前使用过BR_Chat的音视频解决方案作视频会议系统开发,所以这里也就以当时的环境和处理机制简单做一个介绍. 1.BR_Chat-枚举本地视频采集设备-方法概述: DWORD BRAC_EnumVideoCapture(TCHAR** lpDeviceName, DWORD& dwDeviceNum); 功能:枚举本地视频采集设备 返回值:0 表示成功,否则为出错代码 参数: lpDeviceName 视频设备名称,可为空,表示只获取设备数量: dwDeviceNum 视频设备数量;

DirectShow控制台输出和保存视频设备名称

#include "windows.h" #include "TCHAR.h" #include <dshow.h> #include <vector> #include <iostream> #include <cwctype> #define MAX_FRIENDLY_NAME_LENGTH 128 #define MAX_MONIKER_NAME_LENGTH 256 typedef struct _TDevic

摘录DirectShow数据,视频采集

DirectShow在,数据流(Data Flow)它们是依次流过每Filter的.管理其数据具有其自己的方法,并且并没有向用户提供一个统一的接口,供用户操作数据流.这里以提取视频採集在的每帧为位图数据为例,说说怎样在Directshow中提取数据. 这里我们用到了DirectShow提供给我们的接口ISampleGrabber,并定义了一个供它回调的CSampleGrabberCB对象(继承ISampleGrabberCB接口). 我们知道,DirectShow中的数据存储是通过Sample完

GPS部标和视频设备硬件厂商广告位招商

本博客及网站www.ltmonitor.com致力于gps和视频软件平台的开发技术分享,欢迎车载设备厂商有好的符合交通部部标的硬件产品和综合解决方案,投放在本博客当中. 可签订长期服务合同,开具正规公司发票. 联系人:[email protected] 1)3G车载硬盘录像机DVR,用于车载视频监控. 防爆摄像头,用于车载视频监控,适用于各种油品.化工等危险品运输车辆上安装. 2)部标北斗/GPS终端设备 3)防爆摄像头 4)油感设备:油耗检测设备用于物流运输车辆的油耗检测,显示油量与车速.里程

《韦东山新视频 — 设备树调试技巧》

1.设备树的信息 以下目录对应设备树的根节点,可以从此进去找到自己定义的节点. cd /sys/firmware/devicetree/base/ 节点是目录,属性是文件. 属性值是字符串时,用 cat 命令可以打印出来:属性值是数值时,用 hexdump 命令可以打印出来. 2.platform_device 的信息 以下目录含有注册进内核的所有 platform_device: /sys/devices/platform 一个设备对应一个目录,进入某个目录后,如果它有“driver”子目录,

mac下ffmpeg打开音视频设备(开启音视频设备访问限制)

The app's Info.plist must contain an NSMicrophoneUsageDescription key with a string value explaining to the user how the app uses this data 在mac上用Xcode用ffmpeg的API: ret = avformat_open_input(&fmt_ctx, devicename, iformat, &options); 报上述错误:该应用已崩溃,因为