5

Windows XP/Vista マシンですべてのビデオ コーデックを列挙する良い方法を探しています。

コンプレッサとデコンプレッサを含む一連のビデオ コーデックをユーザーに提示する必要があります。出力は次のようになります

利用可能なデコーダー
DiVX バージョン 6.0
XVID
モーションJPEG
CompanyX の MPEG-2 デコーダ
Windows Media ビデオ

**利用可能なエンコーダー**
DiVX バージョン 6.0
Windows Media ビデオ

私が直面している問題は、システムで利用可能なすべてのデコーダーをキャプチャする信頼できる方法がないことです。例えば:

  1. DirectShow を使用してすべての圧縮解除プログラムを列挙できますが、圧縮プログラム (エンコーダー) については何もわかりません。
  2. すべての Video For Windows コンポーネントを列挙できますが、これらがエンコーダーまたはデコーダーであるかどうかは示されません。
  3. 完全にうまく機能する DirectShow フィルターがあります (Motion JPEG フィルターなど) が、特定の DirectShow フィルターが「ビデオ デコーダー」であるという兆候はありません。

Windows API のいずれかを使用して、この問題の一般化された解決策を見つけた人はいますか? Windows Vista Media Foundation APIはこれらの問題を解決しますか?

4

3 に答える 3

7

これは 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には、他のすべての「公式」カテゴリが一覧表示されています。

それがあなたにとって良い出発点になることを願っています。

于 2008-08-27T16:34:45.290 に答える
2

上記の答えは、減圧装置を考慮していません。CLSID_VideoDecompressorCategory はありません。これは、フィルタにビデオ デコンプレッサかどうかを尋ねる方法ですか?

私が知っていることではありません。

このリストのほとんどのフィルターはコーデックであるため、エンコーダーとデコーダーの両方が含まれています。

のフィルター

CLSID_ActiveMovieCategories

インストールされている VfW フィルターのラッパーです。

(一部のソフトウェア会社は独自のカテゴリを作成しているため、一部のマシンには「非公式」のカテゴリが存在する場合があります)

インストールされているすべてのカテゴリを表示するには、DirectShow SDK に付属の GraphEdit を使用します。

GraphEdit 自体は、DirectShow が内部で何を行っているかを確認するための優れたツールです。そのため、システムのフィルター (およびその相互作用) に関する詳細情報のソースになる可能性があります。

于 2008-08-27T17:18:28.397 に答える
1

忘れていたもう一つのポイント。

Windows Media Foundation は、WMV/WMA を使用するためのツールキットです。DirectShow がサポートするすべてのものを提供するわけではありません。これは実際には Windows Media 用の SDK にすぎません。DirectShow アプリケーションで WM* ファイル/ストリームを使用できるように、WMV/WMA には DirectShow へのバインディングがあります。

于 2008-08-27T17:21:55.970 に答える