2008-08-27 46 views
5

我正在尋找一種很好的方式來枚舉Windows XP/Vista計算機上的所有視頻編解碼器。枚舉Windows上所有可用視頻編解碼器的最佳方法?

我需要向用戶展示一組視頻編解碼器,包括壓縮器和解壓縮器。輸出看起來像

 
Available Decoders 
DiVX Version 6.0 
XVID 
Motion JPEG 
CompanyX's MPEG-2 Decoder 
Windows Media Video 

**Available Encoders** 
DiVX Version 6.0 
Windows Media Video 

,我運行到是有來捕獲所有可用的系統解碼器沒有可靠的方法問題。例如:

  1. 您可以使用DirectShow枚舉所有解壓縮器,但是這不會告訴您有關壓縮器(編碼器)的任何內容。
  2. 您可以枚舉所有Video For Windows組件,但是如果這些組件是編碼器或解碼器,則不會顯示。
  3. 有DirectShow過濾器可以完美地完成工作(例如Motion JPEG過濾器),但沒有跡象表明特定的DirectShow過濾器是「視頻解碼器」。

是否有人使用任何Windows API發現了此問題的推廣解決方案? Windows Vista Media Foundation API解決了這些問題嗎?

回答

6

這最好由DirectShow處理。

DirectShow目前是平臺SDK的一部分。

HRESULT extractFriendlyName(IMoniker* pMk, std::wstring& str) 
{ 
    assert(pMk != 0); 
    IPropertyBag* pBag = 0; 
    HRESULT hr = pMk->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag); 
    if(FAILED(hr) || pBag == 0) 
    { 
    return hr; 
    } 
    VARIANT var; 
    var.vt = VT_BSTR; 
    hr = pBag->Read(L"FriendlyName", &var, NULL); 
    if(SUCCEEDED(hr) && var.bstrVal != 0) 
    { 
    str = reinterpret_cast<wchar_t*>(var.bstrVal); 
    SysFreeString(var.bstrVal); 
    } 
    pBag->Release(); 
    return hr; 
} 


HRESULT enumerateDShowFilterList(const CLSID& category) 
{ 
    HRESULT rval = S_OK; 
    HRESULT hr; 
    ICreateDevEnum* pCreateDevEnum = 0; // volatile, will be destroyed at the end 
    hr = ::CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, reinterpret_cast<void**>(&pCreateDevEnum)); 

    assert(SUCCEEDED(hr) && pCreateDevEnum != 0); 
    if(FAILED(hr) || pCreateDevEnum == 0) 
    { 
    return hr; 
    } 

    IEnumMoniker* pEm = 0; 
    hr = pCreateDevEnum->CreateClassEnumerator(category, &pEm, 0); 

    // If hr == S_FALSE, no error is occured. In this case pEm is NULL, because 
    // a filter does not exist e.g no video capture devives are connected to 
    // the computer or no codecs are installed. 
    assert(SUCCEEDED(hr) && ((hr == S_OK && pEm != 0) || hr == S_FALSE)); 
    if(FAILED(hr)) 
    { 
    pCreateDevEnum->Release(); 
    return hr; 
    } 

    if(hr == S_OK && pEm != 0) // In this case pEm is != NULL 
    { 
    pEm->Reset(); 
    ULONG cFetched; 
    IMoniker* pM = 0; 
    while(pEm->Next(1, &pM, &cFetched) == S_OK && pM != 0) 
    { 
     std::wstring str; 

     if(SUCCEEDED(extractFriendlyName(pM, str)) 
     { 
      // str contains the friendly name of the filter 
      // pM->BindToObject creates the filter 
      std::wcout << str << std::endl; 
     } 

     pM->Release(); 
    } 
    pEm->Release(); 
    } 
    pCreateDevEnum->Release(); 
    return rval; 
} 

以下調用枚舉所有的視頻壓縮到控制檯:

enumerateDShowFilterList(CLSID_VideoCompressorCategory); 

的MSDN頁面Filter Categories列出了所有其他的 '官方' 的類別。

我希望這是一個很好的起點。

+0

我可能會添加以下內容:http://msdn.microsoft.com/en-us/library/windows/desktop/dd375655(v=vs.85).aspx「。在頁面的底部,它表明類別CLSID_LegacyAmFilterCategory將是包含DirectShow可作爲音頻解壓縮器和視頻解壓縮器訪問的DMO的類別。 – sboisse 2012-11-23 03:51:08

2

上面的答案不解釋解壓縮程序。沒有CLSID_VideoDecompressorCategory。如果它是一個視頻解壓縮器,是否可以提供過濾器?

不是我所知道的。

此列表中的大部分過濾器都是編解碼器,因此包含編碼器和解碼器。

CLSID_ActiveMovieCategories 

過濾器周圍安裝VFW的過濾器的包裝。

(一些軟件公司創建自己的類別,所以有可能是在某些機器「非官方」類別)如果你想看到所有已安裝的類別,使用的是與DirectShow的SDK提供的GraphEdit

GraphEdit本身是一個很好的工具,可以看到DirectShow在底層做了什麼。因此,也許這可能是有關係統上過濾器(及其交互)的更多信息的來源。

1

我忘記了另一點。

Windows Media Foundation是一個使用WMV/WMA的工具包。它沒有提供DirectShow支持的所有東西。它實際上只是Windows Media SDK。 WMV/WMA在DirectShow中存在綁定,因此您可以在DirectShow應用程序中使用WM *文件/流。

相關問題