枚舉Windows上所有可用視頻編解碼器的最佳方法? (Best way to enumerate all available video codecs on Windows?)


問題描述

枚舉 Windows 上所有可用視頻編解碼器的最佳方法? (Best way to enumerate all available video codecs on Windows?)

我正在尋找一種枚舉 Windows XP/Vista 機器上所有視頻編解碼器的好方法。

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

 可用解碼器 DiVX 版本 6.0 XVID Motion JPEG CompanyX 的 MPEG‑2 解碼器 Windows Media Video **可用編碼器** DiVX 版本 6.0 Windows Media Video 

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

  1. 您可以使用 DirectShow 枚舉所有解壓縮器,但這不會告訴您有關壓縮器(編碼器)的任何信息。
  2. 您可以枚舉所有 Video For Windows 組件, 但是您沒有任何跡象表明這些是編碼器還是解碼器。
  3. 有 DirectShow 過濾器可以很好地為您完成這項工作(例如 Motion JPEG 過濾器),但沒有跡象表明特定的 DirectShow 過濾器是“視頻解碼器”。

有沒有人使用任何 Windows API 找到了針對此問題的通用解決方案?Windows Vista Media Foundation API 是否解決了這些問題?


參考解法

方法 1:

This is best handled by DirectShow.

DirectShow is currently a part of the platform 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;
}

The following call enumerates all video compressors to the console :

enumerateDShowFilterList( CLSID_VideoCompressorCategory );

The MSDN page Filter Categories lists all other 'official' categories.

I hope that is a good starting point for you.

方法 2:

The answer above doesn't account for decompressors. There is no CLSID_VideoDecompressorCategory. Is the are a way to ask a filter if it is a video decompressor?

Not that I know of.

Most filters in this list are codecs, so contain both a encoder and decoder.

The filters in the

CLSID_ActiveMovieCategories

are wrappers around the VfW filters installed.

(Some software companies create their own categories, so there may be 'non official' categories on some machines)

If you want to see all installed categories, use GraphEdit which is supplied with the DirectShow SDK.

GraphEdit itself is a great tool to see what DirectShow does under the hood. So maybe that may be a source of more information about the filters (and their interactions) on your system.

方法 3:

Another point I forgot.

The Windows Media Foundation is a toolkit for using WMV/WMA. It does not provide all things that DirectShow supports. It is really only a SDK for Windows Media. There are bindings in WMV/WMA to DirectShow, so that you can use WM* files/streams in DirectShow applications.

(by Nick HaddadChristopherChristopherChristopher)

參考文件

  1. Best way to enumerate all available video codecs on Windows? (CC BY‑SA 2.5/3.0/4.0)

#video #directshow #media #codec






相關問題

當前在網站上放置音頻和視頻的最佳方式是什麼? (what's the current best way to put audio and video on a web site?)

相當於PNG的視頻? (Video equivalent of PNG?)

IOS - UISaveVideoAtPathToSavedPhotosAlbum 如何返回保存的視頻路徑? (IOS -how could UISaveVideoAtPathToSavedPhotosAlbum return the saved video path?)

如何使用 c# 編寫一個簡單的視頻播放器,以準確的 fps 播放視頻? (How to use c# to write a simple video player which plays the video with accurate fps?)

Monotouch - MoviePlayer 永遠不會超越“正在加載...” (Monotouch - MoviePlayer never gets beyond "loading...")

Android MediaMetadataRetriever setDataSource 失敗 (Android MediaMetadataRetriever setDataSource failed)

枚舉Windows上所有可用視頻編解碼器的最佳方法? (Best way to enumerate all available video codecs on Windows?)

如何通過上傳單個視頻文件為任何 html5 視頻獲得多種質量(360p、480p、720p)選擇 (how can i get multiple quality(360p,480p, 720p) selection for any html5 video with uploading single video file)

由於不支持的編解碼器,FFmpeg/Avconv 無法複製字幕? (FFmpeg/Avconv unable to copy subtitles due to unsupported codec?)

嵌入 youtube 視頻響應解決方案 (embed youtube video responsive solution)

如何輕鬆識別流是視頻還是圖片【ffmpeg庫】 (How to easily recognize whether stream is video or image [ffmpeg library])

livestream.com 如何顯示存檔的視頻? (how is livestream.com displaying the archived video(s)?)







留言討論