[VC++][DirectShow]如何列舉video capture device的FriendlyName

有關於C/C++的語法, 程式等
回覆文章
頭像
tim
文章: 1318
註冊時間: 2008年 11月 26日, 00:49

[VC++][DirectShow]如何列舉video capture device的FriendlyName

文章 tim » 2008年 11月 27日, 16:39

在 VFW 中, 利用 capGetDriverDescription 取得的是一種 driver 的設備名稱, 往往讓人看不出來是什麼設備, 要如何才能取得更正確的設備名稱, 如在控制台中看到的設備名稱呢? 其實可以透過 DirectShow 來取得這些設備的 FriendlyName , 如此一來, 能更方便地取得這些資訊.

由於是 com base 的程式, 所以專案若是 unicode 時, BSTR 是不需要轉換的, 否則需要利用 comdef.h 中的 _com_util::ConvertBSTRToString 來轉型為 char *
字串轉型文章可以參考: http://blog.csdn.net/axes/articles/344040.aspx

以下函數必須 include 三個 header file
#include "strmif.h"
#include "uuids.h"
#include "comdef.h"

link 也要加入 strmiids.lib 才能順利進行.
程式碼如下,

代碼: 選擇全部

     
    ///////////////////////////////////////////////// 
    // ds_enum cap name 
    void ds_enumcapname() 
    { 
      // com initialize 
      CoInitialize(NULL); 
     
        ICreateDevEnum *pCreateDevEnum; 
        long hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, 
            IID_ICreateDevEnum, (void**)&pCreateDevEnum); 
        if(hr != NOERROR) { 
            AfxMessageBox(TEXT("Error Creating Device Enumerator")); 
            return; 
        } 
     
        IEnumMoniker *pEm; 
        hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, 
            &pEm, 0); 
        if(hr != NOERROR) { 
            AfxMessageBox(TEXT("Sorry, you have no video capture hardware")); 
            return; 
        } 
        pEm->Reset(); 
        ULONG cFetched; 
        IMoniker *pM; 
     
      int uIndex=0; 
      CString s; 
        while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK) { 
            IPropertyBag *pBag; 
            hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag); 
            if(SUCCEEDED(hr)) { 
                VARIANT var; 
                var.vt = VT_BSTR; 
                hr = pBag->Read(L"FriendlyName", &var, NULL); 
                if(hr == NOERROR) {           
            s.format("%d. %s", uIndex, _com_util::ConvertBSTRToString(var.bstrVal));         
            AfxMessageBox(s); 
                    SysFreeString(var.bstrVal); 
                    pM->AddRef(); 
                } 
                pBag->Release(); 
            } 
            pM->Release(); 
        uIndex++; 
        } 
        pEm->Release(); 
     
      // com uninitialize 
      CoUninitialize(); 
    } 
     
    ///////////////////////////////////////////////// 
    // 
    void ds_enumaudioname() 
    { 
      // com initialize 
      CoInitialize(NULL); 
     
      ICreateDevEnum *pCreateDevEnum; 
        long hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, 
            IID_ICreateDevEnum, (void**)&pCreateDevEnum); 
        if(hr != NOERROR) { 
            AfxMessageBox(TEXT("Error Creating Device Enumerator")); 
            return; 
        } 
     
        IEnumMoniker *pEm; 
        hr = pCreateDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory, 
            &pEm, 0); 
        pCreateDevEnum->Release(); 
        if(hr != NOERROR) 
            return; 
     
        ULONG cFetched; 
        IMoniker *pM; 
        pEm->Reset(); 
     
      int uIndex=0; 
      CString s; 
        while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK) { 
            IPropertyBag *pBag; 
            hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag); 
            if(SUCCEEDED(hr)) { 
                VARIANT var; 
                var.vt = VT_BSTR; 
                hr = pBag->Read(L"FriendlyName", &var, NULL); 
                if(hr == NOERROR) { 
            s.format("%d. %s", uIndex, _com_util::ConvertBSTRToString(var.bstrVal));         
            AfxMessageBox(s); 
                    SysFreeString(var.bstrVal); 
                    pM->AddRef();                 
                } 
                pBag->Release(); 
            } 
            pM->Release(); 
            uIndex++; 
        } 
        pEm->Release(); 
     
      // com uninitialize 
      CoUninitialize(); 
    } 
多多留言, 整理文章, 把經驗累積下來.....

回覆文章