Windows で利用可能なすべてのビデオ コーデックを列挙する最良の方法は?
-
09-06-2019 - |
質問
Windows XP/Vista マシン上のすべてのビデオ コーデックを列挙する良い方法を探しています。
コンプレッサーとデコンプレッサーを含む一連のビデオ コーデックをユーザーに提示する必要があります。出力は次のようになります
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
私が直面している問題は、システムで利用可能なすべてのデコーダーをキャプチャする信頼できる方法がないことです。例えば:
- DirectShow を使用してすべての解凍プログラムを列挙できますが、これでは圧縮プログラム (エンコーダー) については何もわかりません。
- すべての Video For Windows コンポーネントを列挙できますが、これらがエンコーダーであるかデコーダーであるかはわかりません。
- 完璧に機能する DirectShow フィルター (たとえば、Motion JPEG フィルター) はありますが、特定の DirectShow フィルターが「ビデオ デコーダー」であることを示すものはありません。
Windows API のいずれかを使用して、この問題を一般化した解決策を見つけた人はいますか?Windows Vistaは メディア ファンデーション API これらの問題は解決しますか?
解決
これは 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 ページ カテゴリのフィルタリング 他のすべての「公式」カテゴリをリストします。
これが良い出発点となることを願っています。
他のヒント
上記の答えは解凍器を考慮していません。CLSID_VideoDecompressorCategory はありません。フィルターにビデオ解凍プログラムであるかどうかを問い合わせる方法はありますか?
私が知っているわけではありません。
このリストのほとんどのフィルターはコーデックであるため、エンコーダーとデコーダーの両方が含まれています。
のフィルターは、
CLSID_ActiveMovieCategories
インストールされている VfW フィルターのラッパーです。
(一部のソフトウェア会社は独自のカテゴリを作成しているため、一部のマシンには「非公式」カテゴリが存在する可能性があります)
インストールされているすべてのカテゴリを表示したい場合は、DirectShow SDK に付属の GraphEdit を使用してください。
GraphEdit 自体は、DirectShow が内部で何を行うかを確認するための優れたツールです。したがって、これはシステム上のフィルター (およびフィルターの相互作用) に関する詳細情報のソースになる可能性があります。
もう一つ忘れていた点。
Windows Media Foundation は、WMV/WMA を使用するためのツールキットです。DirectShow がサポートするすべての機能が提供されるわけではありません。これは実際には Windows Media 用の SDK にすぎません。WMV/WMA には DirectShow へのバインディングがあるため、DirectShow アプリケーションで WM* ファイル/ストリームを使用できます。