zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    linux/unix下 pid文件作用浅析
    gunicorn启动django时静态文件的加载
    分享30道Redis面试题,面试官能问到的我都找到了
    python利用mongodb上传图片数据 : GridFS 与 bson两种方式
    GridFS大文件的添加、获取、查看、删除
    你真的懂redis吗?
    mongoDB的复制集5----复制集安全(认证,用户,权限)
    MongoDB复制集安全认证
    MongoDB 用户名密码登录
    MongoDB 分片
  • 原文地址:https://www.cnblogs.com/wainiwann/p/7458114.html
Copyright © 2011-2022 走看看